-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang] Fix crash in error recovery (implicit host association) #92795
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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 llvm#92647.
@llvm/pr-subscribers-flang-semantics Author: Peter Klausler (klausler) ChangesWhen 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. Full diff: https://github.com/llvm/llvm-project/pull/92795.diff 3 Files Affected:
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
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All builds and tests correctly and looks good.
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.