diff options
author | peter klausler <pklausler@nvidia.com> | 2021-01-21 14:42:20 -0800 |
---|---|---|
committer | peter klausler <pklausler@nvidia.com> | 2021-01-21 16:15:38 -0800 |
commit | 3738447c96c7400d0e9b9b00b583dca45fb0807f (patch) | |
tree | 9ba9fca3f8bfbf981dfdf1c1b548fe9ce1ac2668 /flang | |
parent | 6e360460f14b4904f197b805f0f4659f4b960a16 (diff) | |
download | llvm-3738447c96c7400d0e9b9b00b583dca45fb0807f.zip llvm-3738447c96c7400d0e9b9b00b583dca45fb0807f.tar.gz llvm-3738447c96c7400d0e9b9b00b583dca45fb0807f.tar.bz2 |
[flang] Address name resolution problems
Don't emit a bogus error message about a bad forward reference
when it's an IMPORT of a USE-associated symbol; don't ignore
intrinsic functions when USE-associating the contents of a
module when the intrinsic has been explicitly USE'd; allow
PUBLIC or PRIVATE accessibility attribute to be specified
for an enumerator before the declaration of the enumerator.
Differential Revision: https://reviews.llvm.org/D95175
Diffstat (limited to 'flang')
-rw-r--r-- | flang/lib/Semantics/resolve-names.cpp | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index d76abbf..2b7ee04 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -2238,6 +2238,12 @@ std::optional<SourceName> ScopeHandler::HadForwardRef( bool ScopeHandler::CheckPossibleBadForwardRef(const Symbol &symbol) { if (!context().HasError(symbol)) { if (auto fwdRef{HadForwardRef(symbol)}) { + const Symbol *outer{symbol.owner().FindSymbol(symbol.name())}; + if (outer && symbol.has<UseDetails>() && + &symbol.GetUltimate() == &outer->GetUltimate()) { + // e.g. IMPORT of host's USE association + return false; + } Say(*fwdRef, "Forward reference to '%s' is not allowed in the same specification part"_err_en_US, *fwdRef) @@ -2332,7 +2338,8 @@ void ModuleVisitor::Post(const parser::UseStmt &x) { } for (const auto &[name, symbol] : *useModuleScope_) { if (symbol->attrs().test(Attr::PUBLIC) && - !symbol->attrs().test(Attr::INTRINSIC) && + (!symbol->attrs().test(Attr::INTRINSIC) || + symbol->has<UseDetails>()) && !symbol->has<MiscDetails>() && useNames.count(name) == 0) { SourceName location{x.moduleName.source}; if (auto *localSymbol{FindInScope(name)}) { @@ -3310,10 +3317,11 @@ bool DeclarationVisitor::Pre(const parser::NamedConstant &x) { bool DeclarationVisitor::Pre(const parser::Enumerator &enumerator) { const parser::Name &name{std::get<parser::NamedConstant>(enumerator.t).v}; Symbol *symbol{FindSymbol(name)}; - if (symbol) { + if (symbol && !symbol->has<UnknownDetails>()) { // Contrary to named constants appearing in a PARAMETER statement, // enumerator names should not have their type, dimension or any other - // attributes defined before they are declared in the enumerator statement. + // attributes defined before they are declared in the enumerator statement, + // with the exception of accessibility. // This is not explicitly forbidden by the standard, but they are scalars // which type is left for the compiler to chose, so do not let users try to // tamper with that. |