Skip to content

Commit c9f94ba

Browse files
authored
[flang] Fix crash in error recovery (implicit host association) (#92795)
When a symbol appears in a specification expression in a subprogram contained in a host program unit, semantics may have to create a symbol in the host and use host association to it. This shouldn't happen for nested subprograms that can't import such a symbol, such as interface blocks by default. Further, when host association fails, semantics shouldn't crash. Fixes #92647.
1 parent 70d1844 commit c9f94ba

File tree

3 files changed

+39
-22
lines changed

3 files changed

+39
-22
lines changed

flang/include/flang/Semantics/scope.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ class Scope {
225225
ImportKind GetImportKind() const;
226226
// Names appearing in IMPORT statements in this scope
227227
std::set<SourceName> importNames() const { return importNames_; }
228+
bool CanImport(const SourceName &) const;
228229

229230
// Set the kind of imports from host into this scope.
230231
// Return an error message for incompatible kinds.
@@ -298,7 +299,6 @@ class Scope {
298299
// or Symbol& points to one in there.
299300
static Symbols<1024> allSymbols;
300301

301-
bool CanImport(const SourceName &) const;
302302
const DeclTypeSpec &MakeLengthlessType(DeclTypeSpec &&);
303303

304304
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Scope &);

flang/lib/Semantics/resolve-names.cpp

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7846,28 +7846,31 @@ bool DeclarationVisitor::CheckForHostAssociatedImplicit(
78467846
if (name.symbol) {
78477847
ApplyImplicitRules(*name.symbol, true);
78487848
}
7849-
Symbol *hostSymbol;
7850-
Scope *host{GetHostProcedure()};
7851-
if (!host || isImplicitNoneType(*host)) {
7852-
return false;
7853-
}
7854-
if (!name.symbol) {
7855-
hostSymbol = &MakeSymbol(*host, name.source, Attrs{});
7856-
ConvertToObjectEntity(*hostSymbol);
7857-
ApplyImplicitRules(*hostSymbol);
7858-
hostSymbol->set(Symbol::Flag::ImplicitOrError);
7859-
} else if (name.symbol->test(Symbol::Flag::ImplicitOrError)) {
7860-
hostSymbol = name.symbol;
7861-
} else {
7862-
return false;
7863-
}
7864-
Symbol &symbol{MakeHostAssocSymbol(name, *hostSymbol)};
7865-
if (isImplicitNoneType()) {
7866-
symbol.get<HostAssocDetails>().implicitOrExplicitTypeError = true;
7867-
} else {
7868-
symbol.get<HostAssocDetails>().implicitOrSpecExprError = true;
7849+
if (Scope * host{GetHostProcedure()}; host && !isImplicitNoneType(*host)) {
7850+
Symbol *hostSymbol{nullptr};
7851+
if (!name.symbol) {
7852+
if (currScope().CanImport(name.source)) {
7853+
hostSymbol = &MakeSymbol(*host, name.source, Attrs{});
7854+
ConvertToObjectEntity(*hostSymbol);
7855+
ApplyImplicitRules(*hostSymbol);
7856+
hostSymbol->set(Symbol::Flag::ImplicitOrError);
7857+
}
7858+
} else if (name.symbol->test(Symbol::Flag::ImplicitOrError)) {
7859+
hostSymbol = name.symbol;
7860+
}
7861+
if (hostSymbol) {
7862+
Symbol &symbol{MakeHostAssocSymbol(name, *hostSymbol)};
7863+
if (auto *assoc{symbol.detailsIf<HostAssocDetails>()}) {
7864+
if (isImplicitNoneType()) {
7865+
assoc->implicitOrExplicitTypeError = true;
7866+
} else {
7867+
assoc->implicitOrSpecExprError = true;
7868+
}
7869+
return true;
7870+
}
7871+
}
78697872
}
7870-
return true;
7873+
return false;
78717874
}
78727875

78737876
bool DeclarationVisitor::IsUplevelReference(const Symbol &symbol) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
! RUN: %python %S/test_errors.py %s %flang_fc1
2+
interface a1
3+
subroutine s1
4+
interface a2
5+
subroutine s2
6+
!ERROR: Invalid specification expression: reference to local entity 'k'
7+
real x(k)
8+
end subroutine
9+
end interface
10+
!ERROR: Invalid specification expression: reference to local entity 'k'
11+
real y(k)
12+
end subroutine
13+
end interface
14+
end

0 commit comments

Comments
 (0)