diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -2238,6 +2238,12 @@ 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 @@ } 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::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.