-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang] Complete RESULT() name constraint checking #91476
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
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
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.
@llvm/pr-subscribers-flang-semantics Author: Peter Klausler (klausler) ChangesFull diff: https://github.com/llvm/llvm-project/pull/91476.diff 3 Files Affected:
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index c1d9538e557f5..1d98338aab097 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,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 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 64bd954f8ae0f..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()
@@ -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
|
psteinfeld
approved these changes
May 8, 2024
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.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.