[flang-commits] [flang] [flang][Semantics] Introduce `-Wpass-global-variable` warning (PR #160324)

via flang-commits flang-commits at lists.llvm.org
Tue Sep 23 08:29:11 PDT 2025


================
@@ -56,9 +56,64 @@ static void CheckImplicitInterfaceArg(evaluate::ActualArgument &arg,
         "%VAL argument must be a scalar numeric or logical expression"_err_en_US);
   }
   if (const auto *expr{arg.UnwrapExpr()}) {
-    if (const Symbol * base{GetFirstSymbol(*expr)};
-        base && IsFunctionResult(*base)) {
-      context.NoteDefinedSymbol(*base);
+    if (const Symbol * base{GetFirstSymbol(*expr)}) {
+      if (IsFunctionResult(*base)) {
+        context.NoteDefinedSymbol(*base);
+      } else {
+        // passing global variables
+        // here, arrays with subscripts are processing
+        bool warn{false};
+        std::string ownerName{""};
+        std::string ownerType{""};
+        if (base->flags().test(Symbol::Flag::InCommonBlock)) {
+          const Symbol *common{FindCommonBlockContaining(*base)};
+          ownerType = "COMMON";
+          ownerName = common->name().ToString();
+          if (!(base->Rank() == 1 && base->offset() == 0)) {
+            warn |= true;
+          } else if (base->Rank() == 1) {
+            if (const ArraySpec *dims{base->GetShape()};
+                dims && dims->IsExplicitShape()) {
+              if (!((*dims)[0].lbound().GetExplicit() == (*dims)[0].ubound().GetExplicit())) {
+                warn |= true;
+              }
+            }
+            if (common->get<CommonBlockDetails>().objects().size() > 1) {
+              warn |= true;
+            }
+          }
+        } else if (const auto &owner{base->GetUltimate().owner()};
+                   owner.IsModule() || owner.IsSubmodule()) {
+          const Scope *module{FindModuleContaining(owner)};
+          ownerType = "MODULE";
+          ownerName = module->GetName()->ToString();
+          if (base->attrs().test(Attr::PARAMETER)) {
+            warn |= false;
+          } else if (base->Rank() != 1) {
+            warn |= true;
+          } else if (!base->attrs().test(Attr::ALLOCATABLE) &&
+                     !base->attrs().test(Attr::POINTER) &&
+                     !base->attrs().test(Attr::VOLATILE)) {
+            // by some reason, dims is not constructed here. For common blocks' variables, it works
+            // it leads to three skipped tests
+            /*
+            if (const ArraySpec *dims{base->GetShape()};
+                dims && dims->IsExplicitShape()) {
+              if (!((*dims)[0].lbound().GetExplicit() == (*dims)[0].ubound().GetExplicit())) {
+                  warn |= true;
+              }
+            }
----------------
foxtran wrote:

@klausler, do you have an idea why `base->GetShape()` returns `nullptr`? It happens for variables defined in modules, but not for variables defined in common blocks.

https://github.com/llvm/llvm-project/pull/160324


More information about the flang-commits mailing list