diff --git a/flang/lib/Semantics/resolve-labels.cpp b/flang/lib/Semantics/resolve-labels.cpp index 04e4b142efed..b0cbc4b56e88 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 &) { std::is_same_v || std::is_same_v || std::is_same_v || + std::is_same_v || + std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || @@ -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) { - AddTargetLabelDefinition(label.value(), targetFlags, ParentScope()); + AddTargetLabelDefinition(label.value(), targetFlags, ParentScope(), + /*isExecutableConstructEndStmt=*/false); } else if constexpr (std::is_same_v || std::is_same_v) { // 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) { - constexpr bool isExecutableConstructEndStmt{true}; AddTargetLabelDefinition(label.value(), targetFlags, currentScope_, - isExecutableConstructEndStmt); + /*isExecutableConstructEndStmt=*/true); } else if constexpr (!common::HasMember) { // 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()) { diff --git a/flang/test/Semantics/label19.f90 b/flang/test/Semantics/label19.f90 new file mode 100644 index 000000000000..f8ad05335d07 --- /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