Index: flang/lib/Semantics/resolve-labels.cpp =================================================================== --- flang/lib/Semantics/resolve-labels.cpp +++ flang/lib/Semantics/resolve-labels.cpp @@ -60,7 +60,7 @@ std::is_same_v) { // Executable construct end statements are also supported as // an extension but they need special care because the associated - // construct create there own scope. + // construct create their own scope. return Legality::formerly; } else { return Legality::never; @@ -224,10 +224,10 @@ parser::BlockStmt, parser::ChangeTeamStmt, parser::CriticalStmt, parser::IfThenStmt, parser::NonLabelDoStmt, parser::SelectCaseStmt, parser::SelectRankStmt, parser::SelectTypeStmt>; - using LabeledConstructEndStmts = - std::tuple; + using LabeledConstructEndStmts = std::tuple; using LabeledProgramUnitEndStmts = std::tuple; @@ -294,10 +294,10 @@ return SwitchToNewScope(); } bool Pre(const parser::WhereConstruct &whereConstruct) { - return PushConstructNameWithoutBlock(whereConstruct); + return PushConstructName(whereConstruct); } bool Pre(const parser::ForallConstruct &forallConstruct) { - return PushConstructNameWithoutBlock(forallConstruct); + return PushConstructName(forallConstruct); } void Post(const parser::AssociateConstruct &associateConstruct) { @@ -327,12 +327,11 @@ void Post(const parser::SelectTypeConstruct &selectTypeConstruct) { PopConstructName(selectTypeConstruct); } - void Post(const parser::WhereConstruct &whereConstruct) { - PopConstructNameWithoutBlock(whereConstruct); + PopConstructName(whereConstruct); } void Post(const parser::ForallConstruct &forallConstruct) { - PopConstructNameWithoutBlock(forallConstruct); + PopConstructName(forallConstruct); } // Checks for missing or mismatching names on various constructs (e.g., IF) @@ -558,18 +557,6 @@ } return PushSubscope(); } - template bool PushConstructNameWithoutBlock(const A &a) { - const auto &optionalName{std::get<0>(std::get<0>(a.t).statement.t)}; - if (optionalName) { - constructNames_.emplace_back(optionalName->ToString()); - } - return true; - } - - template void PopConstructNameWithoutBlock(const A &a) { - CheckName(a); - PopConstructNameIfPresent(a); - } template void PopConstructNameIfPresent(const A &a) { const auto &optionalName{std::get<0>(std::get<0>(a.t).statement.t)}; if (optionalName) { @@ -963,13 +950,15 @@ } else if (!InInclusiveScope(scopes, scope, target.proxyForScope)) { // Clause 11.1.2.1 prohibits transfer of control to the interior of a // block from outside the block, but this does not apply to formats. + // C1038 and C1034 forbid statements in FORALL and WHERE constructs + // (resp.) from being branch targets. if (target.labeledStmtClassificationSet.test( TargetStatementEnum::Format)) { continue; } context.Say(position, - parser::MessageFormattedText{ - "Label '%u' is not in scope"_en_US, SayLabel(label)}); + "Label '%u' is in a construct that prevents its use as a branch target here"_en_US, + SayLabel(label)); } } } Index: flang/test/Semantics/label05.f90 =================================================================== --- flang/test/Semantics/label05.f90 +++ flang/test/Semantics/label05.f90 @@ -1,7 +1,6 @@ - ! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s ! CHECK: Label '50' was not found -! CHECK: Label '55' is not in scope +! CHECK: Label '55' is in a construct that prevents its use as a branch target here ! CHECK: Label '70' is not a branch target ! CHECK: Control flow use of '70' Index: flang/test/Semantics/label06.f90 =================================================================== --- flang/test/Semantics/label06.f90 +++ flang/test/Semantics/label06.f90 @@ -1,11 +1,10 @@ - ! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s -! CHECK: Label '10' is not in scope +! CHECK: Label '10' is in a construct that prevents its use as a branch target here ! CHECK: Label '20' was not found ! CHECK: Label '30' is not a branch target ! CHECK: Control flow use of '30' -! CHECK: Label '40' is not in scope -! CHECK: Label '50' is not in scope +! CHECK: Label '40' is in a construct that prevents its use as a branch target here +! CHECK: Label '50' is in a construct that prevents its use as a branch target here subroutine sub00(n) GOTO (10,20,30) n Index: flang/test/Semantics/label07.f90 =================================================================== --- flang/test/Semantics/label07.f90 +++ flang/test/Semantics/label07.f90 @@ -1,8 +1,7 @@ - ! RUN: not %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s ! CHECK: Label '30' is not a branch target ! CHECK: Control flow use of '30' -! CHECK: Label '10' is not in scope +! CHECK: Label '10' is in a construct that prevents its use as a branch target here ! CHECK: Label '20' was not found ! CHECK: Label '60' was not found Index: flang/test/Semantics/label14.f90 =================================================================== --- flang/test/Semantics/label14.f90 +++ flang/test/Semantics/label14.f90 @@ -3,7 +3,7 @@ ! Block Construct ! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s -! CHECK: Label '20' is not in scope +! CHECK: Label '20' is in a construct that prevents its use as a branch target here subroutine s1 block