@@ -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,35 @@ 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
+ parser::Message &reason{msgs.messages ().front ()};
532
+ parser::Message *msg{nullptr };
533
+ if (reason.IsFatal ()) {
534
+ msg = messages_.Say (symbol.name (),
535
+ " '%s' may not be a member of BIND(C) COMMON block /%s/" _err_en_US,
536
+ ref->name (), symbol.name ());
537
+ } else {
538
+ msg = messages_.Say (symbol.name (),
539
+ " '%s' should not be a member of BIND(C) COMMON block /%s/" _warn_en_US,
540
+ ref->name (), symbol.name ());
541
+ }
542
+ if (msg) {
543
+ msg->Attach (
544
+ std::move (reason.set_severity (parser::Severity::Because)));
545
+ }
546
+ }
547
+ }
548
+ }
525
549
}
526
- for (MutableSymbolRef ref : symbol.get <CommonBlockDetails>().objects ()) {
550
+ for (auto ref : symbol.get <CommonBlockDetails>().objects ()) {
527
551
if (ref->test (Symbol::Flag::CrayPointee)) {
528
552
messages_.Say (ref->name (),
529
553
" Cray pointee '%s' may not be a member of a COMMON block" _err_en_US,
@@ -3154,14 +3178,16 @@ parser::Messages CheckHelper::WhyNotInteroperableDerivedType(
3154
3178
}
3155
3179
3156
3180
parser::Messages CheckHelper::WhyNotInteroperableObject (
3157
- const Symbol &symbol, bool allowNonInteroperableType) {
3181
+ const Symbol &symbol, bool allowNonInteroperableType, bool forCommonBlock ) {
3158
3182
parser::Messages msgs;
3159
- if (examinedByWhyNotInteroperable_.find (symbol) !=
3160
- examinedByWhyNotInteroperable_.end ()) {
3161
- return msgs;
3183
+ if (!forCommonBlock) {
3184
+ if (examinedByWhyNotInteroperable_.find (symbol) !=
3185
+ examinedByWhyNotInteroperable_.end ()) {
3186
+ return msgs;
3187
+ }
3188
+ examinedByWhyNotInteroperable_.insert (symbol);
3162
3189
}
3163
3190
bool isExplicitBindC{symbol.attrs ().test (Attr::BIND_C)};
3164
- examinedByWhyNotInteroperable_.insert (symbol);
3165
3191
CHECK (symbol.has <ObjectEntityDetails>());
3166
3192
if (isExplicitBindC && !symbol.owner ().IsModule ()) {
3167
3193
msgs.Say (symbol.name (),
@@ -3258,7 +3284,7 @@ parser::Messages CheckHelper::WhyNotInteroperableObject(
3258
3284
msgs.Say (symbol.name (),
3259
3285
" An interoperable pointer must not be CONTIGUOUS" _err_en_US);
3260
3286
}
3261
- if (msgs.AnyFatalError ()) {
3287
+ if (!forCommonBlock && msgs.AnyFatalError ()) {
3262
3288
examinedByWhyNotInteroperable_.erase (symbol);
3263
3289
}
3264
3290
return msgs;
@@ -3338,8 +3364,8 @@ parser::Messages CheckHelper::WhyNotInteroperableProcedure(
3338
3364
// on the C side by either a cdesc_t * or a void *. F'2023 18.3.7 (5)
3339
3365
bool allowNonInteroperableType{!dummy->attrs ().test (Attr::VALUE) &&
3340
3366
(IsDescriptor (*dummy) || IsAssumedType (*dummy))};
3341
- dummyMsgs =
3342
- WhyNotInteroperableObject ( *dummy, allowNonInteroperableType);
3367
+ dummyMsgs = WhyNotInteroperableObject (
3368
+ *dummy, allowNonInteroperableType, /* forCommonBlock= */ false );
3343
3369
} else {
3344
3370
CheckBindC (*dummy);
3345
3371
}
0 commit comments