Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions flang/lib/Semantics/resolve-labels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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> ||
Expand Down Expand Up @@ -210,8 +212,9 @@ class ParseTreeAnalyzer {
// 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;
Expand All @@ -238,18 +241,20 @@ class ParseTreeAnalyzer {
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;
}
Expand Down Expand Up @@ -826,7 +831,7 @@ class ParseTreeAnalyzer {
// 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
Expand Down Expand Up @@ -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()) {
Expand Down
19 changes: 19 additions & 0 deletions flang/test/Semantics/label19.f90
Original file line number Diff line number Diff line change
@@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, isn't parser::EndChangeTeamStmt now a valid branch target?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only for branches within the CHANGE TEAM/END TEAM construct. It's not a valid branch target for branches coming from outside the construct.

if (p) goto 3
5 end
Loading