[flang-commits] [flang] Pf0 (PR #91476)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Wed May 8 07:16:14 PDT 2024
https://github.com/klausler created https://github.com/llvm/llvm-project/pull/91476
None
>From 130a78bde00a01d703a26a77cfebcf00c0cf4b36 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Tue, 7 May 2024 15:14:23 -0700
Subject: [PATCH 1/2] [flang] Enforce result name / ENTRY name constraints
The name of an explicit RESULT() of a function must not be the
name of any ENTRY into that function, even when that ENTRY itself
has a distinct explicit RESULT() name. Further, the name of any
ENTRY's explicit RESULT() must not match the name of the enclosing
function or any other ENTRY into it.
---
flang/lib/Semantics/check-declarations.cpp | 21 ++++++++++++++++++++-
flang/test/Semantics/entry01.f90 | 8 ++++++++
2 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index c1d9538e557f5..7e1cdcd037423 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -1352,7 +1352,7 @@ void CheckHelper::CheckSubprogram(
SubprogramMatchHelper{*this}.Check(symbol, *iface);
}
if (const Scope *entryScope{details.entryScope()}) {
- // ENTRY 15.6.2.6, esp. C1571
+ // ENTRY F'2023 15.6.2.6
std::optional<parser::MessageFixedText> error;
const Symbol *subprogram{entryScope->symbol()};
const SubprogramDetails *subprogramDetails{nullptr};
@@ -1384,6 +1384,25 @@ void CheckHelper::CheckSubprogram(
}
}
}
+ if (details.isFunction() && details.result().name() != symbol.name() &&
+ symbol.scope()) { // F'2023 C1569 & C1583
+ if (auto iter{symbol.owner().find(details.result().name())};
+ iter != symbol.owner().end()) {
+ const Symbol &resNameSym{*iter->second};
+ if (const auto *resNameSubp{resNameSym.detailsIf<SubprogramDetails>()}) {
+ if (const Scope * resNameScope{resNameSubp->entryScope()}) {
+ if (resNameScope == symbol.scope()) {
+ if (auto *msg{messages_.Say(symbol.name(),
+ "Explicit result variable '%s' of function '%s' cannot have the same name as an ENTRY into the same scope"_err_en_US,
+ details.result().name(), symbol.name())}) {
+ msg->Attach(
+ resNameSym.name(), "ENTRY with conflicting name"_en_US);
+ }
+ }
+ }
+ }
+ }
+ }
if (const MaybeExpr & stmtFunction{details.stmtFunction()}) {
if (auto msg{evaluate::CheckStatementFunction(
symbol, *stmtFunction, context_.foldingContext())}) {
diff --git a/flang/test/Semantics/entry01.f90 b/flang/test/Semantics/entry01.f90
index 64bd954f8ae0f..0a8f03aedb9b5 100644
--- a/flang/test/Semantics/entry01.f90
+++ b/flang/test/Semantics/entry01.f90
@@ -255,3 +255,11 @@ subroutine s7(q,q)
!ERROR: 'z' appears more than once as a dummy argument name in this ENTRY statement
entry baz(z,z)
end
+
+!ERROR: Explicit result variable 'f8e1' of function 'f8' cannot have the same name as an ENTRY into the same scope
+function f8() result(f8e1)
+ entry f8e1()
+ entry f8e2() result(f8e2) ! ok
+ !ERROR: RESULT(f8e1) may not have the same name as an ENTRY in the function
+ entry f8e3() result(f8e1)
+end
>From 0714b0fb416810eb418e998d0c2e625878c6ad05 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Wed, 8 May 2024 07:09:21 -0700
Subject: [PATCH 2/2] [flang] Complete RESULT() name constraint checking
There are two constraints in the language that prohibit the
use of an ENTRY name being used as the RESULT() variable of the
function or another ENTRY name in the same function's scope;
neither can the name of the function be used as the RESULT() of
an ENTRY.
Move most of the existing partial enforcement of these constraints
from name resolution into declaration checking, complete it,
and add more cases to the tests.
---
flang/lib/Semantics/check-declarations.cpp | 12 +++---
flang/lib/Semantics/resolve-names.cpp | 49 +++++++++-------------
flang/test/Semantics/entry01.f90 | 11 +++--
3 files changed, 33 insertions(+), 39 deletions(-)
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 7e1cdcd037423..1d98338aab097 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -1384,16 +1384,18 @@ void CheckHelper::CheckSubprogram(
}
}
}
- if (details.isFunction() && details.result().name() != symbol.name() &&
- symbol.scope()) { // F'2023 C1569 & C1583
+ if (details.isFunction() &&
+ details.result().name() != symbol.name()) { // F'2023 C1569 & C1583
if (auto iter{symbol.owner().find(details.result().name())};
iter != symbol.owner().end()) {
const Symbol &resNameSym{*iter->second};
if (const auto *resNameSubp{resNameSym.detailsIf<SubprogramDetails>()}) {
- if (const Scope * resNameScope{resNameSubp->entryScope()}) {
- if (resNameScope == symbol.scope()) {
+ if (const Scope * resNameEntryScope{resNameSubp->entryScope()}) {
+ const Scope *myScope{
+ details.entryScope() ? details.entryScope() : symbol.scope()};
+ if (resNameEntryScope == myScope) {
if (auto *msg{messages_.Say(symbol.name(),
- "Explicit result variable '%s' of function '%s' cannot have the same name as an ENTRY into the same scope"_err_en_US,
+ "Explicit RESULT('%s') of function '%s' cannot have the same name as a distinct ENTRY into the same scope"_err_en_US,
details.result().name(), symbol.name())}) {
msg->Attach(
resNameSym.name(), "ENTRY with conflicting name"_en_US);
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 61394b0f41de7..dd24406f28fdd 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -4048,27 +4048,10 @@ void SubprogramVisitor::CreateEntry(
attrs = extant->attrs();
}
}
- bool badResultName{false};
std::optional<SourceName> distinctResultName;
if (suffix && suffix->resultName &&
suffix->resultName->source != entryName.source) {
distinctResultName = suffix->resultName->source;
- const parser::Name &resultName{*suffix->resultName};
- if (resultName.source == subprogram.name()) { // C1574
- Say2(resultName.source,
- "RESULT(%s) may not have the same name as the function"_err_en_US,
- subprogram, "Containing function"_en_US);
- badResultName = true;
- } else if (const Symbol * extant{FindSymbol(outer, resultName)}) { // C1574
- if (const auto *details{extant->detailsIf<SubprogramDetails>()}) {
- if (details->entryScope() == &currScope()) {
- Say2(resultName.source,
- "RESULT(%s) may not have the same name as an ENTRY in the function"_err_en_US,
- extant->name(), "Conflicting ENTRY"_en_US);
- badResultName = true;
- }
- }
- }
}
if (outer.IsModule() && !attrs.test(Attr::PRIVATE)) {
attrs.set(Attr::PUBLIC);
@@ -4104,17 +4087,24 @@ void SubprogramVisitor::CreateEntry(
EntityDetails resultDetails;
resultDetails.set_funcResult(true);
if (distinctResultName) {
- if (!badResultName) {
- // RESULT(x) can be the same explicitly-named RESULT(x) as
- // the enclosing function or another ENTRY.
- if (auto iter{currScope().find(suffix->resultName->source)};
- iter != currScope().end()) {
- result = &*iter->second;
- }
- if (!result) {
- result = &MakeSymbol(
- *distinctResultName, Attrs{}, std::move(resultDetails));
- }
+ // An explicit RESULT() can also be an explicit RESULT()
+ // of the function or another ENTRY.
+ if (auto iter{currScope().find(suffix->resultName->source)};
+ iter != currScope().end()) {
+ result = &*iter->second;
+ }
+ if (!result) {
+ result =
+ &MakeSymbol(*distinctResultName, Attrs{}, std::move(resultDetails));
+ } else if (!result->has<EntityDetails>()) {
+ Say(*distinctResultName,
+ "ENTRY cannot have RESULT(%s) that is not a variable"_err_en_US,
+ *distinctResultName)
+ .Attach(result->name(), "Existing declaration of '%s'"_en_US,
+ result->name());
+ result = nullptr;
+ }
+ if (result) {
Resolve(*suffix->resultName, *result);
}
} else {
@@ -4124,8 +4114,7 @@ void SubprogramVisitor::CreateEntry(
entryDetails.set_result(*result);
}
}
- if (subpFlag == Symbol::Flag::Subroutine ||
- (distinctResultName && !badResultName)) {
+ if (subpFlag == Symbol::Flag::Subroutine || distinctResultName) {
Symbol &assoc{MakeSymbol(entryName.source)};
assoc.set_details(HostAssocDetails{*entrySymbol});
assoc.set(Symbol::Flag::Subroutine);
diff --git a/flang/test/Semantics/entry01.f90 b/flang/test/Semantics/entry01.f90
index 0a8f03aedb9b5..970cd109921a1 100644
--- a/flang/test/Semantics/entry01.f90
+++ b/flang/test/Semantics/entry01.f90
@@ -86,11 +86,12 @@ function ifunc()
entry ibad2()
!ERROR: ENTRY in a function may not have an alternate return dummy argument
entry ibadalt(*) ! C1573
- !ERROR: RESULT(ifunc) may not have the same name as the function
+ !ERROR: ENTRY cannot have RESULT(ifunc) that is not a variable
entry isameres() result(ifunc) ! C1574
entry iok()
- !ERROR: RESULT(iok) may not have the same name as an ENTRY in the function
+ !ERROR: Explicit RESULT('iok') of function 'isameres2' cannot have the same name as a distinct ENTRY into the same scope
entry isameres2() result(iok) ! C1574
+ !ERROR: Explicit RESULT('iok2') of function 'isameres3' cannot have the same name as a distinct ENTRY into the same scope
entry isameres3() result(iok2) ! C1574
!ERROR: 'iok2' is already declared in this scoping unit
entry iok2()
@@ -256,10 +257,12 @@ subroutine s7(q,q)
entry baz(z,z)
end
-!ERROR: Explicit result variable 'f8e1' of function 'f8' cannot have the same name as an ENTRY into the same scope
+!ERROR: Explicit RESULT('f8e1') of function 'f8' cannot have the same name as a distinct ENTRY into the same scope
function f8() result(f8e1)
entry f8e1()
entry f8e2() result(f8e2) ! ok
- !ERROR: RESULT(f8e1) may not have the same name as an ENTRY in the function
+ !ERROR: Explicit RESULT('f8e1') of function 'f8e3' cannot have the same name as a distinct ENTRY into the same scope
entry f8e3() result(f8e1)
+ !ERROR: ENTRY cannot have RESULT(f8) that is not a variable
+ entry f8e4() result(f8)
end
More information about the flang-commits
mailing list