Skip to content

Commit b1eed3e

Browse files
committed
[flang] Fix crash from undetected program error.
When a function or subroutine interface block conflicts with a name already in scope, emit an error and avoid a crash. Fixes #159554.
1 parent d90a313 commit b1eed3e

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,7 @@ class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor {
955955
bool HandlePreviousCalls(const parser::Name &, Symbol &, Symbol::Flag);
956956
const Symbol *CheckExtantProc(const parser::Name &, Symbol::Flag);
957957
// Create a subprogram symbol in the current scope and push a new scope.
958-
Symbol &PushSubprogramScope(const parser::Name &, Symbol::Flag,
958+
Symbol *PushSubprogramScope(const parser::Name &, Symbol::Flag,
959959
const parser::LanguageBindingSpec * = nullptr,
960960
bool hasModulePrefix = false);
961961
Symbol *GetSpecificFromGeneric(const parser::Name &);
@@ -4501,10 +4501,13 @@ bool SubprogramVisitor::HandleStmtFunction(const parser::StmtFunctionStmt &x) {
45014501
"'%s' has not been declared as an array or pointer-valued function"_err_en_US);
45024502
return false;
45034503
}
4504-
auto &symbol{PushSubprogramScope(name, Symbol::Flag::Function)};
4505-
symbol.set(Symbol::Flag::StmtFunction);
4506-
EraseSymbol(symbol); // removes symbol added by PushSubprogramScope
4507-
auto &details{symbol.get<SubprogramDetails>()};
4504+
Symbol *symbol{PushSubprogramScope(name, Symbol::Flag::Function)};
4505+
if (!symbol) {
4506+
return false;
4507+
}
4508+
symbol->set(Symbol::Flag::StmtFunction);
4509+
EraseSymbol(*symbol); // removes symbol added by PushSubprogramScope
4510+
auto &details{symbol->get<SubprogramDetails>()};
45084511
for (const auto &dummyName : std::get<std::list<parser::Name>>(x.t)) {
45094512
ObjectEntityDetails dummyDetails{true};
45104513
if (auto *dummySymbol{FindInScope(currScope().parent(), dummyName)}) {
@@ -5133,19 +5136,22 @@ bool SubprogramVisitor::BeginSubprogram(const parser::Name &name,
51335136
}
51345137
}
51355138
}
5136-
Symbol &newSymbol{
5139+
Symbol *newSymbol{
51375140
PushSubprogramScope(name, subpFlag, bindingSpec, hasModulePrefix)};
5141+
if (!newSymbol) {
5142+
return false;
5143+
}
51385144
if (moduleInterface) {
5139-
newSymbol.get<SubprogramDetails>().set_moduleInterface(*moduleInterface);
5145+
newSymbol->get<SubprogramDetails>().set_moduleInterface(*moduleInterface);
51405146
if (moduleInterface->attrs().test(Attr::PRIVATE)) {
5141-
SetImplicitAttr(newSymbol, Attr::PRIVATE);
5147+
SetImplicitAttr(*newSymbol, Attr::PRIVATE);
51425148
} else if (moduleInterface->attrs().test(Attr::PUBLIC)) {
5143-
SetImplicitAttr(newSymbol, Attr::PUBLIC);
5149+
SetImplicitAttr(*newSymbol, Attr::PUBLIC);
51445150
}
51455151
}
51465152
if (entryStmts) {
51475153
for (const auto &ref : *entryStmts) {
5148-
CreateEntry(*ref, newSymbol);
5154+
CreateEntry(*ref, *newSymbol);
51495155
}
51505156
}
51515157
return true;
@@ -5252,12 +5258,16 @@ const Symbol *SubprogramVisitor::CheckExtantProc(
52525258
return prev;
52535259
}
52545260

5255-
Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
5261+
Symbol *SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
52565262
Symbol::Flag subpFlag, const parser::LanguageBindingSpec *bindingSpec,
52575263
bool hasModulePrefix) {
52585264
Symbol *symbol{GetSpecificFromGeneric(name)};
52595265
const DeclTypeSpec *previousImplicitType{nullptr};
52605266
SourceName previousName;
5267+
if (symbol && inInterfaceBlock() && !symbol->has<SubprogramDetails>()) {
5268+
SayAlreadyDeclared(name, *symbol);
5269+
return nullptr;
5270+
}
52615271
if (!symbol) {
52625272
if (bindingSpec && currScope().IsGlobal() &&
52635273
std::get<std::optional<parser::ScalarDefaultCharConstantExpr>>(
@@ -5286,9 +5296,7 @@ Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
52865296
if (subpFlag == Symbol::Flag::Function) {
52875297
auto &funcResultTop{funcResultStack().Push(currScope(), name.source)};
52885298
funcResultTop.previousImplicitType = previousImplicitType;
5289-
;
52905299
funcResultTop.previousName = previousName;
5291-
;
52925300
}
52935301
if (inInterfaceBlock()) {
52945302
auto &details{symbol->get<SubprogramDetails>()};
@@ -5314,7 +5322,7 @@ Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
53145322
found && found->has<HostAssocDetails>()) {
53155323
found->set(subpFlag); // PushScope() created symbol
53165324
}
5317-
return *symbol;
5325+
return symbol;
53185326
}
53195327

53205328
void SubprogramVisitor::PushBlockDataScope(const parser::Name &name) {

flang/test/Semantics/bug159554.f90

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
!RUN: %python %S/test_errors.py %s %flang_fc1
2+
use, intrinsic :: iso_c_binding
3+
interface c_funloc
4+
!ERROR: 'c_funloc' is already declared in this scoping unit
5+
function c_funloc()
6+
end function
7+
end interface
8+
end

0 commit comments

Comments
 (0)