diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index d0d3b0e1caa5a..6f0a5a567a25c 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -955,7 +955,7 @@ class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor { bool HandlePreviousCalls(const parser::Name &, Symbol &, Symbol::Flag); const Symbol *CheckExtantProc(const parser::Name &, Symbol::Flag); // Create a subprogram symbol in the current scope and push a new scope. - Symbol &PushSubprogramScope(const parser::Name &, Symbol::Flag, + Symbol *PushSubprogramScope(const parser::Name &, Symbol::Flag, const parser::LanguageBindingSpec * = nullptr, bool hasModulePrefix = false); Symbol *GetSpecificFromGeneric(const parser::Name &); @@ -4501,10 +4501,13 @@ bool SubprogramVisitor::HandleStmtFunction(const parser::StmtFunctionStmt &x) { "'%s' has not been declared as an array or pointer-valued function"_err_en_US); return false; } - auto &symbol{PushSubprogramScope(name, Symbol::Flag::Function)}; - symbol.set(Symbol::Flag::StmtFunction); - EraseSymbol(symbol); // removes symbol added by PushSubprogramScope - auto &details{symbol.get()}; + Symbol *symbol{PushSubprogramScope(name, Symbol::Flag::Function)}; + if (!symbol) { + return false; + } + symbol->set(Symbol::Flag::StmtFunction); + EraseSymbol(*symbol); // removes symbol added by PushSubprogramScope + auto &details{symbol->get()}; for (const auto &dummyName : std::get>(x.t)) { ObjectEntityDetails dummyDetails{true}; if (auto *dummySymbol{FindInScope(currScope().parent(), dummyName)}) { @@ -5133,19 +5136,22 @@ bool SubprogramVisitor::BeginSubprogram(const parser::Name &name, } } } - Symbol &newSymbol{ + Symbol *newSymbol{ PushSubprogramScope(name, subpFlag, bindingSpec, hasModulePrefix)}; + if (!newSymbol) { + return false; + } if (moduleInterface) { - newSymbol.get().set_moduleInterface(*moduleInterface); + newSymbol->get().set_moduleInterface(*moduleInterface); if (moduleInterface->attrs().test(Attr::PRIVATE)) { - SetImplicitAttr(newSymbol, Attr::PRIVATE); + SetImplicitAttr(*newSymbol, Attr::PRIVATE); } else if (moduleInterface->attrs().test(Attr::PUBLIC)) { - SetImplicitAttr(newSymbol, Attr::PUBLIC); + SetImplicitAttr(*newSymbol, Attr::PUBLIC); } } if (entryStmts) { for (const auto &ref : *entryStmts) { - CreateEntry(*ref, newSymbol); + CreateEntry(*ref, *newSymbol); } } return true; @@ -5252,12 +5258,16 @@ const Symbol *SubprogramVisitor::CheckExtantProc( return prev; } -Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name, +Symbol *SubprogramVisitor::PushSubprogramScope(const parser::Name &name, Symbol::Flag subpFlag, const parser::LanguageBindingSpec *bindingSpec, bool hasModulePrefix) { Symbol *symbol{GetSpecificFromGeneric(name)}; const DeclTypeSpec *previousImplicitType{nullptr}; SourceName previousName; + if (symbol && inInterfaceBlock() && !symbol->has()) { + SayAlreadyDeclared(name, *symbol); + return nullptr; + } if (!symbol) { if (bindingSpec && currScope().IsGlobal() && std::get>( @@ -5286,9 +5296,7 @@ Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name, if (subpFlag == Symbol::Flag::Function) { auto &funcResultTop{funcResultStack().Push(currScope(), name.source)}; funcResultTop.previousImplicitType = previousImplicitType; - ; funcResultTop.previousName = previousName; - ; } if (inInterfaceBlock()) { auto &details{symbol->get()}; @@ -5314,7 +5322,7 @@ Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name, found && found->has()) { found->set(subpFlag); // PushScope() created symbol } - return *symbol; + return symbol; } void SubprogramVisitor::PushBlockDataScope(const parser::Name &name) { diff --git a/flang/test/Semantics/bug159554.f90 b/flang/test/Semantics/bug159554.f90 new file mode 100644 index 0000000000000..f5a51ebc0b5cb --- /dev/null +++ b/flang/test/Semantics/bug159554.f90 @@ -0,0 +1,8 @@ +!RUN: %python %S/test_errors.py %s %flang_fc1 +use, intrinsic :: iso_c_binding +interface c_funloc +!ERROR: 'c_funloc' is already declared in this scoping unit + function c_funloc() + end function +end interface +end