Skip to content

Commit a7afc8a

Browse files
committed
[flang] Fix CHECK() calls on erroneous procedure declarations
When writing tests for a previous problem, I ran across situations where the compiler was failing calls to CHECK(). In these situations, the compiler had inconsistent semantic information because the programs were erroneous. This inconsistent information was causing the calls to CHECK(). I fixed this by avoiding the code that ended up making the failed calls to CHECK() and making sure that we were only avoiding these situations when the associated symbols were erroneous. I also added tests that would cause the calls to CHECK() without these changes. Differential Revision: https://reviews.llvm.org/D99342
1 parent 54bacaf commit a7afc8a

File tree

2 files changed

+84
-11
lines changed

2 files changed

+84
-11
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,9 @@ class InterfaceVisitor : public virtual ScopeHandler {
681681
bool isAbstract() const;
682682

683683
protected:
684-
GenericDetails &GetGenericDetails();
684+
Symbol &GetGenericSymbol() {
685+
return DEREF(genericInfo_.top().symbol);
686+
}
685687
// Add to generic the symbol for the subprogram with the same name
686688
void CheckGenericProcedures(Symbol &);
687689

@@ -2681,9 +2683,6 @@ bool InterfaceVisitor::isGeneric() const {
26812683
bool InterfaceVisitor::isAbstract() const {
26822684
return !genericInfo_.empty() && GetGenericInfo().isAbstract;
26832685
}
2684-
GenericDetails &InterfaceVisitor::GetGenericDetails() {
2685-
return GetGenericInfo().symbol->get<GenericDetails>();
2686-
}
26872686

26882687
void InterfaceVisitor::AddSpecificProcs(
26892688
const std::list<parser::Name> &names, ProcedureKind kind) {
@@ -2885,7 +2884,9 @@ void SubprogramVisitor::Post(const parser::ImplicitPart &) {
28852884
if (funcInfo_.parsedType) {
28862885
messageHandler().set_currStmtSource(funcInfo_.source);
28872886
if (const auto *type{ProcessTypeSpec(*funcInfo_.parsedType, true)}) {
2888-
funcInfo_.resultSymbol->SetType(*type);
2887+
if (!context().HasError(funcInfo_.resultSymbol)) {
2888+
funcInfo_.resultSymbol->SetType(*type);
2889+
}
28892890
}
28902891
}
28912892
funcInfo_ = {};
@@ -2945,11 +2946,16 @@ void SubprogramVisitor::Post(const parser::FunctionStmt &stmt) {
29452946
funcResultName = &name;
29462947
}
29472948
// add function result to function scope
2948-
EntityDetails funcResultDetails;
2949-
funcResultDetails.set_funcResult(true);
2950-
funcInfo_.resultSymbol =
2951-
&MakeSymbol(*funcResultName, std::move(funcResultDetails));
2952-
details.set_result(*funcInfo_.resultSymbol);
2949+
if (details.isFunction()) {
2950+
CHECK(context().HasError(currScope().symbol()));
2951+
} else {
2952+
// add function result to function scope
2953+
EntityDetails funcResultDetails;
2954+
funcResultDetails.set_funcResult(true);
2955+
funcInfo_.resultSymbol =
2956+
&MakeSymbol(*funcResultName, std::move(funcResultDetails));
2957+
details.set_result(*funcInfo_.resultSymbol);
2958+
}
29532959

29542960
// C1560.
29552961
if (funcInfo_.resultName && funcInfo_.resultName->source == name.source) {
@@ -3223,7 +3229,13 @@ Symbol &SubprogramVisitor::PushSubprogramScope(
32233229
MakeExternal(*symbol);
32243230
}
32253231
if (isGeneric()) {
3226-
GetGenericDetails().AddSpecificProc(*symbol, name.source);
3232+
Symbol &genericSymbol{GetGenericSymbol()};
3233+
if (genericSymbol.has<GenericDetails>()) {
3234+
genericSymbol.get<GenericDetails>().AddSpecificProc(
3235+
*symbol, name.source);
3236+
} else {
3237+
CHECK(context().HasError(genericSymbol));
3238+
}
32273239
}
32283240
set_inheritFromParent(false);
32293241
}

flang/test/Semantics/resolve18.f90

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,64 @@ subroutine f8()
121121
end subroutine f8
122122
end interface g8
123123
end module m8
124+
125+
module m9
126+
type f9
127+
end type f9
128+
!ERROR: 'f9' is already declared in this scoping unit
129+
interface f9
130+
real function f9()
131+
end function f9
132+
end interface f9
133+
contains
134+
function f9(x)
135+
end function f9
136+
end module m9
137+
138+
module m10
139+
type :: t10
140+
end type t10
141+
interface f10
142+
function f10()
143+
end function f10
144+
end interface f10
145+
contains
146+
!ERROR: 'f10' is already declared in this scoping unit
147+
function f10(x)
148+
end function f10
149+
end module m10
150+
151+
module m11
152+
type :: t11
153+
end type t11
154+
interface i11
155+
function f11()
156+
end function f11
157+
end interface i11
158+
contains
159+
!ERROR: 'f11' is already declared in this scoping unit
160+
function f11(x)
161+
end function f11
162+
end module m11
163+
164+
module m12
165+
interface f12
166+
function f12()
167+
end function f12
168+
end interface f12
169+
contains
170+
!ERROR: 'f12' is already declared in this scoping unit
171+
function f12(x)
172+
end function f12
173+
end module m12
174+
175+
module m13
176+
interface f13
177+
function f13()
178+
end function f13
179+
end interface f13
180+
contains
181+
!ERROR: 'f13' is already declared in this scoping unit
182+
function f13()
183+
end function f13
184+
end module m13

0 commit comments

Comments
 (0)