diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp --- a/flang/lib/Lower/IO.cpp +++ b/flang/lib/Lower/IO.cpp @@ -485,10 +485,12 @@ } /// Generate a sequence of output data transfer calls. -static void genOutputItemList( - Fortran::lower::AbstractConverter &converter, mlir::Value cookie, - const std::list &items, bool isFormatted, - bool checkResult, mlir::Value &ok, bool inLoop) { +static void +genOutputItemList(Fortran::lower::AbstractConverter &converter, + mlir::Value cookie, + const std::list &items, + bool isFormatted, bool checkResult, mlir::Value &ok, + bool inLoop, Fortran::lower::StatementContext &stmtCtx) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); for (const Fortran::parser::OutputItem &item : items) { if (const auto &impliedDo = std::get_if<1>(&item.u)) { @@ -499,7 +501,6 @@ auto &pExpr = std::get(item.u); mlir::Location loc = converter.genLocation(pExpr.source); makeNextConditionalOn(builder, loc, checkResult, ok, inLoop); - Fortran::lower::StatementContext stmtCtx; const auto *expr = Fortran::semantics::GetExpr(pExpr); if (!expr) @@ -720,7 +721,7 @@ ok, /*inLoop=*/true); else genOutputItemList(converter, cookie, itemList, isFormatted, checkResult, - ok, /*inLoop=*/true); + ok, /*inLoop=*/true, stmtCtx); }; if (!checkResult) { // No IO call result checks - the loop is a fir.do_loop op. @@ -2008,11 +2009,11 @@ else genOutputItemList(converter, cookie, stmt.items, isFormatted, csi.hasTransferConditionSpec(), ok, - /*inLoop=*/false); + /*inLoop=*/false, stmtCtx); } else { // PRINT genOutputItemList(converter, cookie, std::get<1>(stmt.t), isFormatted, csi.hasTransferConditionSpec(), ok, - /*inLoop=*/false); + /*inLoop=*/false, stmtCtx); } builder.restoreInsertionPoint(insertPt); @@ -2271,7 +2272,8 @@ genOutputItemList( converter, cookie, std::get>(ioLength->t), - /*isFormatted=*/false, /*checkResult=*/false, ok, /*inLoop=*/false); + /*isFormatted=*/false, /*checkResult=*/false, ok, /*inLoop=*/false, + stmtCtx); auto *ioLengthVar = Fortran::semantics::GetExpr( std::get(ioLength->t)); mlir::Value ioLengthVarAddr = diff --git a/flang/test/Lower/array-character.f90 b/flang/test/Lower/array-character.f90 --- a/flang/test/Lower/array-character.f90 +++ b/flang/test/Lower/array-character.f90 @@ -121,8 +121,8 @@ ! CHECK: %[[VAL_24:.*]] = fir.embox %[[VAL_13]](%[[VAL_12]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.box>> ! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (!fir.box>>) -> !fir.box ! CHECK: %[[VAL_26:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_10]], %[[VAL_25]]) {{.*}}: (!fir.ref, !fir.box) -> i1 - ! CHECK: fir.freemem %[[VAL_13]] ! CHECK: %[[VAL_27:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_10]]) {{.*}}: (!fir.ref) -> i32 + ! CHECK: fir.freemem %[[VAL_13]] ! CHECK: %[[VAL_28:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_0]], %[[VAL_9]], %{{.*}}) {{.*}}: (i32, !fir.ref, i32) -> !fir.ref ! CHECK: %[[VAL_29:.*]] = fir.allocmem !fir.array<4x!fir.char<1,3>> ! CHECK: br ^bb4(%[[VAL_6]], %[[VAL_5]] : index, index) @@ -143,8 +143,8 @@ ! CHECK: %[[VAL_40:.*]] = fir.embox %[[VAL_29]](%[[VAL_12]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.box>> ! CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_40]] : (!fir.box>>) -> !fir.box ! CHECK: %[[VAL_42:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_28]], %[[VAL_41]]) {{.*}}: (!fir.ref, !fir.box) -> i1 - ! CHECK: fir.freemem %[[VAL_29]] : !fir.heap>> ! CHECK: %[[VAL_43:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_28]]) {{.*}}: (!fir.ref) -> i32 + ! CHECK: fir.freemem %[[VAL_29]] : !fir.heap>> ! CHECK: %[[VAL_44:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_0]], %[[VAL_9]], %{{.*}}) {{.*}}: (i32, !fir.ref, i32) -> !fir.ref ! CHECK: %[[VAL_45:.*]] = fir.allocmem !fir.array<4x!fir.char<1,3>> ! CHECK: br ^bb7(%[[VAL_6]], %[[VAL_5]] : index, index) @@ -165,8 +165,8 @@ ! CHECK: %[[VAL_56:.*]] = fir.embox %[[VAL_45]](%[[VAL_12]]) : (!fir.heap>>, !fir.shape<1>) -> !fir.box>> ! CHECK: %[[VAL_57:.*]] = fir.convert %[[VAL_56]] : (!fir.box>>) -> !fir.box ! CHECK: %[[VAL_58:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_44]], %[[VAL_57]]) {{.*}}: (!fir.ref, !fir.box) -> i1 - ! CHECK: fir.freemem %[[VAL_45]] : !fir.heap>> ! CHECK: %[[VAL_59:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_44]]) {{.*}}: (!fir.ref) -> i32 + ! CHECK: fir.freemem %[[VAL_45]] : !fir.heap>> print*, ['AA ', 'MM ', 'MM ', 'ZZ '] print*, ['AA ', 'MM ', 'MM ', 'ZZ '] print*, ['AA ', 'MM ', 'MM ', 'ZZ '] diff --git a/flang/test/Lower/array-expression.f90 b/flang/test/Lower/array-expression.f90 --- a/flang/test/Lower/array-expression.f90 +++ b/flang/test/Lower/array-expression.f90 @@ -1148,8 +1148,8 @@ ! CHECK: %[[VAL_42:.*]] = fir.embox %[[VAL_18]](%[[VAL_41]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> ! CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_42]] : (!fir.box>) -> !fir.box ! CHECK: %[[VAL_44:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_13]], %[[VAL_43]]) {{.*}}: (!fir.ref, !fir.box) -> i1 -! CHECK: fir.freemem %[[VAL_18]] : !fir.heap> ! CHECK: %[[VAL_45:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_13]]) {{.*}}: (!fir.ref) -> i32 +! CHECK: fir.freemem %[[VAL_18]] : !fir.heap> ! CHECK: return ! CHECK: } diff --git a/flang/test/Lower/array-temp.f90 b/flang/test/Lower/array-temp.f90 --- a/flang/test/Lower/array-temp.f90 +++ b/flang/test/Lower/array-temp.f90 @@ -399,9 +399,9 @@ ! CHECK: fir.freemem %[[temp1]] : !fir.heap> ! CHECK: %[[temp3x:[0-9]+]] = fir.allocmem !fir.array<3xf32> ! CHECK: fir.call @_FortranAioOutputDescriptor + ! CHECK-NEXT: fir.call @_FortranAioEndIoStatement ! CHECK-NEXT: fir.freemem %[[temp3x]] : !fir.heap> ! CHECK-NEXT: fir.freemem %[[temp3arg]] : !fir.heap> - ! CHECK-NEXT: fir.call @_FortranAioEndIoStatement print*, [(r([7.0]),i=1,3)] contains ! CHECK-LABEL: func @_QFtt1Pr diff --git a/flang/test/Lower/derived-type-finalization.f90 b/flang/test/Lower/derived-type-finalization.f90 --- a/flang/test/Lower/derived-type-finalization.f90 +++ b/flang/test/Lower/derived-type-finalization.f90 @@ -12,12 +12,23 @@ final :: t1_final end type + type :: t2 + integer :: b + contains + final :: t2_final + end type + contains subroutine t1_final(this) type(t1) :: this end subroutine + subroutine t2_final(this) + type(t2) :: this + print*,'finalize t2 = ', this%b + end subroutine + ! 7.5.6.3 point 1. Finalization of LHS. subroutine test_lhs() type(t1) :: lhs, rhs @@ -148,6 +159,26 @@ ! CHECK: %{{.*}} = fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}}: (!fir.box) -> none ! CHECK: return + type(t2) function get_t2(i) + integer, intent(in) :: i + get_t2%b = i + end function + + subroutine test_end_of_io_finalize() + print*, get_t2(10) + end subroutine + +! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_end_of_io_finalize() { +! CHECK: %[[TMP:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt2{b:i32}> {bindc_name = ".result"} +! CHECK: %{{.*}} = fir.call @_FortranAioBeginExternalListOutput(%{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (i32, !fir.ref, i32) -> !fir.ref +! CHECK: %[[CALL_RES:.*]] = fir.call @_QMderived_type_finalizationPget_t2(%{{.*}}) {{.*}} : (!fir.ref) -> !fir.type<_QMderived_type_finalizationTt2{b:i32}> +! CHECK: fir.save_result %[[CALL_RES]] to %[[TMP]] : !fir.type<_QMderived_type_finalizationTt2{b:i32}>, !fir.ref> +! CHECK: %{{.*}} = fir.call @_FortranAioOutputDescriptor(%{{.*}}, %{{.*}}) {{.*}} : (!fir.ref, !fir.box) -> i1 +! CHECK: %{{.*}} = fir.call @_FortranAioEndIoStatement(%4) {{.*}} : (!fir.ref) -> i32 +! CHECK: %[[EMBOX_TMP:.*]] = fir.embox %[[TMP]] : (!fir.ref>) -> !fir.box> +! CHECK: %[[TMP_BOX_NONE:.*]] = fir.convert %[[EMBOX_TMP]] : (!fir.box>) -> !fir.box +! CHECK: %{{.*}} = fir.call @_FortranADestroy(%[[TMP_BOX_NONE]]) {{.*}} : (!fir.box) -> none + end module program p diff --git a/flang/test/Lower/host-associated.f90 b/flang/test/Lower/host-associated.f90 --- a/flang/test/Lower/host-associated.f90 +++ b/flang/test/Lower/host-associated.f90 @@ -521,8 +521,8 @@ ! CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_11]] : (!fir.ref>) -> !fir.ref ! CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_9]] : (index) -> i64 ! CHECK: %[[VAL_42:.*]] = fir.call @_FortranAioOutputAscii(%[[VAL_32]], %[[VAL_40]], %[[VAL_41]]) {{.*}}: (!fir.ref, !fir.ref, i64) -> i1 -! CHECK: fir.call @llvm.stackrestore(%[[VAL_38]]) {{.*}}: (!fir.ref) -> () ! CHECK: %[[VAL_43:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_32]]) {{.*}}: (!fir.ref) -> i32 +! CHECK: fir.call @llvm.stackrestore(%[[VAL_38]]) {{.*}}: (!fir.ref) -> () ! CHECK: return ! CHECK: } diff --git a/flang/test/Lower/io-statement-big-unit-checks.f90 b/flang/test/Lower/io-statement-big-unit-checks.f90 --- a/flang/test/Lower/io-statement-big-unit-checks.f90 +++ b/flang/test/Lower/io-statement-big-unit-checks.f90 @@ -285,20 +285,20 @@ ! CHECK: %[[VAL_72:.*]] = fir.call @_QPmake_temp4() {{.*}}: () -> !fir.box> ! CHECK: fir.save_result %[[VAL_72]] to %[[VAL_5:.*]] : !fir.box>, !fir.ref>> ! CHECK: %[[VAL_77:.*]] = fir.call @_FortranAioOutputDescriptor( -! CHECK: %[[VAL_77_1:.*]] = fir.load %[[VAL_5]] : !fir.ref>> -! CHECK: %[[VAL_77_2:.*]] = fir.box_addr %[[VAL_77_1]] : (!fir.box>) -> !fir.heap -! CHECK: fir.freemem %[[VAL_77_2]] : !fir.heap ! CHECK: fir.if %[[VAL_77]] { ! CHECK: %[[VAL_78:.*]] = fir.call @_QPmake_temp5() {{.*}}: () -> !fir.box> ! CHECK: fir.save_result %[[VAL_78]] to %[[VAL_4:.*]] : !fir.box>, !fir.ref>> ! CHECK: fir.call @_FortranAioOutputDescriptor( -! CHECK: %[[VAL_84:.*]] = fir.load %[[VAL_4]] : !fir.ref>> -! CHECK: %[[VAL_85:.*]] = fir.box_addr %[[VAL_84]] : (!fir.box>) -> !fir.heap -! CHECK: fir.freemem %[[VAL_85]] : !fir.heap ! CHECK: } ! CHECK-NOT: fir.call @_QPmake_temp3 ! CHECK: fir.call @_FortranAioGetIoMsg( ! CHECK: %[[VAL_97:.*]] = fir.call @_FortranAioEndIoStatement( +! CHECK: %[[VAL_84:.*]] = fir.load %[[VAL_4]] : !fir.ref>> +! CHECK: %[[VAL_85:.*]] = fir.box_addr %[[VAL_84]] : (!fir.box>) -> !fir.heap +! CHECK: fir.freemem %[[VAL_85]] : !fir.heap +! CHECK: %[[VAL_77_1:.*]] = fir.load %[[VAL_5]] : !fir.ref>> +! CHECK: %[[VAL_77_2:.*]] = fir.box_addr %[[VAL_77_1]] : (!fir.box>) -> !fir.heap +! CHECK: fir.freemem %[[VAL_77_2]] : !fir.heap ! CHECK: fir.result %[[VAL_97]] : i32 ! CHECK: } else { ! CHECK: fir.result %[[VAL_57]] : i32