Skip to content

Commit e6da918

Browse files
authored
[flang] Fix crash from undetected program error. (#159847)
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 977e75c commit e6da918

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 &);
@@ -4492,10 +4492,13 @@ bool SubprogramVisitor::HandleStmtFunction(const parser::StmtFunctionStmt &x) {
44924492
"'%s' has not been declared as an array or pointer-valued function"_err_en_US);
44934493
return false;
44944494
}
4495-
auto &symbol{PushSubprogramScope(name, Symbol::Flag::Function)};
4496-
symbol.set(Symbol::Flag::StmtFunction);
4497-
EraseSymbol(symbol); // removes symbol added by PushSubprogramScope
4498-
auto &details{symbol.get<SubprogramDetails>()};
4495+
Symbol *symbol{PushSubprogramScope(name, Symbol::Flag::Function)};
4496+
if (!symbol) {
4497+
return false;
4498+
}
4499+
symbol->set(Symbol::Flag::StmtFunction);
4500+
EraseSymbol(*symbol); // removes symbol added by PushSubprogramScope
4501+
auto &details{symbol->get<SubprogramDetails>()};
44994502
for (const auto &dummyName : std::get<std::list<parser::Name>>(x.t)) {
45004503
ObjectEntityDetails dummyDetails{true};
45014504
if (auto *dummySymbol{FindInScope(currScope().parent(), dummyName)}) {
@@ -5124,19 +5127,22 @@ bool SubprogramVisitor::BeginSubprogram(const parser::Name &name,
51245127
}
51255128
}
51265129
}
5127-
Symbol &newSymbol{
5130+
Symbol *newSymbol{
51285131
PushSubprogramScope(name, subpFlag, bindingSpec, hasModulePrefix)};
5132+
if (!newSymbol) {
5133+
return false;
5134+
}
51295135
if (moduleInterface) {
5130-
newSymbol.get<SubprogramDetails>().set_moduleInterface(*moduleInterface);
5136+
newSymbol->get<SubprogramDetails>().set_moduleInterface(*moduleInterface);
51315137
if (moduleInterface->attrs().test(Attr::PRIVATE)) {
5132-
SetImplicitAttr(newSymbol, Attr::PRIVATE);
5138+
SetImplicitAttr(*newSymbol, Attr::PRIVATE);
51335139
} else if (moduleInterface->attrs().test(Attr::PUBLIC)) {
5134-
SetImplicitAttr(newSymbol, Attr::PUBLIC);
5140+
SetImplicitAttr(*newSymbol, Attr::PUBLIC);
51355141
}
51365142
}
51375143
if (entryStmts) {
51385144
for (const auto &ref : *entryStmts) {
5139-
CreateEntry(*ref, newSymbol);
5145+
CreateEntry(*ref, *newSymbol);
51405146
}
51415147
}
51425148
return true;
@@ -5243,12 +5249,16 @@ const Symbol *SubprogramVisitor::CheckExtantProc(
52435249
return prev;
52445250
}
52455251

5246-
Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
5252+
Symbol *SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
52475253
Symbol::Flag subpFlag, const parser::LanguageBindingSpec *bindingSpec,
52485254
bool hasModulePrefix) {
52495255
Symbol *symbol{GetSpecificFromGeneric(name)};
52505256
const DeclTypeSpec *previousImplicitType{nullptr};
52515257
SourceName previousName;
5258+
if (symbol && inInterfaceBlock() && !symbol->has<SubprogramDetails>()) {
5259+
SayAlreadyDeclared(name, *symbol);
5260+
return nullptr;
5261+
}
52525262
if (!symbol) {
52535263
if (bindingSpec && currScope().IsGlobal() &&
52545264
std::get<std::optional<parser::ScalarDefaultCharConstantExpr>>(
@@ -5277,9 +5287,7 @@ Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
52775287
if (subpFlag == Symbol::Flag::Function) {
52785288
auto &funcResultTop{funcResultStack().Push(currScope(), name.source)};
52795289
funcResultTop.previousImplicitType = previousImplicitType;
5280-
;
52815290
funcResultTop.previousName = previousName;
5282-
;
52835291
}
52845292
if (inInterfaceBlock()) {
52855293
auto &details{symbol->get<SubprogramDetails>()};
@@ -5305,7 +5313,7 @@ Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
53055313
found && found->has<HostAssocDetails>()) {
53065314
found->set(subpFlag); // PushScope() created symbol
53075315
}
5308-
return *symbol;
5316+
return symbol;
53095317
}
53105318

53115319
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)