Skip to content

Commit ee9c917

Browse files
committed
[flang] Fix bogus branch target error on END SELECT
The scope model used for branch target checking treats a label on an END SELECT statement as if it were in the previous CASE block. This makes it illegal to GO TO that label from within any earlier CASE block in that statement. Fix by treating the CASE blocks as nested scopes within the scope of the SELECT construct. Also, add a "warning:" tag to related warning messages. Differential Revision: https://reviews.llvm.org/D127425
1 parent bb1a52a commit ee9c917

File tree

4 files changed

+14
-8
lines changed

4 files changed

+14
-8
lines changed

flang/lib/Semantics/resolve-labels.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -233,13 +233,16 @@ class ParseTreeAnalyzer {
233233
using LabeledConstructEndStmts = std::tuple<parser::EndAssociateStmt,
234234
parser::EndBlockStmt, parser::EndChangeTeamStmt,
235235
parser::EndCriticalStmt, parser::EndDoStmt, parser::EndForallStmt,
236-
parser::EndIfStmt, parser::EndSelectStmt, parser::EndWhereStmt>;
236+
parser::EndIfStmt, parser::EndWhereStmt>;
237237
using LabeledProgramUnitEndStmts =
238238
std::tuple<parser::EndFunctionStmt, parser::EndMpSubprogramStmt,
239239
parser::EndProgramStmt, parser::EndSubroutineStmt>;
240240
auto targetFlags{ConstructBranchTargetFlags(statement)};
241241
if constexpr (common::HasMember<A, LabeledConstructStmts>) {
242242
AddTargetLabelDefinition(label.value(), targetFlags, ParentScope());
243+
} else if constexpr (std::is_same_v<A, parser::EndSelectStmt>) {
244+
// the label on an END SELECT is not in the last case
245+
AddTargetLabelDefinition(label.value(), targetFlags, ParentScope(), true);
243246
} else if constexpr (common::HasMember<A, LabeledConstructEndStmts>) {
244247
constexpr bool isExecutableConstructEndStmt{true};
245248
AddTargetLabelDefinition(label.value(), targetFlags, currentScope_,
@@ -286,19 +289,23 @@ class ParseTreeAnalyzer {
286289
bool Pre(const parser::CaseConstruct &caseConstruct) {
287290
return PushConstructName(caseConstruct);
288291
}
292+
void Post(const parser::SelectCaseStmt &) { PushScope(); }
289293
bool Pre(const parser::CaseConstruct::Case &) { return SwitchToNewScope(); }
290294
bool Pre(const parser::SelectRankConstruct &selectRankConstruct) {
291295
return PushConstructName(selectRankConstruct);
292296
}
297+
void Post(const parser::SelectRankStmt &) { PushScope(); }
293298
bool Pre(const parser::SelectRankConstruct::RankCase &) {
294299
return SwitchToNewScope();
295300
}
296301
bool Pre(const parser::SelectTypeConstruct &selectTypeConstruct) {
297302
return PushConstructName(selectTypeConstruct);
298303
}
304+
void Post(const parser::SelectTypeStmt &) { PushScope(); }
299305
bool Pre(const parser::SelectTypeConstruct::TypeCase &) {
300306
return SwitchToNewScope();
301307
}
308+
void Post(const parser::EndSelectStmt &) { PopScope(); }
302309
bool Pre(const parser::WhereConstruct &whereConstruct) {
303310
return PushConstructName(whereConstruct);
304311
}
@@ -994,7 +1001,7 @@ void CheckScopeConstraints(const SourceStmtList &stmts,
9941001
context.Say(position,
9951002
isFatal
9961003
? "Label '%u' is in a construct that prevents its use as a branch target here"_err_en_US
997-
: "Label '%u' is in a construct that prevents its use as a branch target here"_en_US,
1004+
: "Label '%u' is in a construct that should not be used as a branch target here"_warn_en_US,
9981005
SayLabel(label));
9991006
}
10001007
}

flang/test/Semantics/label05.f90

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
22
! CHECK: Label '50' was not found
3-
! CHECK-NOT: error: Label '55' is in a construct that prevents its use as a branch target here
4-
! CHECK: Label '55' is in a construct that prevents its use as a branch target here
3+
! CHECK: warning: Label '55' is in a construct that should not be used as a branch target here
54
! CHECK: Label '70' is not a branch target
65
! CHECK: Control flow use of '70'
76
! CHECK: error: Label '80' is in a construct that prevents its use as a branch target here

flang/test/Semantics/label06.f90

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
2-
! CHECK: Label '10' is in a construct that prevents its use as a branch target here
2+
! CHECK: warning: Label '10' is in a construct that should not be used as a branch target here
33
! CHECK: Label '20' was not found
44
! CHECK: Label '30' is not a branch target
55
! CHECK: Control flow use of '30'
6-
! CHECK: Label '40' is in a construct that prevents its use as a branch target here
7-
! CHECK: Label '50' is in a construct that prevents its use as a branch target here
6+
! CHECK: warning: Label '40' is in a construct that should not be used as a branch target here
7+
! CHECK: warning: Label '50' is in a construct that should not be used as a branch target here
88

99
subroutine sub00(n)
1010
GOTO (10,20,30) n

flang/test/Semantics/label07.f90

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
22
! CHECK: Label '30' is not a branch target
33
! CHECK: Control flow use of '30'
4-
! CHECK: Label '10' is in a construct that prevents its use as a branch target here
4+
! CHECK: warning: Label '10' is in a construct that should not be used as a branch target here
55
! CHECK: Label '20' was not found
66
! CHECK: Label '60' was not found
77

0 commit comments

Comments
 (0)