[flang] Make sure derived-type finalization is done before return
authorValentin Clement <clementval@gmail.com>
Wed, 1 Feb 2023 13:45:53 +0000 (14:45 +0100)
committerValentin Clement <clementval@gmail.com>
Wed, 1 Feb 2023 13:56:18 +0000 (14:56 +0100)
Finalization needs to be done before the terminator. In case
of end program, this was done after it and trigger a verifier error.
This patch fixes this case.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D143055

flang/lib/Lower/Bridge.cpp
flang/test/Lower/derived-type-finalization.f90

index 4f9848d..492176f 100644 (file)
@@ -3438,8 +3438,16 @@ private:
   void endNewFunction(Fortran::lower::pft::FunctionLikeUnit &funit) {
     setCurrentPosition(Fortran::lower::pft::stmtSourceLoc(funit.endStmt));
     if (funit.isMainProgram()) {
-      bridge.fctCtx().finalizeAndPop();
-      genExitRoutine();
+      if (!blockIsUnterminated()) {
+        auto insertPt = builder->saveInsertionPoint();
+        mlir::Block *currentBlock = builder->getBlock();
+        builder->setInsertionPoint(&currentBlock->back());
+        bridge.fctCtx().finalizeAndPop();
+        builder->restoreInsertionPoint(insertPt);
+      } else {
+        bridge.fctCtx().finalizeAndPop();
+        genExitRoutine();
+      }
     } else {
       genFIRProcedureExit(funit, funit.getSubprogramSymbol());
     }
index 81a8a89..6dcf7cf 100644 (file)
@@ -149,3 +149,16 @@ contains
 ! CHECK: return
 
 end module
+
+program p
+  use derived_type_finalization
+  type(t1) :: t
+  print *, 'end of program'
+end program
+
+! CHECK-LABEL: func.func @_QQmain() {
+! CHECK: %[[T:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = "t", uniq_name = "_QFEt"}
+! CHECK: %[[EMBOX:.*]] = fir.embox %[[T]] : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
+! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[EMBOX]] : (!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<none>
+! CHECK: %{{.*}} = fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}} : (!fir.box<none>) -> none
+! CHECK: return