[flang-commits] [flang] 210e675 - [flang] Accept CHANGE TEAM/END TEAM as branch target (#123822)
via flang-commits
flang-commits at lists.llvm.org
Mon Jan 27 08:55:00 PST 2025
Author: Peter Klausler
Date: 2025-01-27T08:54:56-08:00
New Revision: 210e675cfd7be3d7e0d93c29368acd27b51f9a17
URL: https://github.com/llvm/llvm-project/commit/210e675cfd7be3d7e0d93c29368acd27b51f9a17
DIFF: https://github.com/llvm/llvm-project/commit/210e675cfd7be3d7e0d93c29368acd27b51f9a17.diff
LOG: [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.
Added:
flang/test/Semantics/label19.f90
Modified:
flang/lib/Semantics/resolve-labels.cpp
Removed:
################################################################################
diff --git a/flang/lib/Semantics/resolve-labels.cpp b/flang/lib/Semantics/resolve-labels.cpp
index 04e4b142efedf8..b0cbc4b56e8896 100644
--- a/flang/lib/Semantics/resolve-labels.cpp
+++ b/flang/lib/Semantics/resolve-labels.cpp
@@ -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 @@ 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;
@@ -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;
}
@@ -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
@@ -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()) {
diff --git a/flang/test/Semantics/label19.f90 b/flang/test/Semantics/label19.f90
new file mode 100644
index 00000000000000..f8ad05335d0700
--- /dev/null
+++ b/flang/test/Semantics/label19.f90
@@ -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
More information about the flang-commits
mailing list