Skip to content

[flang] Allow interoperable object to have interoperable derived type… #94768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 12, 2024

Conversation

klausler
Copy link
Contributor

@klausler klausler commented Jun 7, 2024

… that's not BIND(C)

An interoperable BIND(C) object with a derived type should have a BIND(C) derived type, but will now work with a derived type that satisfies all of the requirements of a BIND(C) derived type.

@klausler klausler requested a review from wangzpgi June 7, 2024 16:32
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:semantics labels Jun 7, 2024
@llvmbot
Copy link
Member

llvmbot commented Jun 7, 2024

@llvm/pr-subscribers-flang-semantics

Author: Peter Klausler (klausler)

Changes

… that's not BIND(C)

An interoperable BIND(C) object with a derived type should have a BIND(C) derived type, but will now work with a derived type that satisfies all of the requirements of a BIND(C) derived type.


Full diff: https://github.com/llvm/llvm-project/pull/94768.diff

2 Files Affected:

  • (modified) flang/lib/Semantics/check-declarations.cpp (+8-10)
  • (modified) flang/test/Semantics/declarations02.f90 (+3-3)
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 25de9d4af1ffb..ea663161ccbf3 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -139,7 +139,7 @@ class CheckHelper {
   void CheckProcedureAssemblyName(const Symbol &symbol);
   void CheckExplicitSave(const Symbol &);
   parser::Messages WhyNotInteroperableDerivedType(const Symbol &, bool isError);
-  parser::Messages WhyNotInteroperableObject(const Symbol &, bool isError);
+  parser::Messages WhyNotInteroperableObject(const Symbol &);
   parser::Messages WhyNotInteroperableFunctionResult(const Symbol &);
   parser::Messages WhyNotInteroperableProcedure(const Symbol &, bool isError);
   void CheckBindC(const Symbol &);
@@ -2981,15 +2981,13 @@ parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
   return msgs;
 }
 
-parser::Messages CheckHelper::WhyNotInteroperableObject(
-    const Symbol &symbol, bool isError) {
+parser::Messages CheckHelper::WhyNotInteroperableObject(const Symbol &symbol) {
   parser::Messages msgs;
   if (examinedByWhyNotInteroperable_.find(symbol) !=
       examinedByWhyNotInteroperable_.end()) {
     return msgs;
   }
   bool isExplicitBindC{symbol.attrs().test(Attr::BIND_C)};
-  isError |= isExplicitBindC;
   examinedByWhyNotInteroperable_.insert(symbol);
   CHECK(symbol.has<ObjectEntityDetails>());
   if (isExplicitBindC && !symbol.owner().IsModule()) {
@@ -3018,11 +3016,11 @@ parser::Messages CheckHelper::WhyNotInteroperableObject(
   }
   if (const auto *type{symbol.GetType()}) {
     const auto *derived{type->AsDerived()};
-    if (derived) {
-      if (derived->typeSymbol().attrs().test(Attr::BIND_C)) {
-      } else if (isError) {
+    if (derived && !derived->typeSymbol().attrs().test(Attr::BIND_C)) {
+      if (!context_.IsEnabled(
+              common::LanguageFeature::NonBindCInteroperability)) {
         msgs.Say(symbol.name(),
-                "The derived type of a BIND(C) object must also be BIND(C)"_err_en_US)
+                "The derived type of an interoperable object must be BIND(C)"_err_en_US)
             .Attach(derived->typeSymbol().name(), "Non-BIND(C) type"_en_US);
       } else if (auto bad{WhyNotInteroperableDerivedType(
                      derived->typeSymbol(), /*isError=*/false)};
@@ -3155,7 +3153,7 @@ parser::Messages CheckHelper::WhyNotInteroperableProcedure(
                 "A dummy procedure of an interoperable procedure should be BIND(C)"_warn_en_US);
           }
         } else if (dummy->has<ObjectEntityDetails>()) {
-          dummyMsgs = WhyNotInteroperableObject(*dummy, /*isError=*/false);
+          dummyMsgs = WhyNotInteroperableObject(*dummy);
         } else {
           CheckBindC(*dummy);
         }
@@ -3225,7 +3223,7 @@ void CheckHelper::CheckBindC(const Symbol &symbol) {
     }
   }
   if (symbol.has<ObjectEntityDetails>()) {
-    whyNot = WhyNotInteroperableObject(symbol, /*isError=*/isExplicitBindC);
+    whyNot = WhyNotInteroperableObject(symbol);
   } else if (symbol.has<ProcEntityDetails>() ||
       symbol.has<SubprogramDetails>()) {
     whyNot = WhyNotInteroperableProcedure(symbol, /*isError=*/isExplicitBindC);
diff --git a/flang/test/Semantics/declarations02.f90 b/flang/test/Semantics/declarations02.f90
index f39c233c1c3a4..32c3517d13cd1 100644
--- a/flang/test/Semantics/declarations02.f90
+++ b/flang/test/Semantics/declarations02.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
 
 module m
   !ERROR: 'x1' may not have both the BIND(C) and PARAMETER attributes
@@ -32,14 +32,14 @@ module m
   end type
 
   !ERROR: 't1' may not have both the BIND(C) and PARAMETER attributes
-  !ERROR: The derived type of a BIND(C) object must also be BIND(C)
+  !WARNING: The derived type of an interoperable object should be BIND(C)
   type(my_type1), bind(c), parameter :: t1 = my_type1(1)
   !ERROR: 't2' may not have both the BIND(C) and PARAMETER attributes
   type(my_type2), bind(c), parameter :: t2 = my_type2(1)
 
   type(my_type2), parameter :: t3 = my_type2(1) ! no error
   !ERROR: 't4' may not have both the BIND(C) and PARAMETER attributes
-  !ERROR: The derived type of a BIND(C) object must also be BIND(C)
+  !WARNING: The derived type of an interoperable object should be BIND(C)
   type(my_type1), parameter :: t4 = my_type1(1)
   !ERROR: 't5' may not have both the BIND(C) and PARAMETER attributes
   type(my_type2), parameter :: t5 = my_type2(1)

… that's not BIND(C)

An interoperable BIND(C) object with a derived type should have
a BIND(C) derived type, but will now work with a derived type that
satisfies all of the requirements of a BIND(C) derived type.
@klausler klausler merged commit 055df49 into llvm:main Jun 12, 2024
3 of 4 checks passed
@klausler klausler deleted the bindc branch June 12, 2024 00:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants