From 042d2f66bd632fb5d83df0ca4d5c0a3ede031c1c Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Mon, 6 Oct 2025 05:51:32 -0400 Subject: [PATCH 01/29] [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 Date: Thu, 9 Oct 2025 06:30:51 -0400 Subject: [PATCH 02/29] 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()) { + name->symbol = sym; + return sym; + } + } return nullptr; } From 86cb8b62c9c546f4e5c909a2500e4e8563bd2839 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Thu, 9 Oct 2025 09:54:23 -0400 Subject: [PATCH 03/29] 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()) { - 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 Date: Thu, 9 Oct 2025 12:16:44 -0400 Subject: [PATCH 04/29] 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 Date: Thu, 9 Oct 2025 17:01:10 -0400 Subject: [PATCH 05/29] 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 Date: Mon, 13 Oct 2025 07:05:56 -0400 Subject: [PATCH 06/29] 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().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 Date: Mon, 13 Oct 2025 07:08:55 -0400 Subject: [PATCH 07/29] 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().parent() : nullptr}; + const Scope *parent{ + symbol_ ? symbol_->get().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 Date: Mon, 13 Oct 2025 12:48:06 -0400 Subject: [PATCH 08/29] 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 common::IfNoLvalue 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()) { + 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().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().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 Date: Mon, 13 Oct 2025 15:22:42 -0400 Subject: [PATCH 09/29] 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()) { + // 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()) { + 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()) { + // Skip USE associated COMMON blocks + continue; + } if (symbol.get().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 Date: Mon, 13 Oct 2025 16:30:08 -0400 Subject: [PATCH 10/29] 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()) { + // 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 Date: Mon, 13 Oct 2025 16:31:09 -0400 Subject: [PATCH 11/29] 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().parent() : nullptr}) { + if (const Scope *parent{ + symbol_ ? symbol_->get().parent() : nullptr}) { if (auto *cb{parent->FindCommonBlockInScopes(name)}) { return &cb->GetUltimate(); } From c042379c73ea479fd25dceffa4084e686806ce63 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Thu, 16 Oct 2025 14:13:59 -0400 Subject: [PATCH 12/29] 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 @@ -298,6 +303,7 @@ class Scope { std::list children_; mapType symbols_; mapType commonBlocks_; + mapType useCommonBlocks_; // USE-assocated COMMON blocks std::list equivalenceSets_; mapType crayPointers_; std::map> 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()) { - // 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()) { - 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()) { - // Skip USE associated COMMON blocks - continue; - } if (symbol.get().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()) { - // 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()) { - 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().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 Date: Thu, 16 Oct 2025 14:41:03 -0400 Subject: [PATCH 13/29] 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 children_; mapType symbols_; mapType commonBlocks_; - mapType useCommonBlocks_; // USE-assocated COMMON blocks + mapType commonBlockUses_; // USE-assocated COMMON blocks std::list equivalenceSets_; mapType crayPointers_; std::map> 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 Date: Thu, 16 Oct 2025 14:45:29 -0400 Subject: [PATCH 14/29] 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 Date: Thu, 16 Oct 2025 15:02:04 -0400 Subject: [PATCH 15/29] 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 Date: Thu, 16 Oct 2025 15:48:49 -0400 Subject: [PATCH 16/29] 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 Date: Thu, 16 Oct 2025 16:43:25 -0400 Subject: [PATCH 17/29] 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; From b711009a23a34efbf6788aab81d5436dd44e9ff2 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Thu, 16 Oct 2025 22:06:36 -0400 Subject: [PATCH 18/29] Renamed to FindCommonBlockInVisibleScope() --- flang/include/flang/Semantics/scope.h | 2 +- flang/lib/Semantics/resolve-directives.cpp | 2 +- flang/lib/Semantics/resolve-names.cpp | 2 +- flang/lib/Semantics/scope.cpp | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h index dd3f3723086c7..9a99aea17fcfe 100644 --- a/flang/include/flang/Semantics/scope.h +++ b/flang/include/flang/Semantics/scope.h @@ -211,7 +211,7 @@ class Scope { // Find COMMON block in current and surrounding scopes, follow USE // associations - Symbol *FindCommonBlockInSurroundingScopes(const SourceName &) const; + Symbol *FindCommonBlockInVisibleScopes(const SourceName &) const; /// Make a Symbol but don't add it to the scope. template diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 74089d6ad03b4..8c1fa3e68fe20 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -1732,7 +1732,7 @@ Symbol *AccAttributeVisitor::ResolveAccCommonBlockName( if (!name) { return nullptr; } - if (auto *cb{GetContext().scope.FindCommonBlockInSurroundingScopes( + if (auto *cb{GetContext().scope.FindCommonBlockInVisibleScopes( name->source)}) { name->symbol = cb; return cb; diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index f62ea72281e6e..bd98aa182d5df 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 (!currScope().FindCommonBlockInSurroundingScopes(name)) { + if (!currScope().FindCommonBlockInVisibleScopes(name)) { // 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( diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp index a2c3891ec31b8..1a720098cafe9 100644 --- a/flang/lib/Semantics/scope.cpp +++ b/flang/lib/Semantics/scope.cpp @@ -154,7 +154,7 @@ Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) { } } -Symbol *Scope::FindCommonBlockInSurroundingScopes( +Symbol *Scope::FindCommonBlockInVisibleScopes( const SourceName &name) const { if (Symbol * cb{FindCommonBlock(name)}) { return cb; @@ -163,12 +163,12 @@ Symbol *Scope::FindCommonBlockInSurroundingScopes( } else if (IsSubmodule()) { if (const Scope *parent{ symbol_ ? symbol_->get().parent() : nullptr}) { - if (auto *cb{parent->FindCommonBlockInSurroundingScopes(name)}) { + if (auto *cb{parent->FindCommonBlockInVisibleScopes(name)}) { return cb; } } } else if (!IsTopLevel() && parent_) { - if (auto *cb{parent_->FindCommonBlockInSurroundingScopes(name)}) { + if (auto *cb{parent_->FindCommonBlockInVisibleScopes(name)}) { return cb; } } From ee0cddebebf0de01b418d111f10a9fbdc56df1a3 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Thu, 16 Oct 2025 22:09:37 -0400 Subject: [PATCH 19/29] clang-format --- flang/lib/Semantics/resolve-directives.cpp | 4 ++-- flang/lib/Semantics/scope.cpp | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 8c1fa3e68fe20..411d2befee962 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -1732,8 +1732,8 @@ Symbol *AccAttributeVisitor::ResolveAccCommonBlockName( if (!name) { return nullptr; } - if (auto *cb{GetContext().scope.FindCommonBlockInVisibleScopes( - name->source)}) { + if (auto *cb{ + GetContext().scope.FindCommonBlockInVisibleScopes(name->source)}) { name->symbol = cb; return cb; } diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp index 1a720098cafe9..fff0516ce9231 100644 --- a/flang/lib/Semantics/scope.cpp +++ b/flang/lib/Semantics/scope.cpp @@ -154,8 +154,7 @@ Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) { } } -Symbol *Scope::FindCommonBlockInVisibleScopes( - const SourceName &name) const { +Symbol *Scope::FindCommonBlockInVisibleScopes(const SourceName &name) const { if (Symbol * cb{FindCommonBlock(name)}) { return cb; } else if (Symbol * cb{FindCommonBlockUse(name)}) { From 6c8e7a0ce0e3fe39349613b4f07fbda1012e41e8 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Thu, 16 Oct 2025 16:43:25 -0400 Subject: [PATCH 20/29] 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; From bab4e67b3190c4709ecd60e2551ad6671e851ef0 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Thu, 16 Oct 2025 22:06:36 -0400 Subject: [PATCH 21/29] Renamed to FindCommonBlockInVisibleScope() --- flang/include/flang/Semantics/scope.h | 2 +- flang/lib/Semantics/resolve-directives.cpp | 2 +- flang/lib/Semantics/resolve-names.cpp | 2 +- flang/lib/Semantics/scope.cpp | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h index dd3f3723086c7..9a99aea17fcfe 100644 --- a/flang/include/flang/Semantics/scope.h +++ b/flang/include/flang/Semantics/scope.h @@ -211,7 +211,7 @@ class Scope { // Find COMMON block in current and surrounding scopes, follow USE // associations - Symbol *FindCommonBlockInSurroundingScopes(const SourceName &) const; + Symbol *FindCommonBlockInVisibleScopes(const SourceName &) const; /// Make a Symbol but don't add it to the scope. template diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 74089d6ad03b4..8c1fa3e68fe20 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -1732,7 +1732,7 @@ Symbol *AccAttributeVisitor::ResolveAccCommonBlockName( if (!name) { return nullptr; } - if (auto *cb{GetContext().scope.FindCommonBlockInSurroundingScopes( + if (auto *cb{GetContext().scope.FindCommonBlockInVisibleScopes( name->source)}) { name->symbol = cb; return cb; diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index f62ea72281e6e..bd98aa182d5df 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 (!currScope().FindCommonBlockInSurroundingScopes(name)) { + if (!currScope().FindCommonBlockInVisibleScopes(name)) { // 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( diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp index a2c3891ec31b8..1a720098cafe9 100644 --- a/flang/lib/Semantics/scope.cpp +++ b/flang/lib/Semantics/scope.cpp @@ -154,7 +154,7 @@ Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) { } } -Symbol *Scope::FindCommonBlockInSurroundingScopes( +Symbol *Scope::FindCommonBlockInVisibleScopes( const SourceName &name) const { if (Symbol * cb{FindCommonBlock(name)}) { return cb; @@ -163,12 +163,12 @@ Symbol *Scope::FindCommonBlockInSurroundingScopes( } else if (IsSubmodule()) { if (const Scope *parent{ symbol_ ? symbol_->get().parent() : nullptr}) { - if (auto *cb{parent->FindCommonBlockInSurroundingScopes(name)}) { + if (auto *cb{parent->FindCommonBlockInVisibleScopes(name)}) { return cb; } } } else if (!IsTopLevel() && parent_) { - if (auto *cb{parent_->FindCommonBlockInSurroundingScopes(name)}) { + if (auto *cb{parent_->FindCommonBlockInVisibleScopes(name)}) { return cb; } } From ab01526c2b7fda8f3cf22a89a58db4573ac1ec2e Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Thu, 16 Oct 2025 22:09:37 -0400 Subject: [PATCH 22/29] clang-format --- flang/lib/Semantics/resolve-directives.cpp | 4 ++-- flang/lib/Semantics/scope.cpp | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 8c1fa3e68fe20..411d2befee962 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -1732,8 +1732,8 @@ Symbol *AccAttributeVisitor::ResolveAccCommonBlockName( if (!name) { return nullptr; } - if (auto *cb{GetContext().scope.FindCommonBlockInVisibleScopes( - name->source)}) { + if (auto *cb{ + GetContext().scope.FindCommonBlockInVisibleScopes(name->source)}) { name->symbol = cb; return cb; } diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp index 1a720098cafe9..fff0516ce9231 100644 --- a/flang/lib/Semantics/scope.cpp +++ b/flang/lib/Semantics/scope.cpp @@ -154,8 +154,7 @@ Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) { } } -Symbol *Scope::FindCommonBlockInVisibleScopes( - const SourceName &name) const { +Symbol *Scope::FindCommonBlockInVisibleScopes(const SourceName &name) const { if (Symbol * cb{FindCommonBlock(name)}) { return cb; } else if (Symbol * cb{FindCommonBlockUse(name)}) { From f2028c77465866bfa90a658096871fa4ebe624d6 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Mon, 20 Oct 2025 12:24:43 -0400 Subject: [PATCH 23/29] Code review feedback --- flang/include/flang/Semantics/scope.h | 10 +++++++--- flang/lib/Semantics/resolve-directives.cpp | 13 ++++++------- flang/lib/Semantics/resolve-names.cpp | 8 ++++---- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h index 9a99aea17fcfe..e0d6f2635b8a9 100644 --- a/flang/include/flang/Semantics/scope.h +++ b/flang/include/flang/Semantics/scope.h @@ -86,6 +86,13 @@ class Scope { CHECK(parent_ != this); return *parent_; } + + mapType &commonBlocks() { return commonBlocks_; } + const mapType &commonBlocks() const { return commonBlocks_; } + + mapType &commonBlockUses() { return commonBlockUses_; } + const mapType &commonBlockUses() const { return commonBlockUses_; } + Kind kind() const { return kind_; } bool IsGlobal() const { return kind_ == Kind::Global; } bool IsIntrinsicModules() const { return kind_ == Kind::IntrinsicModules; } @@ -186,11 +193,8 @@ class Scope { // Cray pointers are saved as map of pointee name -> pointer symbol const mapType &crayPointers() const { return crayPointers_; } void add_crayPointer(const SourceName &, Symbol &); - mapType &commonBlocks() { return commonBlocks_; } - 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 declared in the current scope Symbol *FindCommonBlock(const SourceName &name) const { diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 411d2befee962..75a89c4e54647 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -1729,13 +1729,12 @@ void AccAttributeVisitor::Post(const parser::Name &name) { Symbol *AccAttributeVisitor::ResolveAccCommonBlockName( const parser::Name *name) { - if (!name) { - return nullptr; - } - if (auto *cb{ - GetContext().scope.FindCommonBlockInVisibleScopes(name->source)}) { - name->symbol = cb; - return cb; + if (name) { + if (Symbol *cb{ + GetContext().scope.FindCommonBlockInVisibleScopes(name->source)}) { + name->symbol = cb; + return cb; + } } return nullptr; } diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index bd98aa182d5df..260adb96a840a 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -3633,9 +3633,9 @@ void ModuleVisitor::Post(const parser::UseStmt &x) { if (!currScope().FindCommonBlockInVisibleScopes(name)) { // 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( + Symbol &localCB{currScope().MakeSymbol( name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()})}; - currScope().AddCommonBlockUse(name, *localCB); + currScope().AddCommonBlockUse(name, localCB); } } // Go through the list of USE-associated COMMON block symbols in the module @@ -3644,9 +3644,9 @@ 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( + Symbol &localCB{currScope().MakeSymbol( name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()})}; - currScope().AddCommonBlockUse(name, *localCB); + currScope().AddCommonBlockUse(name, localCB); } useModuleScope_ = nullptr; } From acde775d9a480cd392c4a1520f2e8ad95b662eee Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Mon, 20 Oct 2025 12:51:22 -0400 Subject: [PATCH 24/29] clang-format --- flang/lib/Semantics/resolve-directives.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index f7361b6990e8d..126d27c02702b 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -1731,8 +1731,8 @@ void AccAttributeVisitor::Post(const parser::Name &name) { Symbol *AccAttributeVisitor::ResolveAccCommonBlockName( const parser::Name *name) { if (name) { - if (Symbol *cb{ - GetContext().scope.FindCommonBlockInVisibleScopes(name->source)}) { + if (Symbol * + cb{GetContext().scope.FindCommonBlockInVisibleScopes(name->source)}) { name->symbol = cb; return cb; } From abd2f40096c84516fc42df6a962fa61ff7dbbebd Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Mon, 20 Oct 2025 17:21:00 -0400 Subject: [PATCH 25/29] [AddOrUpdateCommonBlockUse] Implemented selection of largest COMMON block in case of uses from multiple modules, except that it doesn't work: COMMON block sizes are computed after the name resolution --- flang/include/flang/Semantics/scope.h | 2 +- flang/lib/Semantics/resolve-names.cpp | 12 ++---------- flang/lib/Semantics/scope.cpp | 20 ++++++++++++++++++-- flang/lib/Semantics/symbol.cpp | 11 ++++++++++- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h index e0d6f2635b8a9..69f282acbb9bd 100644 --- a/flang/include/flang/Semantics/scope.h +++ b/flang/include/flang/Semantics/scope.h @@ -194,7 +194,7 @@ class Scope { const mapType &crayPointers() const { return crayPointers_; } void add_crayPointer(const SourceName &, Symbol &); Symbol &MakeCommonBlock(SourceName, SourceName location); - bool AddCommonBlockUse(const SourceName &name, Symbol &cbSymbol); + bool AddOrUpdateCommonBlockUse(const SourceName &name, Attrs attrs, Symbol& cbUltimate); // Find COMMON block that is declared in the current scope Symbol *FindCommonBlock(const SourceName &name) const { diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index 260adb96a840a..c3bcce6b2d939 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -3631,22 +3631,14 @@ void ModuleVisitor::Post(const parser::UseStmt &x) { // their USE association to the current scope's USE-associated COMMON blocks. for (const auto &[name, symbol] : useModuleScope_->commonBlocks()) { if (!currScope().FindCommonBlockInVisibleScopes(name)) { - // 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); + currScope().AddOrUpdateCommonBlockUse(name, symbol->attrs(), symbol->GetUltimate()); } } // 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); + currScope().AddOrUpdateCommonBlockUse(name, symbol->attrs(), symbol->GetUltimate()); } useModuleScope_ = nullptr; } diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp index fff0516ce9231..296da0771184b 100644 --- a/flang/lib/Semantics/scope.cpp +++ b/flang/lib/Semantics/scope.cpp @@ -183,8 +183,24 @@ Scope *Scope::FindSubmodule(const SourceName &name) const { } } -bool Scope::AddCommonBlockUse(const SourceName &name, Symbol &cbSymbol) { - return commonBlockUses_.emplace(name, cbSymbol).second; +bool Scope::AddOrUpdateCommonBlockUse(const SourceName &name, Attrs attrs, Symbol& cbUltimate) { + CHECK(cbUltimate.has()); + if (Symbol *cb{FindCommonBlockUse(name)}) { + // We already stored UseDetails from the previous encounter with the + // same named COMMON block (perhaps it came from a different module). + // Ensure that we store USE association to the largest COMMON block, + // which is presumably is better defined. + Symbol &cbExistingUltimate{cb->GetUltimate()}; + if (cbExistingUltimate.size() < cbUltimate.size()) { + cb->set_details(UseDetails{name, cbUltimate}); + } + return true; + } else { + // Make a symbol, but don't add it to the Scope, since it needs to + // be added to the USE-associated COMMON blocks + Symbol &useCB{MakeSymbol(name, attrs, UseDetails{name, cbUltimate})}; + return commonBlockUses_.emplace(name, useCB).second; + } } bool Scope::AddSubmodule(const SourceName &name, Scope &submodule) { diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp index 0ec44b7c40491..e3119896b648e 100644 --- a/flang/lib/Semantics/symbol.cpp +++ b/flang/lib/Semantics/symbol.cpp @@ -373,7 +373,16 @@ bool Symbol::CanReplaceDetails(const Details &details) const { }, [&](const UseDetails &x) { const auto *use{this->detailsIf()}; - return use && use->symbol() == x.symbol(); + if (!use) { + return false; + } else if (use->symbol().detailsIf() && + x.symbol().detailsIf()) { + // Allow to replace UseDetails, if they both refer to COMMON + // symbol with the same name. + return use->symbol().name() == x.symbol().name(); + } else { + return use->symbol() == x.symbol(); + } }, [&](const HostAssocDetails &) { return has(); }, [&](const UserReductionDetails &) { From fc6beb743dd765ae1fd583b4cbd996caed4e6b49 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Mon, 20 Oct 2025 18:10:22 -0400 Subject: [PATCH 26/29] [AddOrUpdateCommonBlockUse] Implemented selection of largest COMMON block in case of uses from multiple modules, except that it doesn't work: COMMON block sizes are computed after the name resolution --- flang/include/flang/Semantics/scope.h | 2 +- flang/lib/Semantics/resolve-names.cpp | 4 ++-- flang/lib/Semantics/scope.cpp | 22 +++++----------------- flang/lib/Semantics/symbol.cpp | 11 +---------- 4 files changed, 9 insertions(+), 30 deletions(-) diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h index 69f282acbb9bd..df713c0d8bc3b 100644 --- a/flang/include/flang/Semantics/scope.h +++ b/flang/include/flang/Semantics/scope.h @@ -194,7 +194,7 @@ class Scope { const mapType &crayPointers() const { return crayPointers_; } void add_crayPointer(const SourceName &, Symbol &); Symbol &MakeCommonBlock(SourceName, SourceName location); - bool AddOrUpdateCommonBlockUse(const SourceName &name, Attrs attrs, Symbol& cbUltimate); + bool AddCommonBlockUse(const SourceName &name, Attrs attrs, Symbol& cbUltimate); // Find COMMON block that is declared in the current scope Symbol *FindCommonBlock(const SourceName &name) const { diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index c3bcce6b2d939..b408d0dd24a1e 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -3631,14 +3631,14 @@ void ModuleVisitor::Post(const parser::UseStmt &x) { // their USE association to the current scope's USE-associated COMMON blocks. for (const auto &[name, symbol] : useModuleScope_->commonBlocks()) { if (!currScope().FindCommonBlockInVisibleScopes(name)) { - currScope().AddOrUpdateCommonBlockUse(name, symbol->attrs(), symbol->GetUltimate()); + currScope().AddCommonBlockUse(name, symbol->attrs(), symbol->GetUltimate()); } } // 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()) { - currScope().AddOrUpdateCommonBlockUse(name, symbol->attrs(), symbol->GetUltimate()); + currScope().AddCommonBlockUse(name, symbol->attrs(), symbol->GetUltimate()); } useModuleScope_ = nullptr; } diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp index 296da0771184b..98966dfea1186 100644 --- a/flang/lib/Semantics/scope.cpp +++ b/flang/lib/Semantics/scope.cpp @@ -183,24 +183,12 @@ Scope *Scope::FindSubmodule(const SourceName &name) const { } } -bool Scope::AddOrUpdateCommonBlockUse(const SourceName &name, Attrs attrs, Symbol& cbUltimate) { +bool Scope::AddCommonBlockUse(const SourceName &name, Attrs attrs, Symbol& cbUltimate) { CHECK(cbUltimate.has()); - if (Symbol *cb{FindCommonBlockUse(name)}) { - // We already stored UseDetails from the previous encounter with the - // same named COMMON block (perhaps it came from a different module). - // Ensure that we store USE association to the largest COMMON block, - // which is presumably is better defined. - Symbol &cbExistingUltimate{cb->GetUltimate()}; - if (cbExistingUltimate.size() < cbUltimate.size()) { - cb->set_details(UseDetails{name, cbUltimate}); - } - return true; - } else { - // Make a symbol, but don't add it to the Scope, since it needs to - // be added to the USE-associated COMMON blocks - Symbol &useCB{MakeSymbol(name, attrs, UseDetails{name, cbUltimate})}; - return commonBlockUses_.emplace(name, useCB).second; - } + // Make a symbol, but don't add it to the Scope, since it needs to + // be added to the USE-associated COMMON blocks + Symbol &useCB{MakeSymbol(name, attrs, UseDetails{name, cbUltimate})}; + return commonBlockUses_.emplace(name, useCB).second; } bool Scope::AddSubmodule(const SourceName &name, Scope &submodule) { diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp index e3119896b648e..0ec44b7c40491 100644 --- a/flang/lib/Semantics/symbol.cpp +++ b/flang/lib/Semantics/symbol.cpp @@ -373,16 +373,7 @@ bool Symbol::CanReplaceDetails(const Details &details) const { }, [&](const UseDetails &x) { const auto *use{this->detailsIf()}; - if (!use) { - return false; - } else if (use->symbol().detailsIf() && - x.symbol().detailsIf()) { - // Allow to replace UseDetails, if they both refer to COMMON - // symbol with the same name. - return use->symbol().name() == x.symbol().name(); - } else { - return use->symbol() == x.symbol(); - } + return use && use->symbol() == x.symbol(); }, [&](const HostAssocDetails &) { return has(); }, [&](const UserReductionDetails &) { From 19c1534679a135b5c668a94a3eb2aab3b40993f1 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Mon, 20 Oct 2025 18:11:00 -0400 Subject: [PATCH 27/29] clang-format --- flang/include/flang/Semantics/scope.h | 3 ++- flang/lib/Semantics/resolve-names.cpp | 3 ++- flang/lib/Semantics/scope.cpp | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h index df713c0d8bc3b..77edfe16e3010 100644 --- a/flang/include/flang/Semantics/scope.h +++ b/flang/include/flang/Semantics/scope.h @@ -194,7 +194,8 @@ class Scope { const mapType &crayPointers() const { return crayPointers_; } void add_crayPointer(const SourceName &, Symbol &); Symbol &MakeCommonBlock(SourceName, SourceName location); - bool AddCommonBlockUse(const SourceName &name, Attrs attrs, Symbol& cbUltimate); + bool AddCommonBlockUse( + const SourceName &name, Attrs attrs, Symbol &cbUltimate); // Find COMMON block that is declared in the current scope Symbol *FindCommonBlock(const SourceName &name) const { diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index b408d0dd24a1e..7e143b6ec4d75 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -3631,7 +3631,8 @@ void ModuleVisitor::Post(const parser::UseStmt &x) { // their USE association to the current scope's USE-associated COMMON blocks. for (const auto &[name, symbol] : useModuleScope_->commonBlocks()) { if (!currScope().FindCommonBlockInVisibleScopes(name)) { - currScope().AddCommonBlockUse(name, symbol->attrs(), symbol->GetUltimate()); + currScope().AddCommonBlockUse( + name, symbol->attrs(), symbol->GetUltimate()); } } // Go through the list of USE-associated COMMON block symbols in the module diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp index 98966dfea1186..b19bb94a3c65c 100644 --- a/flang/lib/Semantics/scope.cpp +++ b/flang/lib/Semantics/scope.cpp @@ -183,7 +183,8 @@ Scope *Scope::FindSubmodule(const SourceName &name) const { } } -bool Scope::AddCommonBlockUse(const SourceName &name, Attrs attrs, Symbol& cbUltimate) { +bool Scope::AddCommonBlockUse( + const SourceName &name, Attrs attrs, Symbol &cbUltimate) { CHECK(cbUltimate.has()); // Make a symbol, but don't add it to the Scope, since it needs to // be added to the USE-associated COMMON blocks From e7370beae6c7c9ad744aad521e98cd1e52277210 Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 21 Oct 2025 14:25:01 -0400 Subject: [PATCH 28/29] Updated the test with a_common defined with more variables in a different module --- flang/test/Semantics/OpenACC/acc-common.f90 | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/flang/test/Semantics/OpenACC/acc-common.f90 b/flang/test/Semantics/OpenACC/acc-common.f90 index 1843ff7d8cd13..31c4d190d576b 100644 --- a/flang/test/Semantics/OpenACC/acc-common.f90 +++ b/flang/test/Semantics/OpenACC/acc-common.f90 @@ -7,6 +7,13 @@ module acc_common_decl data a/42/ end module acc_common_decl +module acc_common_another + implicit none + integer c, d + common /a_common/ c, d +!$acc declare create (/a_common/) +end module acc_common_another + module acc_common_intermediate use acc_common_decl implicit none @@ -17,6 +24,7 @@ end module acc_common_intermediate program acc_decl_test use acc_common_intermediate + use acc_common_another implicit none a = 1 @@ -25,6 +33,9 @@ program acc_decl_test a = 2 !$acc update device (/b_common/) b = 20 +!$acc update device (/a_common/) + c = 3 + d = 30 !ERROR: Could not find COMMON block 'a_common_bad' used in OpenACC directive !$acc update device (/a_common_bad/) end program From dadf669af695b27db71840272bd3a9cd5865b7dd Mon Sep 17 00:00:00 2001 From: Eugene Epshteyn Date: Tue, 21 Oct 2025 15:34:04 -0400 Subject: [PATCH 29/29] Moved Scope::FindCommonBlock() and Scope::FindCommonBlockUse() implementations to .cpp file --- flang/include/flang/Semantics/scope.h | 15 ++------------- flang/lib/Semantics/scope.cpp | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h index 77edfe16e3010..ecffdb468bf6c 100644 --- a/flang/include/flang/Semantics/scope.h +++ b/flang/include/flang/Semantics/scope.h @@ -198,21 +198,10 @@ class Scope { const SourceName &name, Attrs attrs, Symbol &cbUltimate); // 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; - } - return nullptr; - } + Symbol *FindCommonBlock(const SourceName &name) const; // 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()) { - return &*it->second; - } - return nullptr; - } + Symbol *FindCommonBlockUse(const SourceName &name) const; // Find COMMON block in current and surrounding scopes, follow USE // associations diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp index b19bb94a3c65c..ab75d4c608387 100644 --- a/flang/lib/Semantics/scope.cpp +++ b/flang/lib/Semantics/scope.cpp @@ -192,6 +192,21 @@ bool Scope::AddCommonBlockUse( return commonBlockUses_.emplace(name, useCB).second; } +Symbol *Scope::FindCommonBlock(const SourceName &name) const { + if (const auto it{commonBlocks_.find(name)}; it != commonBlocks_.end()) { + return &*it->second; + } + return nullptr; +} + +Symbol *Scope::FindCommonBlockUse(const SourceName &name) const { + if (const auto it{commonBlockUses_.find(name)}; + it != commonBlockUses_.end()) { + return &*it->second; + } + return nullptr; +} + bool Scope::AddSubmodule(const SourceName &name, Scope &submodule) { return submodules_.emplace(name, submodule).second; }