Index: flang/lib/Semantics/resolve-labels.cpp =================================================================== --- flang/lib/Semantics/resolve-labels.cpp +++ flang/lib/Semantics/resolve-labels.cpp @@ -239,8 +239,9 @@ auto targetFlags{ConstructBranchTargetFlags(statement)}; if constexpr (common::HasMember) { AddTargetLabelDefinition(label.value(), targetFlags, ParentScope()); - } else if constexpr (std::is_same_v) { - // the label on an END SELECT is not in the last case + } 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); } else if constexpr (common::HasMember) { constexpr bool isExecutableConstructEndStmt{true}; @@ -279,12 +280,17 @@ bool Pre(const parser::IfConstruct &ifConstruct) { return PushConstructName(ifConstruct); } + void Post(const parser::IfThenStmt &) { PushScope(); } bool Pre(const parser::IfConstruct::ElseIfBlock &) { return SwitchToNewScope(); } bool Pre(const parser::IfConstruct::ElseBlock &) { return SwitchToNewScope(); } + bool Pre(const parser::EndIfStmt &) { + PopScope(); + return true; + } bool Pre(const parser::CaseConstruct &caseConstruct) { return PushConstructName(caseConstruct); } @@ -1008,15 +1014,18 @@ } bool isFatal{false}; ProxyForScope fromScope{scope}; - for (ProxyForScope toScope{target.proxyForScope}; fromScope != toScope; + for (ProxyForScope toScope{target.proxyForScope}; HasScope(toScope); toScope = scopes[toScope].parent) { + while (scopes[fromScope].depth > scopes[toScope].depth) { + fromScope = scopes[fromScope].parent; + } + if (toScope == fromScope) { + break; + } if (scopes[toScope].isExteriorGotoFatal) { isFatal = true; break; } - if (scopes[toScope].depth == scopes[fromScope].depth) { - fromScope = scopes[fromScope].parent; - } } context.Say(position, isFatal Index: flang/test/Semantics/label18.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/label18.f90 @@ -0,0 +1,18 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +program main + if (.true.) then + do j = 1, 2 + goto 1 ! ok; used to cause looping in label resolution + end do + else + goto 1 ! ok +1 end if + if (.true.) then + do j = 1, 2 + !WARNING: Label '1' is in a construct that should not be used as a branch target here + goto 1 + end do + end if + !WARNING: Label '1' is in a construct that should not be used as a branch target here + goto 1 +end