[flang-commits] [flang] [flang] Fix crash in error recovery (implicit host association) (PR #92795)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Mon May 20 10:52:10 PDT 2024
https://github.com/klausler created https://github.com/llvm/llvm-project/pull/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 https://github.com/llvm/llvm-project/issues/92647.
>From 44acb0735f340f682910903a822df84d8cc63cef Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Mon, 20 May 2024 10:48:04 -0700
Subject: [PATCH] [flang] Fix crash in error recovery (implicit host
association)
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 https://github.com/llvm/llvm-project/issues/92647.
---
flang/include/flang/Semantics/scope.h | 2 +-
flang/lib/Semantics/resolve-names.cpp | 45 +++++++++++++-----------
flang/test/Semantics/procinterface05.f90 | 14 ++++++++
3 files changed, 39 insertions(+), 22 deletions(-)
create mode 100644 flang/test/Semantics/procinterface05.f90
diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h
index 21072772d184b..a58163f5460c2 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -225,6 +225,7 @@ class Scope {
ImportKind GetImportKind() const;
// Names appearing in IMPORT statements in this scope
std::set<SourceName> importNames() const { return importNames_; }
+ bool CanImport(const SourceName &) const;
// Set the kind of imports from host into this scope.
// Return an error message for incompatible kinds.
@@ -298,7 +299,6 @@ class Scope {
// or Symbol& points to one in there.
static Symbols<1024> allSymbols;
- bool CanImport(const SourceName &) const;
const DeclTypeSpec &MakeLengthlessType(DeclTypeSpec &&);
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Scope &);
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index a46c0f378d5d0..612b181a5c13d 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -7846,28 +7846,31 @@ bool DeclarationVisitor::CheckForHostAssociatedImplicit(
if (name.symbol) {
ApplyImplicitRules(*name.symbol, true);
}
- Symbol *hostSymbol;
- Scope *host{GetHostProcedure()};
- if (!host || isImplicitNoneType(*host)) {
- return false;
- }
- if (!name.symbol) {
- hostSymbol = &MakeSymbol(*host, name.source, Attrs{});
- ConvertToObjectEntity(*hostSymbol);
- ApplyImplicitRules(*hostSymbol);
- hostSymbol->set(Symbol::Flag::ImplicitOrError);
- } else if (name.symbol->test(Symbol::Flag::ImplicitOrError)) {
- hostSymbol = name.symbol;
- } else {
- return false;
- }
- Symbol &symbol{MakeHostAssocSymbol(name, *hostSymbol)};
- if (isImplicitNoneType()) {
- symbol.get<HostAssocDetails>().implicitOrExplicitTypeError = true;
- } else {
- symbol.get<HostAssocDetails>().implicitOrSpecExprError = true;
+ if (Scope * host{GetHostProcedure()}; host && !isImplicitNoneType(*host)) {
+ Symbol *hostSymbol{nullptr};
+ if (!name.symbol) {
+ if (currScope().CanImport(name.source)) {
+ hostSymbol = &MakeSymbol(*host, name.source, Attrs{});
+ ConvertToObjectEntity(*hostSymbol);
+ ApplyImplicitRules(*hostSymbol);
+ hostSymbol->set(Symbol::Flag::ImplicitOrError);
+ }
+ } else if (name.symbol->test(Symbol::Flag::ImplicitOrError)) {
+ hostSymbol = name.symbol;
+ }
+ if (hostSymbol) {
+ Symbol &symbol{MakeHostAssocSymbol(name, *hostSymbol)};
+ if (auto *assoc{symbol.detailsIf<HostAssocDetails>()}) {
+ if (isImplicitNoneType()) {
+ assoc->implicitOrExplicitTypeError = true;
+ } else {
+ assoc->implicitOrSpecExprError = true;
+ }
+ return true;
+ }
+ }
}
- return true;
+ return false;
}
bool DeclarationVisitor::IsUplevelReference(const Symbol &symbol) {
diff --git a/flang/test/Semantics/procinterface05.f90 b/flang/test/Semantics/procinterface05.f90
new file mode 100644
index 0000000000000..8c3afbffb2cf3
--- /dev/null
+++ b/flang/test/Semantics/procinterface05.f90
@@ -0,0 +1,14 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+interface a1
+ subroutine s1
+ interface a2
+ subroutine s2
+ !ERROR: Invalid specification expression: reference to local entity 'k'
+ real x(k)
+ end subroutine
+ end interface
+ !ERROR: Invalid specification expression: reference to local entity 'k'
+ real y(k)
+ end subroutine
+end interface
+end
More information about the flang-commits
mailing list