[flang] Accept CHANGE TEAM/END TEAM as branch target (#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.
This commit is contained in:
parent
73db9ee1e8
commit
210e675cfd
@ -122,6 +122,8 @@ constexpr Legality IsLegalBranchTarget(const parser::Statement<A> &) {
|
||||
std::is_same_v<A, parser::EndCriticalStmt> ||
|
||||
std::is_same_v<A, parser::ForallConstructStmt> ||
|
||||
std::is_same_v<A, parser::WhereConstructStmt> ||
|
||||
std::is_same_v<A, parser::ChangeTeamStmt> ||
|
||||
std::is_same_v<A, parser::EndChangeTeamStmt> ||
|
||||
std::is_same_v<A, parser::EndFunctionStmt> ||
|
||||
std::is_same_v<A, parser::EndMpSubprogramStmt> ||
|
||||
std::is_same_v<A, parser::EndProgramStmt> ||
|
||||
@ -210,8 +212,9 @@ public:
|
||||
// subprograms. Visit that statement in advance so that results
|
||||
// are placed in the correct programUnits_ slot.
|
||||
auto targetFlags{ConstructBranchTargetFlags(endStmt)};
|
||||
AddTargetLabelDefinition(
|
||||
endStmt.label.value(), targetFlags, currentScope_);
|
||||
AddTargetLabelDefinition(endStmt.label.value(), targetFlags,
|
||||
currentScope_,
|
||||
/*isExecutableConstructEndStmt=*/false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -238,18 +241,20 @@ public:
|
||||
parser::EndProgramStmt, parser::EndSubroutineStmt>;
|
||||
auto targetFlags{ConstructBranchTargetFlags(statement)};
|
||||
if constexpr (common::HasMember<A, LabeledConstructStmts>) {
|
||||
AddTargetLabelDefinition(label.value(), targetFlags, ParentScope());
|
||||
AddTargetLabelDefinition(label.value(), targetFlags, ParentScope(),
|
||||
/*isExecutableConstructEndStmt=*/false);
|
||||
} else if constexpr (std::is_same_v<A, parser::EndIfStmt> ||
|
||||
std::is_same_v<A, parser::EndSelectStmt>) {
|
||||
// the label on an END IF/SELECT is not in the last part/case
|
||||
AddTargetLabelDefinition(label.value(), targetFlags, ParentScope(), true);
|
||||
AddTargetLabelDefinition(label.value(), targetFlags, ParentScope(),
|
||||
/*isExecutableConstructEndStmt=*/true);
|
||||
} else if constexpr (common::HasMember<A, LabeledConstructEndStmts>) {
|
||||
constexpr bool isExecutableConstructEndStmt{true};
|
||||
AddTargetLabelDefinition(label.value(), targetFlags, currentScope_,
|
||||
isExecutableConstructEndStmt);
|
||||
/*isExecutableConstructEndStmt=*/true);
|
||||
} else if constexpr (!common::HasMember<A, LabeledProgramUnitEndStmts>) {
|
||||
// Program unit END statements have already been processed.
|
||||
AddTargetLabelDefinition(label.value(), targetFlags, currentScope_);
|
||||
AddTargetLabelDefinition(label.value(), targetFlags, currentScope_,
|
||||
/*isExecutableConstructEndStmt=*/false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -826,7 +831,7 @@ private:
|
||||
// 6.2.5., paragraph 2
|
||||
void AddTargetLabelDefinition(parser::Label label,
|
||||
LabeledStmtClassificationSet labeledStmtClassificationSet,
|
||||
ProxyForScope scope, bool isExecutableConstructEndStmt = false) {
|
||||
ProxyForScope scope, bool isExecutableConstructEndStmt) {
|
||||
CheckLabelInRange(label);
|
||||
TargetStmtMap &targetStmtMap{disposableMaps_.empty()
|
||||
? programUnits_.back().targetStmts
|
||||
@ -912,7 +917,7 @@ bool InBody(const parser::CharBlock &position,
|
||||
return false;
|
||||
}
|
||||
|
||||
LabeledStatementInfoTuplePOD GetLabel(
|
||||
static LabeledStatementInfoTuplePOD GetLabel(
|
||||
const TargetStmtMap &labels, const parser::Label &label) {
|
||||
const auto iter{labels.find(label)};
|
||||
if (iter == labels.cend()) {
|
||||
|
19
flang/test/Semantics/label19.f90
Normal file
19
flang/test/Semantics/label19.f90
Normal file
@ -0,0 +1,19 @@
|
||||
! RUN: %python %S/test_errors.py %s %flang_fc1
|
||||
program main
|
||||
use, intrinsic:: iso_fortran_env, only: team_type
|
||||
type(team_type) team
|
||||
logical :: p = false
|
||||
1 change team(team)
|
||||
2 if (p) goto 1 ! ok
|
||||
if (p) goto 2 ! ok
|
||||
if (p) goto 3 ! ok
|
||||
if (p) goto 4 ! ok
|
||||
if (p) goto 5 ! ok
|
||||
3 end team
|
||||
4 continue
|
||||
if (p) goto 1 ! ok
|
||||
!ERROR: Label '2' is in a construct that prevents its use as a branch target here
|
||||
if (p) goto 2
|
||||
!ERROR: Label '3' is in a construct that prevents its use as a branch target here
|
||||
if (p) goto 3
|
||||
5 end
|
Loading…
x
Reference in New Issue
Block a user