Skip to content

Commit 56cd8a5

Browse files
authored
[flang] Relax BIND(C) derived type component check (#94392)
Allow an explicit BIND(C) derived type to have a non-BIND(C) component so long as the component's type is interoperable and it satisfies all other constraints.
1 parent 11a4d43 commit 56cd8a5

File tree

2 files changed

+15
-19
lines changed

2 files changed

+15
-19
lines changed

flang/lib/Semantics/check-declarations.cpp

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ class CheckHelper {
138138
void CheckGlobalName(const Symbol &);
139139
void CheckProcedureAssemblyName(const Symbol &symbol);
140140
void CheckExplicitSave(const Symbol &);
141-
parser::Messages WhyNotInteroperableDerivedType(const Symbol &, bool isError);
141+
parser::Messages WhyNotInteroperableDerivedType(const Symbol &);
142142
parser::Messages WhyNotInteroperableObject(const Symbol &, bool isError);
143143
parser::Messages WhyNotInteroperableFunctionResult(const Symbol &);
144144
parser::Messages WhyNotInteroperableProcedure(const Symbol &, bool isError);
@@ -2892,13 +2892,12 @@ void CheckHelper::CheckProcedureAssemblyName(const Symbol &symbol) {
28922892
}
28932893

28942894
parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
2895-
const Symbol &symbol, bool isError) {
2895+
const Symbol &symbol) {
28962896
parser::Messages msgs;
28972897
if (examinedByWhyNotInteroperable_.find(symbol) !=
28982898
examinedByWhyNotInteroperable_.end()) {
28992899
return msgs;
29002900
}
2901-
isError |= symbol.attrs().test(Attr::BIND_C);
29022901
examinedByWhyNotInteroperable_.insert(symbol);
29032902
if (const auto *derived{symbol.detailsIf<DerivedTypeDetails>()}) {
29042903
if (derived->sequence()) { // C1801
@@ -2909,14 +2908,13 @@ parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
29092908
"An interoperable derived type cannot have a type parameter"_err_en_US);
29102909
} else if (const auto *parent{
29112910
symbol.scope()->GetDerivedTypeParent()}) { // C1803
2912-
if (isError) {
2911+
if (symbol.attrs().test(Attr::BIND_C)) {
29132912
msgs.Say(symbol.name(),
29142913
"A derived type with the BIND attribute cannot be an extended derived type"_err_en_US);
29152914
} else {
29162915
bool interoperableParent{true};
29172916
if (parent->symbol()) {
2918-
auto bad{WhyNotInteroperableDerivedType(
2919-
*parent->symbol(), /*isError=*/false)};
2917+
auto bad{WhyNotInteroperableDerivedType(*parent->symbol())};
29202918
if (bad.AnyFatalError()) {
29212919
auto &msg{msgs.Say(symbol.name(),
29222920
"The parent of an interoperable type is not interoperable"_err_en_US)};
@@ -2946,8 +2944,7 @@ parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
29462944
"An interoperable derived type cannot have a pointer or allocatable component"_err_en_US);
29472945
} else if (const auto *type{component.GetType()}) {
29482946
if (const auto *derived{type->AsDerived()}) {
2949-
auto bad{
2950-
WhyNotInteroperableDerivedType(derived->typeSymbol(), isError)};
2947+
auto bad{WhyNotInteroperableDerivedType(derived->typeSymbol())};
29512948
if (bad.AnyFatalError()) {
29522949
auto &msg{msgs.Say(component.name(),
29532950
"Component '%s' of an interoperable derived type must have an interoperable type but does not"_err_en_US,
@@ -2999,13 +2996,6 @@ parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
29992996
}
30002997
}
30012998
}
3002-
if (isError) {
3003-
for (auto &m : msgs.messages()) {
3004-
if (!m.IsFatal()) {
3005-
m.set_severity(parser::Severity::Error);
3006-
}
3007-
}
3008-
}
30092999
if (msgs.AnyFatalError()) {
30103000
examinedByWhyNotInteroperable_.erase(symbol);
30113001
}
@@ -3055,8 +3045,8 @@ parser::Messages CheckHelper::WhyNotInteroperableObject(
30553045
msgs.Say(symbol.name(),
30563046
"The derived type of a BIND(C) object must also be BIND(C)"_err_en_US)
30573047
.Attach(derived->typeSymbol().name(), "Non-BIND(C) type"_en_US);
3058-
} else if (auto bad{WhyNotInteroperableDerivedType(
3059-
derived->typeSymbol(), /*isError=*/false)};
3048+
} else if (auto bad{
3049+
WhyNotInteroperableDerivedType(derived->typeSymbol())};
30603050
bad.AnyFatalError()) {
30613051
bad.AttachTo(
30623052
msgs.Say(symbol.name(),
@@ -3261,8 +3251,7 @@ void CheckHelper::CheckBindC(const Symbol &symbol) {
32613251
symbol.has<SubprogramDetails>()) {
32623252
whyNot = WhyNotInteroperableProcedure(symbol, /*isError=*/isExplicitBindC);
32633253
} else if (symbol.has<DerivedTypeDetails>()) {
3264-
whyNot =
3265-
WhyNotInteroperableDerivedType(symbol, /*isError=*/isExplicitBindC);
3254+
whyNot = WhyNotInteroperableDerivedType(symbol);
32663255
}
32673256
if (!whyNot.empty()) {
32683257
bool anyFatal{whyNot.AnyFatalError()};

flang/test/Semantics/bind-c15.f90

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ module m
1616
type :: non_interoperable2
1717
type(non_interoperable1) b
1818
end type
19+
type :: no_bind_c
20+
real a
21+
end type
22+
type, bind(c) :: has_bind_c
23+
!WARNING: Derived type of component 'a' of an interoperable derived type should have the BIND attribute
24+
type(no_bind_c) :: a
25+
end type
1926
interface
2027
subroutine sub_bind_c_1(x_bind_c) bind(c)
2128
import explicit_bind_c

0 commit comments

Comments
 (0)