[flang-commits] [flang] [flang][OpenACC] Relax COMMON block usage restriction in OpenACC directives (PR #162659)

Eugene Epshteyn via flang-commits flang-commits at lists.llvm.org
Thu Oct 16 13:49:15 PDT 2025


https://github.com/eugeneepshteyn updated https://github.com/llvm/llvm-project/pull/162659

>From 042d2f66bd632fb5d83df0ca4d5c0a3ede031c1c Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 6 Oct 2025 05:51:32 -0400
Subject: [PATCH 01/17] [flang] Draft of the work to look up COMMON
 declarations in the modules for ACC directives.

---
 flang/lib/Semantics/resolve-directives.cpp | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 18fc63814d973..eefd19f3ac6a9 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1695,17 +1695,13 @@ void AccAttributeVisitor::Post(const parser::Name &name) {
 
 Symbol *AccAttributeVisitor::ResolveAccCommonBlockName(
     const parser::Name *name) {
-  if (auto *prev{name
-              ? GetContext().scope.parent().FindCommonBlock(name->source)
-              : nullptr}) {
-    name->symbol = prev;
-    return prev;
-  }
-  // Check if the Common Block is declared in the current scope
-  if (auto *commonBlockSymbol{
-          name ? GetContext().scope.FindCommonBlock(name->source) : nullptr}) {
-    name->symbol = commonBlockSymbol;
-    return commonBlockSymbol;
+  if (!name) {
+    return nullptr;
+  }
+  if (auto *cb{GetProgramUnitOrBlockConstructContaining(GetContext().scope)
+              .FindCommonBlock(name->source)}) {
+    name->symbol = cb;
+    return cb;
   }
   return nullptr;
 }

>From 931b300841960e8c33c4c1351fdeb0ec1916f329 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Thu, 9 Oct 2025 06:30:51 -0400
Subject: [PATCH 02/17] Try to handle use association, but didn't work, because
 no symbol

---
 flang/lib/Semantics/resolve-directives.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index eefd19f3ac6a9..583f69dca6bbf 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1703,6 +1703,12 @@ Symbol *AccAttributeVisitor::ResolveAccCommonBlockName(
     name->symbol = cb;
     return cb;
   }
+  if (auto *cb{GetContext().scope.FindSymbol(name->source)}) {
+    if (auto *sym{&cb->GetUltimate()}; sym && sym->has<CommonBlockDetails>()) {
+      name->symbol = sym;
+      return sym;
+    }
+  }
   return nullptr;
 }
 

>From 86cb8b62c9c546f4e5c909a2500e4e8563bd2839 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Thu, 9 Oct 2025 09:54:23 -0400
Subject: [PATCH 03/17] Searching for COMMON definition in top level modules

---
 flang/lib/Semantics/resolve-directives.cpp | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 583f69dca6bbf..a7fcc4d46e4a5 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1698,15 +1698,18 @@ Symbol *AccAttributeVisitor::ResolveAccCommonBlockName(
   if (!name) {
     return nullptr;
   }
+  // Check the local and surrounding scopes first
   if (auto *cb{GetProgramUnitOrBlockConstructContaining(GetContext().scope)
               .FindCommonBlock(name->source)}) {
     name->symbol = cb;
     return cb;
   }
-  if (auto *cb{GetContext().scope.FindSymbol(name->source)}) {
-    if (auto *sym{&cb->GetUltimate()}; sym && sym->has<CommonBlockDetails>()) {
-      name->symbol = sym;
-      return sym;
+  // Look for COMMON block in the modules
+  for (const Scope &childScope : context_.globalScope().children()) {
+    if (childScope.kind() == Scope::Kind::Module) {
+      auto *cb{childScope.FindCommonBlock(name->source)};
+      name->symbol = cb;
+      return cb;
     }
   }
   return nullptr;
@@ -1757,8 +1760,8 @@ void AccAttributeVisitor::ResolveAccObject(
               }
             } else {
               context_.Say(name.source,
-                  "COMMON block must be declared in the same scoping unit "
-                  "in which the OpenACC directive or clause appears"_err_en_US);
+                  "Could not find COMMON block '%s' used in OpenACC directive"_err_en_US,
+                  name.ToString());
             }
           },
       },

>From f462bf5d170e4bbd82cd46d963baef9077985982 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Thu, 9 Oct 2025 12:16:44 -0400
Subject: [PATCH 04/17] Guard against null cb

---
 flang/lib/Semantics/resolve-directives.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index a7fcc4d46e4a5..44cfb75e06164 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1707,9 +1707,10 @@ Symbol *AccAttributeVisitor::ResolveAccCommonBlockName(
   // Look for COMMON block in the modules
   for (const Scope &childScope : context_.globalScope().children()) {
     if (childScope.kind() == Scope::Kind::Module) {
-      auto *cb{childScope.FindCommonBlock(name->source)};
-      name->symbol = cb;
-      return cb;
+      if (auto *cb{childScope.FindCommonBlock(name->source)}) {
+        name->symbol = cb;
+        return cb;
+      }
     }
   }
   return nullptr;

>From 14ce6b6f5c3eb66d2d7412ee9f8c82cbf22c6f64 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Thu, 9 Oct 2025 17:01:10 -0400
Subject: [PATCH 05/17] Unit test

---
 flang/test/Semantics/OpenACC/acc-common.f90 | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 flang/test/Semantics/OpenACC/acc-common.f90

diff --git a/flang/test/Semantics/OpenACC/acc-common.f90 b/flang/test/Semantics/OpenACC/acc-common.f90
new file mode 100644
index 0000000000000..c6142bdb915f6
--- /dev/null
+++ b/flang/test/Semantics/OpenACC/acc-common.f90
@@ -0,0 +1,19 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+module acc_common_decl
+  implicit none
+  integer a
+  common /a_common/ a
+!$acc declare create (/a_common/)
+  data a/42/
+end module acc_common_decl
+
+program acc_decl_test
+  use acc_common_decl
+  implicit none
+
+  a = 1
+!$acc update device (/a_common/)
+  a = 2
+!ERROR: Could not find COMMON block 'a_common_bad' used in OpenACC directive
+!$acc update device (/a_common_bad/)
+end program

>From ff637dd5a65f944d098743400a670be913827f5f Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 13 Oct 2025 07:05:56 -0400
Subject: [PATCH 06/17] Updated Scope::FindCommonBlock() to be similar to
 Scope::FindSymbol(). (Currently the code doesn't fix ACC COMMON problem.)

---
 flang/lib/Semantics/resolve-directives.cpp | 13 +------------
 flang/lib/Semantics/scope.cpp              | 12 ++++++++++--
 2 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 44cfb75e06164..5009819876cf6 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1698,21 +1698,10 @@ Symbol *AccAttributeVisitor::ResolveAccCommonBlockName(
   if (!name) {
     return nullptr;
   }
-  // Check the local and surrounding scopes first
-  if (auto *cb{GetProgramUnitOrBlockConstructContaining(GetContext().scope)
-              .FindCommonBlock(name->source)}) {
+  if (auto *cb{GetContext().scope.FindCommonBlock(name->source)}) {
     name->symbol = cb;
     return cb;
   }
-  // Look for COMMON block in the modules
-  for (const Scope &childScope : context_.globalScope().children()) {
-    if (childScope.kind() == Scope::Kind::Module) {
-      if (auto *cb{childScope.FindCommonBlock(name->source)}) {
-        name->symbol = cb;
-        return cb;
-      }
-    }
-  }
   return nullptr;
 }
 
diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp
index 4af371f3611f3..f859728424dc6 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -155,8 +155,16 @@ Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) {
   }
 }
 Symbol *Scope::FindCommonBlock(const SourceName &name) const {
-  const auto it{commonBlocks_.find(name)};
-  return it != commonBlocks_.end() ? &*it->second : nullptr;
+  if (const auto it{commonBlocks_.find(name)}; it != commonBlocks_.end()) {
+    return &*it->second;
+  } else if (IsSubmodule()) {
+    const Scope *parent{symbol_ ? symbol_->get<ModuleDetails>().parent() : nullptr};
+    return parent ? parent->FindCommonBlock(name) : nullptr;
+  } else if (!IsTopLevel()) {
+    return parent_ ? parent_->FindCommonBlock(name) : nullptr;
+  } else {
+    return nullptr;
+  }
 }
 
 Scope *Scope::FindSubmodule(const SourceName &name) const {

>From 9e19979825c7896816fc3d27c7178fc7a3085799 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 13 Oct 2025 07:08:55 -0400
Subject: [PATCH 07/17] clang-format

---
 flang/lib/Semantics/scope.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp
index f859728424dc6..901e9744257d6 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -158,7 +158,8 @@ Symbol *Scope::FindCommonBlock(const SourceName &name) const {
   if (const auto it{commonBlocks_.find(name)}; it != commonBlocks_.end()) {
     return &*it->second;
   } else if (IsSubmodule()) {
-    const Scope *parent{symbol_ ? symbol_->get<ModuleDetails>().parent() : nullptr};
+    const Scope *parent{
+        symbol_ ? symbol_->get<ModuleDetails>().parent() : nullptr};
     return parent ? parent->FindCommonBlock(name) : nullptr;
   } else if (!IsTopLevel()) {
     return parent_ ? parent_->FindCommonBlock(name) : nullptr;

>From 66028eff741153b2a3e86632dd00d305e557c5e7 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 13 Oct 2025 12:48:06 -0400
Subject: [PATCH 08/17] Split FindCommonBlock() into FindCB() and
 FindCommonBlockInScopes(). This resolves OpenMP regressions with COMMON.
 Still working on USE-association for COMMON blocks

---
 flang/include/flang/Semantics/scope.h      | 13 +++++++++
 flang/lib/Semantics/resolve-directives.cpp |  2 +-
 flang/lib/Semantics/scope.cpp              | 33 ++++++++++++++++------
 3 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h
index 3195892fa7b91..53619d2ecc40d 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -189,8 +189,21 @@ class Scope {
   mapType &commonBlocks() { return commonBlocks_; }
   const mapType &commonBlocks() const { return commonBlocks_; }
   Symbol &MakeCommonBlock(SourceName, SourceName location);
+
+  /// Find COMMON block in the current scope
+  Symbol *FindCB(const SourceName &name) const {
+    if (const auto it{commonBlocks_.find(name)}; it != commonBlocks_.end()) {
+      return &*it->second;
+    }
+    return nullptr;
+  }
+
+  /// Find COMMON block that is not USE-associated in the current scope
   Symbol *FindCommonBlock(const SourceName &) const;
 
+  /// Find COMMON block in current and surrounding scopes, follow USE associations
+  Symbol *FindCommonBlockInScopes(const SourceName &) const;
+
   /// Make a Symbol but don't add it to the scope.
   template <typename D>
   common::IfNoLvalue<Symbol &, D> MakeSymbol(
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 5009819876cf6..bcdf701f16b21 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1698,7 +1698,7 @@ Symbol *AccAttributeVisitor::ResolveAccCommonBlockName(
   if (!name) {
     return nullptr;
   }
-  if (auto *cb{GetContext().scope.FindCommonBlock(name->source)}) {
+  if (auto *cb{GetContext().scope.FindCommonBlockInScopes(name->source)}) {
     name->symbol = cb;
     return cb;
   }
diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp
index 901e9744257d6..067d1d6058102 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -154,18 +154,33 @@ Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) {
     return symbol;
   }
 }
+
 Symbol *Scope::FindCommonBlock(const SourceName &name) const {
-  if (const auto it{commonBlocks_.find(name)}; it != commonBlocks_.end()) {
-    return &*it->second;
+  if (auto *cb{FindCB(name)}) {
+    // Ensure this COMMON block is not USE-associated
+    if (cb->has<UseDetails>()) {
+      cb = nullptr;
+    }
+    return cb;
+  }
+  return nullptr;
+}
+
+Symbol *Scope::FindCommonBlockInScopes(const SourceName &name) const {
+  if (auto *cb{FindCB(name)}) {
+    return &cb->GetUltimate();
   } else if (IsSubmodule()) {
-    const Scope *parent{
-        symbol_ ? symbol_->get<ModuleDetails>().parent() : nullptr};
-    return parent ? parent->FindCommonBlock(name) : nullptr;
-  } else if (!IsTopLevel()) {
-    return parent_ ? parent_->FindCommonBlock(name) : nullptr;
-  } else {
-    return nullptr;
+    if (const Scope *parent{symbol_ ? symbol_->get<ModuleDetails>().parent() : nullptr}) {
+      if (auto *cb{parent->FindCommonBlockInScopes(name)}) {
+        return &cb->GetUltimate();
+      }
+    }
+  } else if (!IsTopLevel() && parent_) {
+    if (auto *cb{parent_->FindCommonBlockInScopes(name)}) {
+      return &cb->GetUltimate();
+    }
   }
+  return nullptr;
 }
 
 Scope *Scope::FindSubmodule(const SourceName &name) const {

>From 41336f12ac8e8509f6cc50ff728b94a371b90292 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 13 Oct 2025 15:22:42 -0400
Subject: [PATCH 09/17] Add USE association details to COMMON blocks

---
 flang/include/flang/Semantics/scope.h      |  1 +
 flang/lib/Semantics/check-declarations.cpp |  5 ++++-
 flang/lib/Semantics/compute-offsets.cpp    |  5 ++++-
 flang/lib/Semantics/resolve-names.cpp      | 15 +++++++++++++++
 flang/lib/Semantics/scope.cpp              | 10 +++++++---
 5 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h
index 53619d2ecc40d..a0b1aa4dfe3bc 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -189,6 +189,7 @@ class Scope {
   mapType &commonBlocks() { return commonBlocks_; }
   const mapType &commonBlocks() const { return commonBlocks_; }
   Symbol &MakeCommonBlock(SourceName, SourceName location);
+  bool AddCommonBlock(const SourceName &name, Symbol &cbSymbol);
 
   /// Find COMMON block in the current scope
   Symbol *FindCB(const SourceName &name) const {
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index ea5e2c095d31a..f051eb3e54781 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -2782,7 +2782,10 @@ void CheckHelper::Check(const Scope &scope) {
       Check(*scope.symbol());
     }
     for (const auto &pair : scope.commonBlocks()) {
-      CheckCommonBlock(*pair.second);
+      if (pair.second->has<CommonBlockDetails>()) {
+        // Only process actual COMMON block objects, not their uses
+        CheckCommonBlock(*pair.second);
+      }
     }
     int mainProgCnt{0};
     for (const Scope &child : scope.children()) {
diff --git a/flang/lib/Semantics/compute-offsets.cpp b/flang/lib/Semantics/compute-offsets.cpp
index 1c48d33549a2e..8c47ef1f2ed1e 100644
--- a/flang/lib/Semantics/compute-offsets.cpp
+++ b/flang/lib/Semantics/compute-offsets.cpp
@@ -207,7 +207,10 @@ void ComputeOffsetsHelper::Compute(Scope &scope) {
   // where COMMON blocks are illegal (C1107 and C1108).
   if (scope.kind() != Scope::Kind::BlockConstruct) {
     for (auto &pair : scope.commonBlocks()) {
-      DoCommonBlock(*pair.second);
+      // Only process actual COMMON block objects, not their uses
+      if (pair.second->has<CommonBlockDetails>()) {
+        DoCommonBlock(*pair.second);
+      }
     }
   }
   for (auto &[symbol, dep] : dependents_) {
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 861218809c0f9..b399d963a6ab1 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -3627,6 +3627,17 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
       }
     }
   }
+  // Go through the list of COMMON block symbols in the module scope and add
+  // their USE association to the current scope's COMMON blocks.
+  for (const auto &[name, symbol] : useModuleScope_->commonBlocks()) {
+    if (auto *localCB{currScope().FindCommonBlockInScopes(name)}; !localCB) {
+      // Make a symbol, but don't add it to the Scope, since it needs to
+      // be added to the COMMON blocks
+      localCB = &currScope().MakeSymbol(
+          name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()});
+      currScope().AddCommonBlock(name, *localCB);
+    }
+  }
   useModuleScope_ = nullptr;
 }
 
@@ -7284,6 +7295,10 @@ void DeclarationVisitor::CheckCommonBlocks() {
   // check for empty common blocks
   for (const auto &pair : currScope().commonBlocks()) {
     const auto &symbol{*pair.second};
+    if (!pair.second->has<CommonBlockDetails>()) {
+      // Skip USE associated COMMON blocks
+      continue;
+    }
     if (symbol.get<CommonBlockDetails>().objects().empty() &&
         symbol.attrs().test(Attr::BIND_C)) {
       Say(symbol.name(),
diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp
index 067d1d6058102..cec6eb6ea6969 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -144,9 +144,8 @@ void Scope::add_crayPointer(const SourceName &name, Symbol &pointer) {
 }
 
 Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) {
-  const auto it{commonBlocks_.find(name)};
-  if (it != commonBlocks_.end()) {
-    return *it->second;
+  if (auto *cb{FindCB(name)}) {
+    return *cb;
   } else {
     Symbol &symbol{MakeSymbol(
         name, Attrs{}, CommonBlockDetails{name.empty() ? location : name})};
@@ -191,6 +190,11 @@ Scope *Scope::FindSubmodule(const SourceName &name) const {
     return &*it->second;
   }
 }
+
+bool Scope::AddCommonBlock(const SourceName &name, Symbol &cbSymbol) {
+  return commonBlocks_.emplace(name, cbSymbol).second;
+}
+
 bool Scope::AddSubmodule(const SourceName &name, Scope &submodule) {
   return submodules_.emplace(name, submodule).second;
 }

>From eac75b744a46f4698a1f9cf4239f856c882367a4 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 13 Oct 2025 16:30:08 -0400
Subject: [PATCH 10/17] Handle the case of redeclared COMMON block

---
 flang/include/flang/Semantics/symbol.h |  2 +-
 flang/lib/Semantics/scope.cpp          | 15 +++++++++++++++
 flang/lib/Semantics/symbol.cpp         |  6 ++++--
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 77f567e69ce55..696cc5cb14921 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -884,7 +884,7 @@ class Symbol {
   const Details &details() const { return details_; }
   // Assign the details of the symbol from one of the variants.
   // Only allowed in certain cases.
-  void set_details(Details &&);
+  void set_details(Details &&, bool force = false);
 
   // Can the details of this symbol be replaced with the given details?
   bool CanReplaceDetails(const Details &details) const;
diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp
index cec6eb6ea6969..b8506bb29d8bb 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -145,6 +145,21 @@ void Scope::add_crayPointer(const SourceName &name, Symbol &pointer) {
 
 Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) {
   if (auto *cb{FindCB(name)}) {
+    if (cb->has<UseDetails>()) {
+      // COMMON blocks could be re-declared. Example:
+      //    module test
+      //      integer :: a
+      //      common /blk/ a
+      //    end module test
+      //    program main
+      //      use test          ! Initially get /blk/ with UseDetails
+      //      integer :: a1
+      //      common /blk/ a1   ! Update with CommonBlockDetails
+      //    end program main
+      // Reset details with real COMMON block details.
+      cb->set_details(CommonBlockDetails{name.empty() ? location : name},
+          /*force*/true);
+    }
     return *cb;
   } else {
     Symbol &symbol{MakeSymbol(
diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index 69169469fe8ce..3d428ac54440b 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -317,8 +317,10 @@ std::string DetailsToString(const Details &details) {
 
 std::string Symbol::GetDetailsName() const { return DetailsToString(details_); }
 
-void Symbol::set_details(Details &&details) {
-  CHECK(CanReplaceDetails(details));
+void Symbol::set_details(Details &&details, bool force) {
+  if (!force) {
+    CHECK(CanReplaceDetails(details));
+  }
   details_ = std::move(details);
 }
 

>From 553a3c3d607391f5bf02c81a32669dac37d56518 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 13 Oct 2025 16:31:09 -0400
Subject: [PATCH 11/17] clang-format

---
 flang/include/flang/Semantics/scope.h | 3 ++-
 flang/lib/Semantics/scope.cpp         | 5 +++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h
index a0b1aa4dfe3bc..05f214cef193d 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -202,7 +202,8 @@ class Scope {
   /// Find COMMON block that is not USE-associated in the current scope
   Symbol *FindCommonBlock(const SourceName &) const;
 
-  /// Find COMMON block in current and surrounding scopes, follow USE associations
+  /// Find COMMON block in current and surrounding scopes, follow USE
+  /// associations
   Symbol *FindCommonBlockInScopes(const SourceName &) const;
 
   /// Make a Symbol but don't add it to the scope.
diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp
index b8506bb29d8bb..55a51f16f7e92 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -158,7 +158,7 @@ Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) {
       //    end program main
       // Reset details with real COMMON block details.
       cb->set_details(CommonBlockDetails{name.empty() ? location : name},
-          /*force*/true);
+          /*force*/ true);
     }
     return *cb;
   } else {
@@ -184,7 +184,8 @@ Symbol *Scope::FindCommonBlockInScopes(const SourceName &name) const {
   if (auto *cb{FindCB(name)}) {
     return &cb->GetUltimate();
   } else if (IsSubmodule()) {
-    if (const Scope *parent{symbol_ ? symbol_->get<ModuleDetails>().parent() : nullptr}) {
+    if (const Scope *parent{
+            symbol_ ? symbol_->get<ModuleDetails>().parent() : nullptr}) {
       if (auto *cb{parent->FindCommonBlockInScopes(name)}) {
         return &cb->GetUltimate();
       }

>From c042379c73ea479fd25dceffa4084e686806ce63 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Thu, 16 Oct 2025 14:13:59 -0400
Subject: [PATCH 12/17] Code review feedback + separated COMMON lists into
 COMMON in the current scope and COMMON with USE details

---
 flang/include/flang/Semantics/scope.h      | 22 +++++++----
 flang/include/flang/Semantics/symbol.h     |  2 +-
 flang/lib/Semantics/check-declarations.cpp |  5 +--
 flang/lib/Semantics/compute-offsets.cpp    |  5 +--
 flang/lib/Semantics/resolve-directives.cpp |  2 +-
 flang/lib/Semantics/resolve-names.cpp      | 12 ++----
 flang/lib/Semantics/scope.cpp              | 44 +++++-----------------
 flang/lib/Semantics/symbol.cpp             |  6 +--
 8 files changed, 34 insertions(+), 64 deletions(-)

diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h
index 05f214cef193d..c8cc04fdc7b0d 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -189,22 +189,27 @@ class Scope {
   mapType &commonBlocks() { return commonBlocks_; }
   const mapType &commonBlocks() const { return commonBlocks_; }
   Symbol &MakeCommonBlock(SourceName, SourceName location);
-  bool AddCommonBlock(const SourceName &name, Symbol &cbSymbol);
+  bool AddCommonBlockUse(const SourceName &name, Symbol &cbSymbol);
 
-  /// Find COMMON block in the current scope
-  Symbol *FindCB(const SourceName &name) const {
+  // Find COMMON block that is not USE-associated in the current scope
+  Symbol *FindCommonBlock(const SourceName &name) const  {
     if (const auto it{commonBlocks_.find(name)}; it != commonBlocks_.end()) {
       return &*it->second;
     }
     return nullptr;
   }
 
-  /// Find COMMON block that is not USE-associated in the current scope
-  Symbol *FindCommonBlock(const SourceName &) const;
+  // Find USE-associated COMMON block in the current scope
+  Symbol *FindCommonBlockUse(const SourceName &name) const  {
+    if (const auto it{useCommonBlocks_.find(name)}; it != useCommonBlocks_.end()) {
+      return &*it->second;
+    }
+    return nullptr;
+  }
 
-  /// Find COMMON block in current and surrounding scopes, follow USE
-  /// associations
-  Symbol *FindCommonBlockInScopes(const SourceName &) const;
+  // Find COMMON block in current and surrounding scopes, follow USE
+  // associations
+  Symbol *FindCommonBlockInSurroundingScopes(const SourceName &) const;
 
   /// Make a Symbol but don't add it to the scope.
   template <typename D>
@@ -298,6 +303,7 @@ class Scope {
   std::list<Scope> children_;
   mapType symbols_;
   mapType commonBlocks_;
+  mapType useCommonBlocks_; // USE-assocated COMMON blocks
   std::list<EquivalenceSet> equivalenceSets_;
   mapType crayPointers_;
   std::map<SourceName, common::Reference<Scope>> submodules_;
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 3536d7271c86c..14da5b443633f 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -884,7 +884,7 @@ class Symbol {
   const Details &details() const { return details_; }
   // Assign the details of the symbol from one of the variants.
   // Only allowed in certain cases.
-  void set_details(Details &&, bool force = false);
+  void set_details(Details &&);
 
   // Can the details of this symbol be replaced with the given details?
   bool CanReplaceDetails(const Details &details) const;
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 74c21b8afffdf..31e246cf0ab03 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -2782,10 +2782,7 @@ void CheckHelper::Check(const Scope &scope) {
       Check(*scope.symbol());
     }
     for (const auto &pair : scope.commonBlocks()) {
-      if (pair.second->has<CommonBlockDetails>()) {
-        // Only process actual COMMON block objects, not their uses
-        CheckCommonBlock(*pair.second);
-      }
+      CheckCommonBlock(*pair.second);
     }
     int mainProgCnt{0};
     for (const Scope &child : scope.children()) {
diff --git a/flang/lib/Semantics/compute-offsets.cpp b/flang/lib/Semantics/compute-offsets.cpp
index 8c47ef1f2ed1e..1c48d33549a2e 100644
--- a/flang/lib/Semantics/compute-offsets.cpp
+++ b/flang/lib/Semantics/compute-offsets.cpp
@@ -207,10 +207,7 @@ void ComputeOffsetsHelper::Compute(Scope &scope) {
   // where COMMON blocks are illegal (C1107 and C1108).
   if (scope.kind() != Scope::Kind::BlockConstruct) {
     for (auto &pair : scope.commonBlocks()) {
-      // Only process actual COMMON block objects, not their uses
-      if (pair.second->has<CommonBlockDetails>()) {
-        DoCommonBlock(*pair.second);
-      }
+      DoCommonBlock(*pair.second);
     }
   }
   for (auto &[symbol, dep] : dependents_) {
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 99a9a62a5d7d5..9dae11f70ea6a 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1714,7 +1714,7 @@ Symbol *AccAttributeVisitor::ResolveAccCommonBlockName(
   if (!name) {
     return nullptr;
   }
-  if (auto *cb{GetContext().scope.FindCommonBlockInScopes(name->source)}) {
+  if (auto *cb{GetContext().scope.FindCommonBlockInSurroundingScopes(name->source)}) {
     name->symbol = cb;
     return cb;
   }
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index e97187e6b5116..2a4f163ca80ac 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -3628,14 +3628,14 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
     }
   }
   // Go through the list of COMMON block symbols in the module scope and add
-  // their USE association to the current scope's COMMON blocks.
+  // their USE association to the current scope's USE-associated COMMON blocks.
   for (const auto &[name, symbol] : useModuleScope_->commonBlocks()) {
-    if (auto *localCB{currScope().FindCommonBlockInScopes(name)}; !localCB) {
+    if (auto *localCB{currScope().FindCommonBlockInSurroundingScopes(name)}; !localCB) {
       // Make a symbol, but don't add it to the Scope, since it needs to
-      // be added to the COMMON blocks
+      // be added to the USE-associated COMMON blocks
       localCB = &currScope().MakeSymbol(
           name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()});
-      currScope().AddCommonBlock(name, *localCB);
+      currScope().AddCommonBlockUse(name, *localCB);
     }
   }
   useModuleScope_ = nullptr;
@@ -7295,10 +7295,6 @@ void DeclarationVisitor::CheckCommonBlocks() {
   // check for empty common blocks
   for (const auto &pair : currScope().commonBlocks()) {
     const auto &symbol{*pair.second};
-    if (!pair.second->has<CommonBlockDetails>()) {
-      // Skip USE associated COMMON blocks
-      continue;
-    }
     if (symbol.get<CommonBlockDetails>().objects().empty() &&
         symbol.attrs().test(Attr::BIND_C)) {
       Say(symbol.name(),
diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp
index 55a51f16f7e92..4fcdce2c4925c 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -144,22 +144,7 @@ void Scope::add_crayPointer(const SourceName &name, Symbol &pointer) {
 }
 
 Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) {
-  if (auto *cb{FindCB(name)}) {
-    if (cb->has<UseDetails>()) {
-      // COMMON blocks could be re-declared. Example:
-      //    module test
-      //      integer :: a
-      //      common /blk/ a
-      //    end module test
-      //    program main
-      //      use test          ! Initially get /blk/ with UseDetails
-      //      integer :: a1
-      //      common /blk/ a1   ! Update with CommonBlockDetails
-      //    end program main
-      // Reset details with real COMMON block details.
-      cb->set_details(CommonBlockDetails{name.empty() ? location : name},
-          /*force*/ true);
-    }
+  if (auto *cb{FindCommonBlock(name)}) {
     return *cb;
   } else {
     Symbol &symbol{MakeSymbol(
@@ -169,30 +154,21 @@ Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) {
   }
 }
 
-Symbol *Scope::FindCommonBlock(const SourceName &name) const {
-  if (auto *cb{FindCB(name)}) {
-    // Ensure this COMMON block is not USE-associated
-    if (cb->has<UseDetails>()) {
-      cb = nullptr;
-    }
+Symbol *Scope::FindCommonBlockInSurroundingScopes(const SourceName &name) const {
+  if (Symbol *cb{FindCommonBlock(name)}) {
     return cb;
-  }
-  return nullptr;
-}
-
-Symbol *Scope::FindCommonBlockInScopes(const SourceName &name) const {
-  if (auto *cb{FindCB(name)}) {
+  } else if (Symbol *cb{FindCommonBlockUse(name)}) {
     return &cb->GetUltimate();
   } else if (IsSubmodule()) {
     if (const Scope *parent{
             symbol_ ? symbol_->get<ModuleDetails>().parent() : nullptr}) {
-      if (auto *cb{parent->FindCommonBlockInScopes(name)}) {
-        return &cb->GetUltimate();
+      if (auto *cb{parent->FindCommonBlockInSurroundingScopes(name)}) {
+        return cb;
       }
     }
   } else if (!IsTopLevel() && parent_) {
-    if (auto *cb{parent_->FindCommonBlockInScopes(name)}) {
-      return &cb->GetUltimate();
+    if (auto *cb{parent_->FindCommonBlockInSurroundingScopes(name)}) {
+      return cb;
     }
   }
   return nullptr;
@@ -207,8 +183,8 @@ Scope *Scope::FindSubmodule(const SourceName &name) const {
   }
 }
 
-bool Scope::AddCommonBlock(const SourceName &name, Symbol &cbSymbol) {
-  return commonBlocks_.emplace(name, cbSymbol).second;
+bool Scope::AddCommonBlockUse(const SourceName &name, Symbol &cbSymbol) {
+  return useCommonBlocks_.emplace(name, cbSymbol).second;
 }
 
 bool Scope::AddSubmodule(const SourceName &name, Scope &submodule) {
diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index 3d428ac54440b..69169469fe8ce 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -317,10 +317,8 @@ std::string DetailsToString(const Details &details) {
 
 std::string Symbol::GetDetailsName() const { return DetailsToString(details_); }
 
-void Symbol::set_details(Details &&details, bool force) {
-  if (!force) {
-    CHECK(CanReplaceDetails(details));
-  }
+void Symbol::set_details(Details &&details) {
+  CHECK(CanReplaceDetails(details));
   details_ = std::move(details);
 }
 

>From 740894faa7d81959df0e222e1a45cab212d66a74 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Thu, 16 Oct 2025 14:41:03 -0400
Subject: [PATCH 13/17] COMMON block uses renames. Extended test to using
 module chain

---
 flang/include/flang/Semantics/scope.h       |  5 +++--
 flang/lib/Semantics/resolve-names.cpp       | 14 +++++++++++++-
 flang/lib/Semantics/scope.cpp               |  2 +-
 flang/test/Semantics/OpenACC/acc-common.f90 | 13 ++++++++++++-
 4 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h
index c8cc04fdc7b0d..9aff27c9a0eab 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -190,6 +190,7 @@ class Scope {
   const mapType &commonBlocks() const { return commonBlocks_; }
   Symbol &MakeCommonBlock(SourceName, SourceName location);
   bool AddCommonBlockUse(const SourceName &name, Symbol &cbSymbol);
+  mapType &commonBlockUses() { return commonBlockUses_; }
 
   // Find COMMON block that is not USE-associated in the current scope
   Symbol *FindCommonBlock(const SourceName &name) const  {
@@ -201,7 +202,7 @@ class Scope {
 
   // Find USE-associated COMMON block in the current scope
   Symbol *FindCommonBlockUse(const SourceName &name) const  {
-    if (const auto it{useCommonBlocks_.find(name)}; it != useCommonBlocks_.end()) {
+    if (const auto it{commonBlockUses_.find(name)}; it != commonBlockUses_.end()) {
       return &*it->second;
     }
     return nullptr;
@@ -303,7 +304,7 @@ class Scope {
   std::list<Scope> children_;
   mapType symbols_;
   mapType commonBlocks_;
-  mapType useCommonBlocks_; // USE-assocated COMMON blocks
+  mapType commonBlockUses_; // USE-assocated COMMON blocks
   std::list<EquivalenceSet> equivalenceSets_;
   mapType crayPointers_;
   std::map<SourceName, common::Reference<Scope>> submodules_;
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 2a4f163ca80ac..64ffd00180314 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -3630,7 +3630,7 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
   // Go through the list of COMMON block symbols in the module scope and add
   // their USE association to the current scope's USE-associated COMMON blocks.
   for (const auto &[name, symbol] : useModuleScope_->commonBlocks()) {
-    if (auto *localCB{currScope().FindCommonBlockInSurroundingScopes(name)}; !localCB) {
+    if (Symbol *localCB{currScope().FindCommonBlockInSurroundingScopes(name)}; !localCB) {
       // Make a symbol, but don't add it to the Scope, since it needs to
       // be added to the USE-associated COMMON blocks
       localCB = &currScope().MakeSymbol(
@@ -3638,6 +3638,18 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
       currScope().AddCommonBlockUse(name, *localCB);
     }
   }
+#if 0
+  // Go through the list of USE-associated COMMON block symbols in the module
+  // scope and add USE associations to their ultimate symbols to the current
+  // scope's USE-associated COMMON blocks.
+  for (const auto &[name, symbol] : useModuleScope_->commonBlockUses()) {
+    // Make a symbol, but don't add it to the Scope, since it needs to
+    // be added to the USE-associated COMMON blocks
+    Symbol *localCB = &currScope().MakeSymbol(
+        name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()});
+    currScope().AddCommonBlockUse(name, *localCB);
+  }
+#endif
   useModuleScope_ = nullptr;
 }
 
diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp
index 4fcdce2c4925c..6beeff172b56c 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -184,7 +184,7 @@ Scope *Scope::FindSubmodule(const SourceName &name) const {
 }
 
 bool Scope::AddCommonBlockUse(const SourceName &name, Symbol &cbSymbol) {
-  return useCommonBlocks_.emplace(name, cbSymbol).second;
+  return commonBlockUses_.emplace(name, cbSymbol).second;
 }
 
 bool Scope::AddSubmodule(const SourceName &name, Scope &submodule) {
diff --git a/flang/test/Semantics/OpenACC/acc-common.f90 b/flang/test/Semantics/OpenACC/acc-common.f90
index c6142bdb915f6..1843ff7d8cd13 100644
--- a/flang/test/Semantics/OpenACC/acc-common.f90
+++ b/flang/test/Semantics/OpenACC/acc-common.f90
@@ -7,13 +7,24 @@ module acc_common_decl
   data a/42/
 end module acc_common_decl
 
-program acc_decl_test
+module acc_common_intermediate
   use acc_common_decl
   implicit none
+  integer b
+  common /b_common/ b
+!$acc declare create (/b_common/)
+end module acc_common_intermediate
+
+program acc_decl_test
+  use acc_common_intermediate
+  implicit none
 
   a = 1
+  b = 10
 !$acc update device (/a_common/)
   a = 2
+!$acc update device (/b_common/)
+  b = 20
 !ERROR: Could not find COMMON block 'a_common_bad' used in OpenACC directive
 !$acc update device (/a_common_bad/)
 end program

>From ca82173cfdd0beca714595984fa99ca65852398f Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Thu, 16 Oct 2025 14:45:29 -0400
Subject: [PATCH 14/17] clang-format

---
 flang/include/flang/Semantics/scope.h      | 7 ++++---
 flang/lib/Semantics/resolve-directives.cpp | 3 ++-
 flang/lib/Semantics/resolve-names.cpp      | 3 ++-
 flang/lib/Semantics/scope.cpp              | 3 ++-
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h
index 9aff27c9a0eab..b49b6d58cc5e6 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -193,7 +193,7 @@ class Scope {
   mapType &commonBlockUses() { return commonBlockUses_; }
 
   // Find COMMON block that is not USE-associated in the current scope
-  Symbol *FindCommonBlock(const SourceName &name) const  {
+  Symbol *FindCommonBlock(const SourceName &name) const {
     if (const auto it{commonBlocks_.find(name)}; it != commonBlocks_.end()) {
       return &*it->second;
     }
@@ -201,8 +201,9 @@ class Scope {
   }
 
   // Find USE-associated COMMON block in the current scope
-  Symbol *FindCommonBlockUse(const SourceName &name) const  {
-    if (const auto it{commonBlockUses_.find(name)}; it != commonBlockUses_.end()) {
+  Symbol *FindCommonBlockUse(const SourceName &name) const {
+    if (const auto it{commonBlockUses_.find(name)};
+        it != commonBlockUses_.end()) {
       return &*it->second;
     }
     return nullptr;
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 9dae11f70ea6a..b71e52f7a60b7 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1714,7 +1714,8 @@ Symbol *AccAttributeVisitor::ResolveAccCommonBlockName(
   if (!name) {
     return nullptr;
   }
-  if (auto *cb{GetContext().scope.FindCommonBlockInSurroundingScopes(name->source)}) {
+  if (auto *cb{GetContext().scope.FindCommonBlockInSurroundingScopes(
+          name->source)}) {
     name->symbol = cb;
     return cb;
   }
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 64ffd00180314..af9a706427235 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -3630,7 +3630,8 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
   // Go through the list of COMMON block symbols in the module scope and add
   // their USE association to the current scope's USE-associated COMMON blocks.
   for (const auto &[name, symbol] : useModuleScope_->commonBlocks()) {
-    if (Symbol *localCB{currScope().FindCommonBlockInSurroundingScopes(name)}; !localCB) {
+    if (Symbol *localCB{currScope().FindCommonBlockInSurroundingScopes(name)};
+        !localCB) {
       // Make a symbol, but don't add it to the Scope, since it needs to
       // be added to the USE-associated COMMON blocks
       localCB = &currScope().MakeSymbol(
diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp
index 6beeff172b56c..2e26ab27be343 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -154,7 +154,8 @@ Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) {
   }
 }
 
-Symbol *Scope::FindCommonBlockInSurroundingScopes(const SourceName &name) const {
+Symbol *Scope::FindCommonBlockInSurroundingScopes(
+    const SourceName &name) const {
   if (Symbol *cb{FindCommonBlock(name)}) {
     return cb;
   } else if (Symbol *cb{FindCommonBlockUse(name)}) {

>From 2474da05690f4880733728ed19744ffbf8559cfd Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Thu, 16 Oct 2025 15:02:04 -0400
Subject: [PATCH 15/17] Enabled creating of USE symbols from USE symbols of
 COMMON blocks

---
 flang/lib/Semantics/resolve-names.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index af9a706427235..569d61355cd7a 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -3639,7 +3639,6 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
       currScope().AddCommonBlockUse(name, *localCB);
     }
   }
-#if 0
   // Go through the list of USE-associated COMMON block symbols in the module
   // scope and add USE associations to their ultimate symbols to the current
   // scope's USE-associated COMMON blocks.
@@ -3650,7 +3649,6 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
         name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()});
     currScope().AddCommonBlockUse(name, *localCB);
   }
-#endif
   useModuleScope_ = nullptr;
 }
 

>From 5c84d48737e8e47720b3377d9be89caa9c578987 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Thu, 16 Oct 2025 15:48:49 -0400
Subject: [PATCH 16/17] clang-format

---
 flang/lib/Semantics/scope.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp
index 2e26ab27be343..a2c3891ec31b8 100644
--- a/flang/lib/Semantics/scope.cpp
+++ b/flang/lib/Semantics/scope.cpp
@@ -156,9 +156,9 @@ Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) {
 
 Symbol *Scope::FindCommonBlockInSurroundingScopes(
     const SourceName &name) const {
-  if (Symbol *cb{FindCommonBlock(name)}) {
+  if (Symbol * cb{FindCommonBlock(name)}) {
     return cb;
-  } else if (Symbol *cb{FindCommonBlockUse(name)}) {
+  } else if (Symbol * cb{FindCommonBlockUse(name)}) {
     return &cb->GetUltimate();
   } else if (IsSubmodule()) {
     if (const Scope *parent{

>From 8f802f71847748d71fce41c3f1a17d4052e2198e Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Thu, 16 Oct 2025 16:43:25 -0400
Subject: [PATCH 17/17] Code review feedback

---
 flang/include/flang/Semantics/scope.h |  2 +-
 flang/lib/Semantics/resolve-names.cpp | 11 +++++------
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h
index b49b6d58cc5e6..dd3f3723086c7 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -192,7 +192,7 @@ class Scope {
   bool AddCommonBlockUse(const SourceName &name, Symbol &cbSymbol);
   mapType &commonBlockUses() { return commonBlockUses_; }
 
-  // Find COMMON block that is not USE-associated in the current scope
+  // Find COMMON block that is declared in the current scope
   Symbol *FindCommonBlock(const SourceName &name) const {
     if (const auto it{commonBlocks_.find(name)}; it != commonBlocks_.end()) {
       return &*it->second;
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 6e6f4eb77edf2..f62ea72281e6e 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -3630,12 +3630,11 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
   // Go through the list of COMMON block symbols in the module scope and add
   // their USE association to the current scope's USE-associated COMMON blocks.
   for (const auto &[name, symbol] : useModuleScope_->commonBlocks()) {
-    if (Symbol *localCB{currScope().FindCommonBlockInSurroundingScopes(name)};
-        !localCB) {
+    if (!currScope().FindCommonBlockInSurroundingScopes(name)) {
       // Make a symbol, but don't add it to the Scope, since it needs to
       // be added to the USE-associated COMMON blocks
-      localCB = &currScope().MakeSymbol(
-          name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()});
+      Symbol *localCB{&currScope().MakeSymbol(
+          name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()})};
       currScope().AddCommonBlockUse(name, *localCB);
     }
   }
@@ -3645,8 +3644,8 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
   for (const auto &[name, symbol] : useModuleScope_->commonBlockUses()) {
     // Make a symbol, but don't add it to the Scope, since it needs to
     // be added to the USE-associated COMMON blocks
-    Symbol *localCB = &currScope().MakeSymbol(
-        name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()});
+    Symbol *localCB{&currScope().MakeSymbol(
+        name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()})};
     currScope().AddCommonBlockUse(name, *localCB);
   }
   useModuleScope_ = nullptr;



More information about the flang-commits mailing list