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 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits