[flang-commits] [flang] 3a0352b - [flang] Fix bug with USE of USE of generic
Tim Keith via flang-commits
flang-commits at lists.llvm.org
Tue Dec 15 16:12:27 PST 2020
Author: Tim Keith
Date: 2020-12-15T16:11:59-08:00
New Revision: 3a0352b85c14cb83150df62a9ea9ac3c4129060d
URL: https://github.com/llvm/llvm-project/commit/3a0352b85c14cb83150df62a9ea9ac3c4129060d
DIFF: https://github.com/llvm/llvm-project/commit/3a0352b85c14cb83150df62a9ea9ac3c4129060d.diff
LOG: [flang] Fix bug with USE of USE of generic
When merging use associations into a generic, we weren't handling
the case where the name that was use associated was itself a use
association. This is fixed by following that association to its
ultimate symbol (`useUltimate` in `DoAddUse`).
An example of the bug is `m12d` in `resolve17.f90`. `g` is associated
with `gc` in `m12c` which is associated with `gb` in `m12b`. It was that
last association that we weren't correctly following.
Differential Revision: https://reviews.llvm.org/D93343
Added:
Modified:
flang/lib/Semantics/resolve-names.cpp
flang/lib/Semantics/symbol.cpp
flang/test/Semantics/resolve17.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index b0e0b0b80ebf..5ac787b61d68 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2371,38 +2371,40 @@ void ModuleVisitor::DoAddUse(const SourceName &location,
const SourceName &localName, Symbol &localSymbol, const Symbol &useSymbol) {
localSymbol.attrs() = useSymbol.attrs() & ~Attrs{Attr::PUBLIC, Attr::PRIVATE};
localSymbol.flags() = useSymbol.flags();
+ const Symbol &useUltimate{useSymbol.GetUltimate()};
if (auto *useDetails{localSymbol.detailsIf<UseDetails>()}) {
- const Symbol &ultimate{localSymbol.GetUltimate()};
- if (ultimate == useSymbol.GetUltimate()) {
+ const Symbol &localUltimate{localSymbol.GetUltimate()};
+ if (localUltimate == useUltimate) {
// use-associating the same symbol again -- ok
- } else if (ultimate.has<GenericDetails>() &&
- useSymbol.has<GenericDetails>()) {
+ } else if (localUltimate.has<GenericDetails>() &&
+ useUltimate.has<GenericDetails>()) {
// use-associating generics with the same names: merge them into a
// new generic in this scope
- auto generic1{ultimate.get<GenericDetails>()};
- AddGenericUse(generic1, localName, useSymbol);
+ auto generic1{localUltimate.get<GenericDetails>()};
+ AddGenericUse(generic1, localName, useUltimate);
generic1.AddUse(localSymbol);
// useSymbol has specific g and so does generic1
- auto &generic2{useSymbol.get<GenericDetails>()};
+ auto &generic2{useUltimate.get<GenericDetails>()};
if (generic1.derivedType() && generic2.derivedType() &&
generic1.derivedType() != generic2.derivedType()) {
Say(location,
"Generic interface '%s' has ambiguous derived types"
" from modules '%s' and '%s'"_err_en_US,
localSymbol.name(), GetUsedModule(*useDetails).name(),
- useSymbol.owner().GetName().value());
+ useUltimate.owner().GetName().value());
context().SetError(localSymbol);
} else {
generic1.CopyFrom(generic2);
}
EraseSymbol(localSymbol);
- MakeSymbol(localSymbol.name(), ultimate.attrs(), std::move(generic1));
+ MakeSymbol(
+ localSymbol.name(), localUltimate.attrs(), std::move(generic1));
} else {
ConvertToUseError(localSymbol, location, *useModuleScope_);
}
} else if (auto *genericDetails{localSymbol.detailsIf<GenericDetails>()}) {
- if (const auto *useDetails{useSymbol.detailsIf<GenericDetails>()}) {
- AddGenericUse(*genericDetails, localName, useSymbol);
+ if (const auto *useDetails{useUltimate.detailsIf<GenericDetails>()}) {
+ AddGenericUse(*genericDetails, localName, useUltimate);
if (genericDetails->derivedType() && useDetails->derivedType() &&
genericDetails->derivedType() != useDetails->derivedType()) {
Say(location,
diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index ee6a4a15de83..656c993935cd 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -431,8 +431,11 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Details &details) {
},
[&](const UseErrorDetails &x) {
os << " uses:";
+ char sep{':'};
for (const auto &[location, module] : x.occurrences()) {
- os << " from " << module->GetName().value() << " at " << location;
+ os << sep << " from " << module->GetName().value() << " at "
+ << location;
+ sep = ',';
}
},
[](const HostAssocDetails &) {},
diff --git a/flang/test/Semantics/resolve17.f90 b/flang/test/Semantics/resolve17.f90
index 5aedaaa62003..2a2688749209 100644
--- a/flang/test/Semantics/resolve17.f90
+++ b/flang/test/Semantics/resolve17.f90
@@ -238,3 +238,30 @@ module m11c
!ERROR: Generic interface 'g' has ambiguous derived types from modules 'm11a' and 'm11b'
use m11b
end module
+
+module m12a
+ interface ga
+ module procedure sa
+ end interface
+contains
+ subroutine sa(i)
+ end
+end
+module m12b
+ use m12a
+ interface gb
+ module procedure sb
+ end interface
+contains
+ subroutine sb(x)
+ end
+end
+module m12c
+ use m12b, only: gc => gb
+end
+module m12d
+ use m12a, only: g => ga
+ use m12c, only: g => gc
+ interface g
+ end interface
+end module
More information about the flang-commits
mailing list