[flang-commits] [flang] 19b41f4 - [flang] Complete RESULT() name constraint checking (#91476)
via flang-commits
flang-commits at lists.llvm.org
Thu May 9 11:31:16 PDT 2024
Author: Peter Klausler
Date: 2024-05-09T11:31:13-07:00
New Revision: 19b41f40a4b93a6243c816b80b6e664a4418f79f
URL: https://github.com/llvm/llvm-project/commit/19b41f40a4b93a6243c816b80b6e664a4418f79f
DIFF: https://github.com/llvm/llvm-project/commit/19b41f40a4b93a6243c816b80b6e664a4418f79f.diff
LOG: [flang] Complete RESULT() name constraint checking (#91476)
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.
Added:
Modified:
flang/lib/Semantics/check-declarations.cpp
flang/lib/Semantics/resolve-names.cpp
flang/test/Semantics/entry01.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 9ef34f0f81c0..26efa288b5ae 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -1361,7 +1361,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};
@@ -1393,6 +1393,27 @@ void CheckHelper::CheckSubprogram(
}
}
}
+ 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 * resNameEntryScope{resNameSubp->entryScope()}) {
+ const Scope *myScope{
+ details.entryScope() ? details.entryScope() : symbol.scope()};
+ if (resNameEntryScope == myScope) {
+ if (auto *msg{messages_.Say(symbol.name(),
+ "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);
+ }
+ }
+ }
+ }
+ }
+ }
if (const MaybeExpr & stmtFunction{details.stmtFunction()}) {
if (auto msg{evaluate::CheckStatementFunction(
symbol, *stmtFunction, context_.foldingContext())}) {
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 4df347a878de..e2875081b732 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 64bd954f8ae0..970cd109921a 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()
@@ -255,3 +256,13 @@ 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('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: 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