[llvm-branch-commits] [flang] [flang] Do not branch to a FORMAT statement from an assigned GO TO (PR #217220)
Kareem Ergawy via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Aug 21 02:06:37 PDT 2026
================
@@ -0,0 +1,75 @@
+! RUN: bbc -emit-fir -o - %s | FileCheck %s
+
+! A FORMAT statement is not a branch target. Branching to a label that was
+! ASSIGN'd from one is not conforming, and the program is meant to reach the
+! run-time error rather than jump into the FORMAT statement.
+
+! The only label assigned to j is a FORMAT, so no target survives and no
+! branch is generated at all.
+! CHECK-LABEL: func.func @_QPfmt_only(
+! CHECK: %[[J:.*]] = fir.declare %arg0
+! CHECK: fir.store %c1{{.*}} to %[[J]]
+! CHECK-NOT: fir.select
+! CHECK-NOT: ^bb
+! CHECK: fir.call @_FortranAReportFatalUserError
+! CHECK-NEXT: fir.unreachable
+subroutine fmt_only(j)
+ integer :: j
+ assign 1 to j
+ go to j
+1 format("fmt")
+end subroutine
+
+! Both labels are assigned to j, but only 20 is a branch target. The select
+! carries exactly one case, for 20; label 1 does not appear.
+! CHECK-LABEL: func.func @_QPfmt_and_real(
+! CHECK: %[[J:.*]] = fir.declare %arg0
+! CHECK: fir.store %c1{{.*}} to %[[J]]
+! CHECK: fir.store %c20{{.*}} to %[[J]]
+! CHECK: %[[V:.*]] = fir.load %[[J]]
+! CHECK: fir.select %[[V]] : i32 [20, ^bb[[TGT:[0-9]+]], unit, ^bb[[ERR:[0-9]+]]]
+!
+! The default destination reports the error and terminates.
+! CHECK: ^bb[[ERR]]:
+! CHECK: fir.call @_FortranAReportFatalUserError
+! CHECK-NEXT: fir.unreachable
+!
+! The one real target is the PRINT at label 20, which returns normally.
+! CHECK: ^bb[[TGT]]:
+! CHECK: fir.call @_FortranAioBeginExternalListOutput
+! CHECK: return
+subroutine fmt_and_real(j)
+ integer :: j
+ assign 1 to j
+ assign 20 to j
+ go to j
+1 format("fmt")
+20 print *, "twenty"
+end subroutine
+
+! FORMAT is the only labelled statement that can be assigned and then reach the
+! GO TO without being a branch target; every other kind is rejected by semantic
+! analysis at the ASSIGN. The labels below are branch targets of four different
+! kinds -- an action statement, the statement that begins an IF construct, the
+! statement that begins a DO construct, and the END statement of the subroutine
+! -- so every one of them survives and appears as a case of the select. Each is
+! branched to from the same inclusive scope, and the two construct labels name
+! the statement that begins the construct rather than the one that ends it, so
+! control enters the construct normally instead of jumping into its interior.
+! CHECK-LABEL: func.func @_QPbranch_target_kinds(
+! CHECK: fir.select %{{.*}} : i32 [10, ^bb{{[0-9]+}}, 20, ^bb{{[0-9]+}}, 30, ^bb{{[0-9]+}}, 40, ^bb{{[0-9]+}}, unit, ^bb{{[0-9]+}}]
----------------
ergawy wrote:
Done in 6d3274b48ed580f1a759895bfea11694af4cb719.
https://github.com/llvm/llvm-project/pull/217220
More information about the llvm-branch-commits
mailing list