[flang-commits] [flang] fce3a66 - [flang] Preserve UseErrorDetails in module files (#189423)
via flang-commits
flang-commits at lists.llvm.org
Tue Mar 31 09:10:05 PDT 2026
Author: Peter Klausler
Date: 2026-03-31T09:10:00-07:00
New Revision: fce3a66f5e2f247890c57ac01a2c9847358c0f27
URL: https://github.com/llvm/llvm-project/commit/fce3a66f5e2f247890c57ac01a2c9847358c0f27
DIFF: https://github.com/llvm/llvm-project/commit/fce3a66f5e2f247890c57ac01a2c9847358c0f27.diff
LOG: [flang] Preserve UseErrorDetails in module files (#189423)
When the same name is USE-associated with two or more distinct ultimate
symbols, and they are not both generic procedure interfaces, it's not an
error unless the name is actually referenced in the scope. But when the
scope is itself a module or submodule, our module files don't preserve
the error for later diagnosis -- instead, the UseErrorDetails symbol
that serves as a "poison pill" in case of later use is discarded when
the module file is generated. So emit additional USE statements to the
module file so that a UseErrorDetails symbol is created anew when the
module file is read.
Added:
flang/test/Semantics/Inputs/modfile84.f90
flang/test/Semantics/modfile84.f90
Modified:
flang/lib/Semantics/mod-file.cpp
flang/lib/Semantics/mod-file.h
flang/lib/Semantics/resolve-names.cpp
Removed:
################################################################################
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 3bfe1e144f961..f880d33858f7e 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -528,7 +528,15 @@ void ModFileWriter::PutSymbol(
}
},
[&](const UseDetails &) { PutUse(symbol); },
- [](const UseErrorDetails &) {},
+ [&](const UseErrorDetails &x) {
+ for (const auto &[at, symptr] : x.occurrences()) {
+ if (symptr) {
+ UseDetails details{at, *symptr};
+ PutUseDetails(details);
+ uses_ << symbol.name() << "=>" << symptr->name() << '\n';
+ }
+ }
+ },
[&](const ProcBindingDetails &x) {
bool deferred{symbol.attrs().test(Attr::DEFERRED)};
typeBindings << "procedure";
@@ -852,8 +860,7 @@ void ModFileWriter::PutGeneric(const Symbol &symbol) {
}
}
-void ModFileWriter::PutUse(const Symbol &symbol) {
- auto &details{symbol.get<UseDetails>()};
+void ModFileWriter::PutUseDetails(const UseDetails &details) {
auto &use{details.symbol()};
const Symbol &module{GetUsedModule(details)};
if (use.owner().parent().IsIntrinsicModules()) {
@@ -863,9 +870,15 @@ void ModFileWriter::PutUse(const Symbol &symbol) {
usedNonIntrinsicModules_.insert(module);
}
uses_ << module.name() << ",only:";
+}
+
+void ModFileWriter::PutUse(const Symbol &symbol) {
+ const auto &details{symbol.get<UseDetails>()};
+ PutUseDetails(details);
PutGenericName(uses_, symbol);
// Can have intrinsic op with
diff erent local-name and use-name
// (e.g. `operator(<)` and `operator(.lt.)`) but rename is not allowed
+ auto &use{details.symbol()};
if (!IsIntrinsicOp(symbol) && use.name() != symbol.name()) {
PutGenericName(uses_ << "=>", use);
}
diff --git a/flang/lib/Semantics/mod-file.h b/flang/lib/Semantics/mod-file.h
index 9e5724089b3c5..f1a23394ef80b 100644
--- a/flang/lib/Semantics/mod-file.h
+++ b/flang/lib/Semantics/mod-file.h
@@ -83,6 +83,7 @@ class ModFileWriter {
void PutUserReduction(llvm::raw_ostream &, const Symbol &);
void PutSubprogram(const Symbol &);
void PutGeneric(const Symbol &);
+ void PutUseDetails(const UseDetails &);
void PutUse(const Symbol &);
void PutUseExtraAttr(Attr, const Symbol &, const Symbol &);
llvm::raw_ostream &PutAttrs(llvm::raw_ostream &, Attrs,
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index b6907cc792d76..e177363e4d440 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -9534,7 +9534,7 @@ void ResolveNamesVisitor::HandleProcedureName(
} else if (symbol->test(Symbol::Flag::Implicit)) {
Say(name,
"Use of '%s' as a procedure conflicts with its implicit definition"_err_en_US);
- } else {
+ } else if (!HadUseError(context(), name.source, symbol)) {
SayWithDecl(name, *symbol,
"Use of '%s' as a procedure conflicts with its declaration"_err_en_US);
}
diff --git a/flang/test/Semantics/Inputs/modfile84.f90 b/flang/test/Semantics/Inputs/modfile84.f90
new file mode 100644
index 0000000000000..d049749028509
--- /dev/null
+++ b/flang/test/Semantics/Inputs/modfile84.f90
@@ -0,0 +1,14 @@
+module modfile84A
+ contains
+ subroutine foo()
+ end subroutine
+end
+module modfile84B
+ contains
+ subroutine foo()
+ end
+end
+module modfile84AB
+ use modfile84A, only: foo, bar=>foo
+ use modfile84B, only: foo, bar=>foo
+end
diff --git a/flang/test/Semantics/modfile84.f90 b/flang/test/Semantics/modfile84.f90
new file mode 100644
index 0000000000000..d19e3813bd511
--- /dev/null
+++ b/flang/test/Semantics/modfile84.f90
@@ -0,0 +1,19 @@
+!RUN: rm -rf %t && mkdir -p %t
+!RUN: %flang_fc1 -fsyntax-only -J%t %S/Inputs/modfile84.f90
+!RUN: not %flang_fc1 -fsyntax-only -J%t %s 2>&1 | FileCheck %s
+
+!CHECK: error: Reference to 'foo' is ambiguous
+!CHECK: 'foo' was use-associated from module 'modfile84a'
+!CHECK: 'foo' was use-associated from module 'modfile84b'
+!CHECK: error: 'foo' is not a callable procedure
+!CHECK: 'foo' is USE-associated with 'foo' in module 'modfile84ab'
+!CHECK: error: Reference to 'bar' is ambiguous
+!CHECK: 'bar' was use-associated from module 'modfile84a'
+!CHECK: 'bar' was use-associated from module 'modfile84b'
+!CHECK: error: 'bar' is not a callable procedure
+!CHECK: 'bar' is USE-associated with 'bar' in module 'modfile84ab'
+
+use modfile84AB
+call foo()
+call bar()
+end
More information about the flang-commits
mailing list