Skip to content

Commit 210e675

Browse files
authored
[flang] Accept CHANGE TEAM/END TEAM as branch target (llvm#123822)
It is valid to jump to a CHANGE TEAM statement from anywhere in the containing executable part, and valid to jump to an END TEAM statement from within the construct.
1 parent 73db9ee commit 210e675

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

flang/lib/Semantics/resolve-labels.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ constexpr Legality IsLegalBranchTarget(const parser::Statement<A> &) {
122122
std::is_same_v<A, parser::EndCriticalStmt> ||
123123
std::is_same_v<A, parser::ForallConstructStmt> ||
124124
std::is_same_v<A, parser::WhereConstructStmt> ||
125+
std::is_same_v<A, parser::ChangeTeamStmt> ||
126+
std::is_same_v<A, parser::EndChangeTeamStmt> ||
125127
std::is_same_v<A, parser::EndFunctionStmt> ||
126128
std::is_same_v<A, parser::EndMpSubprogramStmt> ||
127129
std::is_same_v<A, parser::EndProgramStmt> ||
@@ -210,8 +212,9 @@ class ParseTreeAnalyzer {
210212
// subprograms. Visit that statement in advance so that results
211213
// are placed in the correct programUnits_ slot.
212214
auto targetFlags{ConstructBranchTargetFlags(endStmt)};
213-
AddTargetLabelDefinition(
214-
endStmt.label.value(), targetFlags, currentScope_);
215+
AddTargetLabelDefinition(endStmt.label.value(), targetFlags,
216+
currentScope_,
217+
/*isExecutableConstructEndStmt=*/false);
215218
}
216219
}
217220
return true;
@@ -238,18 +241,20 @@ class ParseTreeAnalyzer {
238241
parser::EndProgramStmt, parser::EndSubroutineStmt>;
239242
auto targetFlags{ConstructBranchTargetFlags(statement)};
240243
if constexpr (common::HasMember<A, LabeledConstructStmts>) {
241-
AddTargetLabelDefinition(label.value(), targetFlags, ParentScope());
244+
AddTargetLabelDefinition(label.value(), targetFlags, ParentScope(),
245+
/*isExecutableConstructEndStmt=*/false);
242246
} else if constexpr (std::is_same_v<A, parser::EndIfStmt> ||
243247
std::is_same_v<A, parser::EndSelectStmt>) {
244248
// the label on an END IF/SELECT is not in the last part/case
245-
AddTargetLabelDefinition(label.value(), targetFlags, ParentScope(), true);
249+
AddTargetLabelDefinition(label.value(), targetFlags, ParentScope(),
250+
/*isExecutableConstructEndStmt=*/true);
246251
} else if constexpr (common::HasMember<A, LabeledConstructEndStmts>) {
247-
constexpr bool isExecutableConstructEndStmt{true};
248252
AddTargetLabelDefinition(label.value(), targetFlags, currentScope_,
249-
isExecutableConstructEndStmt);
253+
/*isExecutableConstructEndStmt=*/true);
250254
} else if constexpr (!common::HasMember<A, LabeledProgramUnitEndStmts>) {
251255
// Program unit END statements have already been processed.
252-
AddTargetLabelDefinition(label.value(), targetFlags, currentScope_);
256+
AddTargetLabelDefinition(label.value(), targetFlags, currentScope_,
257+
/*isExecutableConstructEndStmt=*/false);
253258
}
254259
return true;
255260
}
@@ -826,7 +831,7 @@ class ParseTreeAnalyzer {
826831
// 6.2.5., paragraph 2
827832
void AddTargetLabelDefinition(parser::Label label,
828833
LabeledStmtClassificationSet labeledStmtClassificationSet,
829-
ProxyForScope scope, bool isExecutableConstructEndStmt = false) {
834+
ProxyForScope scope, bool isExecutableConstructEndStmt) {
830835
CheckLabelInRange(label);
831836
TargetStmtMap &targetStmtMap{disposableMaps_.empty()
832837
? programUnits_.back().targetStmts
@@ -912,7 +917,7 @@ bool InBody(const parser::CharBlock &position,
912917
return false;
913918
}
914919

915-
LabeledStatementInfoTuplePOD GetLabel(
920+
static LabeledStatementInfoTuplePOD GetLabel(
916921
const TargetStmtMap &labels, const parser::Label &label) {
917922
const auto iter{labels.find(label)};
918923
if (iter == labels.cend()) {

flang/test/Semantics/label19.f90

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
! RUN: %python %S/test_errors.py %s %flang_fc1
2+
program main
3+
use, intrinsic:: iso_fortran_env, only: team_type
4+
type(team_type) team
5+
logical :: p = false
6+
1 change team(team)
7+
2 if (p) goto 1 ! ok
8+
if (p) goto 2 ! ok
9+
if (p) goto 3 ! ok
10+
if (p) goto 4 ! ok
11+
if (p) goto 5 ! ok
12+
3 end team
13+
4 continue
14+
if (p) goto 1 ! ok
15+
!ERROR: Label '2' is in a construct that prevents its use as a branch target here
16+
if (p) goto 2
17+
!ERROR: Label '3' is in a construct that prevents its use as a branch target here
18+
if (p) goto 3
19+
5 end

0 commit comments

Comments
 (0)