diff --git a/flang/include/flang/Semantics/scope.h b/flang/include/flang/Semantics/scope.h --- a/flang/include/flang/Semantics/scope.h +++ b/flang/include/flang/Semantics/scope.h @@ -87,6 +87,7 @@ bool IsModule() const; // only module, not submodule bool IsSubmodule() const; bool IsDerivedType() const { return kind_ == Kind::DerivedType; } + bool IsStmtFunction() const; bool IsParameterizedDerivedType() const; Symbol *symbol() { return symbol_; } const Symbol *symbol() const { return symbol_; } diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -482,6 +482,7 @@ Error, // an error has been reported on this symbol Function, // symbol is a function Subroutine, // symbol is a subroutine + StmtFunction, // symbol is a statement function (Function is set too) Implicit, // symbol is implicitly typed ModFile, // symbol came from .mod file ParentComp, // symbol is the "parent component" of an extended type diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -2015,7 +2015,8 @@ Scope &ScopeHandler::InclusiveScope() { for (auto *scope{&currScope()};; scope = &scope->parent()) { - if (scope->kind() != Scope::Kind::Block && !scope->IsDerivedType()) { + if (scope->kind() != Scope::Kind::Block && !scope->IsDerivedType() && + !scope->IsStmtFunction()) { return *scope; } } @@ -2692,6 +2693,7 @@ return true; } auto &symbol{PushSubprogramScope(name, Symbol::Flag::Function)}; + symbol.set(Symbol::Flag::StmtFunction); EraseSymbol(symbol); // removes symbol added by PushSubprogramScope auto &details{symbol.get()}; for (const auto &dummyName : std::get>(x.t)) { diff --git a/flang/lib/Semantics/scope.cpp b/flang/lib/Semantics/scope.cpp --- a/flang/lib/Semantics/scope.cpp +++ b/flang/lib/Semantics/scope.cpp @@ -333,6 +333,10 @@ return os; } +bool Scope::IsStmtFunction() const { + return symbol_ && symbol_->test(Symbol::Flag::StmtFunction); +} + bool Scope::IsParameterizedDerivedType() const { if (!IsDerivedType()) { return false; diff --git a/flang/test/Semantics/symbol16.f90 b/flang/test/Semantics/symbol16.f90 --- a/flang/test/Semantics/symbol16.f90 +++ b/flang/test/Semantics/symbol16.f90 @@ -3,7 +3,7 @@ !DEF: /p1 MainProgram program p1 - !DEF: /p1/f (Function) Subprogram INTEGER(4) + !DEF: /p1/f (Function, StmtFunction) Subprogram INTEGER(4) !DEF: /p1/i ObjectEntity INTEGER(4) !DEF: /p1/j ObjectEntity INTEGER(4) integer f, i, j @@ -15,3 +15,13 @@ !REF: /p1/f j = f(2) end program + +!DEF: /p2 MainProgram +program p2 + !DEF: /p2/f (Function, StmtFunction) Subprogram REAL(4) + !DEF: /p2/f/x (Implicit) ObjectEntity REAL(4) + !DEF: /p2/y (Implicit) ObjectEntity REAL(4) + f(x) = y + !REF: /p2/y + y = 1.0 +end program