@@ -151,8 +151,8 @@ class CheckHelper {
151
151
void CheckProcedureAssemblyName (const Symbol &symbol);
152
152
void CheckExplicitSave (const Symbol &);
153
153
parser::Messages WhyNotInteroperableDerivedType (const Symbol &);
154
- parser::Messages WhyNotInteroperableObject (
155
- const Symbol & , bool allowNonInteroperableType = false );
154
+ parser::Messages WhyNotInteroperableObject (const Symbol &,
155
+ bool allowNonInteroperableType = false , bool forCommonBlock = false );
156
156
parser::Messages WhyNotInteroperableFunctionResult (const Symbol &);
157
157
parser::Messages WhyNotInteroperableProcedure (const Symbol &, bool isError);
158
158
void CheckBindC (const Symbol &);
@@ -519,11 +519,28 @@ void CheckHelper::Check(const Symbol &symbol) {
519
519
}
520
520
521
521
void CheckHelper::CheckCommonBlock (const Symbol &symbol) {
522
+ auto restorer{messages_.SetLocation (symbol.name ())};
522
523
CheckGlobalName (symbol);
523
524
if (symbol.attrs ().test (Attr::BIND_C)) {
524
525
CheckBindC (symbol);
526
+ for (auto ref : symbol.get <CommonBlockDetails>().objects ()) {
527
+ if (ref->has <ObjectEntityDetails>()) {
528
+ if (auto msgs{WhyNotInteroperableObject (*ref,
529
+ /* allowInteroperableType=*/ false , /* forCommonBlock=*/ true )};
530
+ !msgs.empty ()) {
531
+ if (auto *msg{messages_.Say (symbol.name (),
532
+ " '%s' may not be a member of BIND(C) COMMON block /%s/" _err_en_US,
533
+ ref->name (), symbol.name ())}) {
534
+ for (parser::Message &reason : msgs.messages ()) {
535
+ reason.set_severity (parser::Severity::Because);
536
+ msg->Attach (std::move (reason));
537
+ }
538
+ }
539
+ }
540
+ }
541
+ }
525
542
}
526
- for (MutableSymbolRef ref : symbol.get <CommonBlockDetails>().objects ()) {
543
+ for (auto ref : symbol.get <CommonBlockDetails>().objects ()) {
527
544
if (ref->test (Symbol::Flag::CrayPointee)) {
528
545
messages_.Say (ref->name (),
529
546
" Cray pointee '%s' may not be a member of a COMMON block" _err_en_US,
@@ -3154,14 +3171,16 @@ parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
3154
3171
}
3155
3172
3156
3173
parser::Messages CheckHelper::WhyNotInteroperableObject (
3157
- const Symbol &symbol, bool allowNonInteroperableType) {
3174
+ const Symbol &symbol, bool allowNonInteroperableType, bool forCommonBlock ) {
3158
3175
parser::Messages msgs;
3159
- if (examinedByWhyNotInteroperable_.find (symbol) !=
3160
- examinedByWhyNotInteroperable_.end ()) {
3161
- return msgs;
3176
+ if (!forCommonBlock) {
3177
+ if (examinedByWhyNotInteroperable_.find (symbol) !=
3178
+ examinedByWhyNotInteroperable_.end ()) {
3179
+ return msgs;
3180
+ }
3181
+ examinedByWhyNotInteroperable_.insert (symbol);
3162
3182
}
3163
3183
bool isExplicitBindC{symbol.attrs ().test (Attr::BIND_C)};
3164
- examinedByWhyNotInteroperable_.insert (symbol);
3165
3184
CHECK (symbol.has <ObjectEntityDetails>());
3166
3185
if (isExplicitBindC && !symbol.owner ().IsModule ()) {
3167
3186
msgs.Say (symbol.name (),
@@ -3338,8 +3357,8 @@ parser::Messages CheckHelper::WhyNotInteroperableProcedure(
3338
3357
// on the C side by either a cdesc_t * or a void *. F'2023 18.3.7 (5)
3339
3358
bool allowNonInteroperableType{!dummy->attrs ().test (Attr::VALUE) &&
3340
3359
(IsDescriptor (*dummy) || IsAssumedType (*dummy))};
3341
- dummyMsgs =
3342
- WhyNotInteroperableObject ( *dummy, allowNonInteroperableType);
3360
+ dummyMsgs = WhyNotInteroperableObject (
3361
+ *dummy, allowNonInteroperableType, /* forCommonBlock= */ false );
3343
3362
} else {
3344
3363
CheckBindC (*dummy);
3345
3364
}
0 commit comments