Index: flang/lib/Lower/Bridge.cpp =================================================================== --- flang/lib/Lower/Bridge.cpp +++ flang/lib/Lower/Bridge.cpp @@ -1661,6 +1661,14 @@ llvm::SmallVector valueList; llvm::SmallVector blockList; mlir::Block *defaultBlock = eval.parentConstruct->constructExit->block; + if (!defaultBlock && + eval.parentConstruct->constructExit->lexicalSuccessor->block) { + // The CaseConstruct is perfectly nested in other construct without any + // other statements. The exit block is the block of the sucessor of parent + // construct exit. + defaultBlock = + eval.parentConstruct->constructExit->lexicalSuccessor->block; + } using CaseValue = Fortran::parser::Scalar; auto addValue = [&](const CaseValue &caseValue) { const Fortran::lower::SomeExpr *expr = Index: flang/lib/Lower/PFTBuilder.cpp =================================================================== --- flang/lib/Lower/PFTBuilder.cpp +++ flang/lib/Lower/PFTBuilder.cpp @@ -822,7 +822,7 @@ lastConstructStmtEvaluation = &eval; }, [&](const parser::EndSelectStmt &) { - eval.nonNopSuccessor().isNewBlock = true; + eval.lexicalSuccessor->isNewBlock = true; lastConstructStmtEvaluation = nullptr; }, [&](const parser::ChangeTeamStmt &s) { @@ -918,7 +918,11 @@ eval.constructExit = &eval.evaluationList->back(); }, [&](const parser::CaseConstruct &) { - setConstructExit(eval); + // FIXME: Fix this by using one general solution by fixing + // `setConstructExit` considering there is nop successor when + // creating PFT, but generating one statement such as memory free + // when lowering. + eval.constructExit = eval.evaluationList->back().lexicalSuccessor; eval.isUnstructured = true; }, [&](const parser::ChangeTeamConstruct &) { Index: flang/test/Lower/nested-branching.f90 =================================================================== --- /dev/null +++ flang/test/Lower/nested-branching.f90 @@ -0,0 +1,31 @@ +! RUN: bbc -emit-fir -o - %s | FileCheck %s + +! CHECK-LABEL: func.func @_QMmPhd() { +! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.box>> +! CHECK: cf.cond_br %{{.*}}, ^bb1, ^bb4 +! CHECK:^bb1: // pred: ^bb0 +! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[VAL_2:.*]] = fir.box_elesize %[[VAL_1]] : (!fir.box>>) -> index +! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2:.*]] : (!fir.box>>) -> !fir.heap> +! CHECK: cf.cond_br %{{.*}}, ^bb2, ^bb2 +! CHECK:^bb2: // 2 preds: ^bb1, ^bb1 +! CHECK: cf.br ^bb3 +! CHECK:^bb3: // pred: ^bb2 +! CHECK: fir.freemem %[[VAL_3]] : !fir.heap> +! CHECK: cf.br ^bb4 +! CHECK:^bb4: // 2 preds: ^bb0, ^bb3 +! CHECK: return +! CHECK:} + +module m + character(len=16) :: x +contains + subroutine hd + if (.true.) then + select case(trim(x)) + case('abc') + continue + end select + end if + end subroutine +end module m