Skip to content

Commit

Permalink
[flang] Detect more misparsed statement functions (same name as funct… (
Browse files Browse the repository at this point in the history
#73852)

…ion result)

A function can't return a statement function, so an apparent attempt to
define a statement function with the same name as the function's result
must be a misparsed assignment statement.
  • Loading branch information
klausler committed Nov 30, 2023
1 parent d3e5c20 commit a4745ff
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
3 changes: 3 additions & 0 deletions flang/lib/Semantics/check-declarations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,9 @@ void CheckHelper::CheckSubprogram(
if (auto msg{evaluate::CheckStatementFunction(
symbol, *stmtFunction, context_.foldingContext())}) {
SayWithDeclaration(symbol, std::move(*msg));
} else if (IsPointer(symbol)) {
SayWithDeclaration(symbol,
"A statement function must not have the POINTER attribute"_err_en_US);
} else if (details.result().flags().test(Symbol::Flag::Implicit)) {
// 15.6.4 p2 weird requirement
if (const Symbol *
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3531,7 +3531,8 @@ bool SubprogramVisitor::HandleStmtFunction(const parser::StmtFunctionStmt &x) {
Symbol &ultimate{symbol->GetUltimate()};
if (ultimate.has<ObjectEntityDetails>() ||
ultimate.has<AssocEntityDetails>() ||
CouldBeDataPointerValuedFunction(&ultimate)) {
CouldBeDataPointerValuedFunction(&ultimate) ||
(&symbol->owner() == &currScope() && IsFunctionResult(*symbol))) {
misparsedStmtFuncFound_ = true;
return false;
}
Expand Down
30 changes: 30 additions & 0 deletions flang/test/Semantics/stmt-func01.f90
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,33 @@ subroutine foo
sf13(x) = 2.*x
end subroutine
end

subroutine s0
allocatable :: sf
!ERROR: 'sf' is not a callable procedure
sf(x) = 1.
end

subroutine s1
asynchronous :: sf
!ERROR: An entity may not have the ASYNCHRONOUS attribute unless it is a variable
sf(x) = 1.
end

subroutine s2
pointer :: sf
!ERROR: A statement function must not have the POINTER attribute
sf(x) = 1.
end

subroutine s3
save :: sf
!ERROR: The entity 'sf' with an explicit SAVE attribute must be a variable, procedure pointer, or COMMON block
sf(x) = 1.
end

subroutine s4
volatile :: sf
!ERROR: VOLATILE attribute may apply only to a variable
sf(x) = 1.
end
19 changes: 19 additions & 0 deletions flang/test/Semantics/stmt-func02.f90
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,23 @@ subroutine test3
!ERROR: 'sf' has not been declared as an array or pointer-valued function
sf(x) = 4.
end
function f()
!ERROR: Recursive call to 'f' requires a distinct RESULT in its declaration
!ERROR: Left-hand side of assignment is not definable
!BECAUSE: 'f()' is not a variable or pointer
f() = 1. ! statement function of same name as function
end
function g() result(r)
!WARNING: Name 'g' from host scope should have a type declaration before its local statement function definition
!ERROR: 'g' is already declared in this scoping unit
g() = 1. ! statement function of same name as function
end
function h1() result(r)
!ERROR: 'r' is not a callable procedure
r() = 1. ! statement function of same name as function result
end
function h2() result(r)
procedure(real), pointer :: r
r() = 1. ! not a statement function
end
end

0 comments on commit a4745ff

Please sign in to comment.