Skip to content

Commit 19b41f4

Browse files
authored
[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.
1 parent b942c24 commit 19b41f4

File tree

3 files changed

+54
-33
lines changed

3 files changed

+54
-33
lines changed

flang/lib/Semantics/check-declarations.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1361,7 +1361,7 @@ void CheckHelper::CheckSubprogram(
13611361
SubprogramMatchHelper{*this}.Check(symbol, *iface);
13621362
}
13631363
if (const Scope *entryScope{details.entryScope()}) {
1364-
// ENTRY 15.6.2.6, esp. C1571
1364+
// ENTRY F'2023 15.6.2.6
13651365
std::optional<parser::MessageFixedText> error;
13661366
const Symbol *subprogram{entryScope->symbol()};
13671367
const SubprogramDetails *subprogramDetails{nullptr};
@@ -1393,6 +1393,27 @@ void CheckHelper::CheckSubprogram(
13931393
}
13941394
}
13951395
}
1396+
if (details.isFunction() &&
1397+
details.result().name() != symbol.name()) { // F'2023 C1569 & C1583
1398+
if (auto iter{symbol.owner().find(details.result().name())};
1399+
iter != symbol.owner().end()) {
1400+
const Symbol &resNameSym{*iter->second};
1401+
if (const auto *resNameSubp{resNameSym.detailsIf<SubprogramDetails>()}) {
1402+
if (const Scope * resNameEntryScope{resNameSubp->entryScope()}) {
1403+
const Scope *myScope{
1404+
details.entryScope() ? details.entryScope() : symbol.scope()};
1405+
if (resNameEntryScope == myScope) {
1406+
if (auto *msg{messages_.Say(symbol.name(),
1407+
"Explicit RESULT('%s') of function '%s' cannot have the same name as a distinct ENTRY into the same scope"_err_en_US,
1408+
details.result().name(), symbol.name())}) {
1409+
msg->Attach(
1410+
resNameSym.name(), "ENTRY with conflicting name"_en_US);
1411+
}
1412+
}
1413+
}
1414+
}
1415+
}
1416+
}
13961417
if (const MaybeExpr & stmtFunction{details.stmtFunction()}) {
13971418
if (auto msg{evaluate::CheckStatementFunction(
13981419
symbol, *stmtFunction, context_.foldingContext())}) {

flang/lib/Semantics/resolve-names.cpp

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4048,27 +4048,10 @@ void SubprogramVisitor::CreateEntry(
40484048
attrs = extant->attrs();
40494049
}
40504050
}
4051-
bool badResultName{false};
40524051
std::optional<SourceName> distinctResultName;
40534052
if (suffix && suffix->resultName &&
40544053
suffix->resultName->source != entryName.source) {
40554054
distinctResultName = suffix->resultName->source;
4056-
const parser::Name &resultName{*suffix->resultName};
4057-
if (resultName.source == subprogram.name()) { // C1574
4058-
Say2(resultName.source,
4059-
"RESULT(%s) may not have the same name as the function"_err_en_US,
4060-
subprogram, "Containing function"_en_US);
4061-
badResultName = true;
4062-
} else if (const Symbol * extant{FindSymbol(outer, resultName)}) { // C1574
4063-
if (const auto *details{extant->detailsIf<SubprogramDetails>()}) {
4064-
if (details->entryScope() == &currScope()) {
4065-
Say2(resultName.source,
4066-
"RESULT(%s) may not have the same name as an ENTRY in the function"_err_en_US,
4067-
extant->name(), "Conflicting ENTRY"_en_US);
4068-
badResultName = true;
4069-
}
4070-
}
4071-
}
40724055
}
40734056
if (outer.IsModule() && !attrs.test(Attr::PRIVATE)) {
40744057
attrs.set(Attr::PUBLIC);
@@ -4104,17 +4087,24 @@ void SubprogramVisitor::CreateEntry(
41044087
EntityDetails resultDetails;
41054088
resultDetails.set_funcResult(true);
41064089
if (distinctResultName) {
4107-
if (!badResultName) {
4108-
// RESULT(x) can be the same explicitly-named RESULT(x) as
4109-
// the enclosing function or another ENTRY.
4110-
if (auto iter{currScope().find(suffix->resultName->source)};
4111-
iter != currScope().end()) {
4112-
result = &*iter->second;
4113-
}
4114-
if (!result) {
4115-
result = &MakeSymbol(
4116-
*distinctResultName, Attrs{}, std::move(resultDetails));
4117-
}
4090+
// An explicit RESULT() can also be an explicit RESULT()
4091+
// of the function or another ENTRY.
4092+
if (auto iter{currScope().find(suffix->resultName->source)};
4093+
iter != currScope().end()) {
4094+
result = &*iter->second;
4095+
}
4096+
if (!result) {
4097+
result =
4098+
&MakeSymbol(*distinctResultName, Attrs{}, std::move(resultDetails));
4099+
} else if (!result->has<EntityDetails>()) {
4100+
Say(*distinctResultName,
4101+
"ENTRY cannot have RESULT(%s) that is not a variable"_err_en_US,
4102+
*distinctResultName)
4103+
.Attach(result->name(), "Existing declaration of '%s'"_en_US,
4104+
result->name());
4105+
result = nullptr;
4106+
}
4107+
if (result) {
41184108
Resolve(*suffix->resultName, *result);
41194109
}
41204110
} else {
@@ -4124,8 +4114,7 @@ void SubprogramVisitor::CreateEntry(
41244114
entryDetails.set_result(*result);
41254115
}
41264116
}
4127-
if (subpFlag == Symbol::Flag::Subroutine ||
4128-
(distinctResultName && !badResultName)) {
4117+
if (subpFlag == Symbol::Flag::Subroutine || distinctResultName) {
41294118
Symbol &assoc{MakeSymbol(entryName.source)};
41304119
assoc.set_details(HostAssocDetails{*entrySymbol});
41314120
assoc.set(Symbol::Flag::Subroutine);

flang/test/Semantics/entry01.f90

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,12 @@ function ifunc()
8686
entry ibad2()
8787
!ERROR: ENTRY in a function may not have an alternate return dummy argument
8888
entry ibadalt(*) ! C1573
89-
!ERROR: RESULT(ifunc) may not have the same name as the function
89+
!ERROR: ENTRY cannot have RESULT(ifunc) that is not a variable
9090
entry isameres() result(ifunc) ! C1574
9191
entry iok()
92-
!ERROR: RESULT(iok) may not have the same name as an ENTRY in the function
92+
!ERROR: Explicit RESULT('iok') of function 'isameres2' cannot have the same name as a distinct ENTRY into the same scope
9393
entry isameres2() result(iok) ! C1574
94+
!ERROR: Explicit RESULT('iok2') of function 'isameres3' cannot have the same name as a distinct ENTRY into the same scope
9495
entry isameres3() result(iok2) ! C1574
9596
!ERROR: 'iok2' is already declared in this scoping unit
9697
entry iok2()
@@ -255,3 +256,13 @@ subroutine s7(q,q)
255256
!ERROR: 'z' appears more than once as a dummy argument name in this ENTRY statement
256257
entry baz(z,z)
257258
end
259+
260+
!ERROR: Explicit RESULT('f8e1') of function 'f8' cannot have the same name as a distinct ENTRY into the same scope
261+
function f8() result(f8e1)
262+
entry f8e1()
263+
entry f8e2() result(f8e2) ! ok
264+
!ERROR: Explicit RESULT('f8e1') of function 'f8e3' cannot have the same name as a distinct ENTRY into the same scope
265+
entry f8e3() result(f8e1)
266+
!ERROR: ENTRY cannot have RESULT(f8) that is not a variable
267+
entry f8e4() result(f8)
268+
end

0 commit comments

Comments
 (0)