From: peter klausler Date: Thu, 21 Jan 2021 22:42:20 +0000 (-0800) Subject: [flang] Address name resolution problems X-Git-Tag: llvmorg-13-init~548 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3738447c96c7400d0e9b9b00b583dca45fb0807f;p=platform%2Fupstream%2Fllvm.git [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 --- 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 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() && + &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()) && !symbol->has() && 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(enumerator.t).v}; Symbol *symbol{FindSymbol(name)}; - if (symbol) { + if (symbol && !symbol->has()) { // 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.