Index: flang/lib/Lower/ConvertExpr.cpp
===================================================================
--- flang/lib/Lower/ConvertExpr.cpp
+++ flang/lib/Lower/ConvertExpr.cpp
@@ -3367,7 +3367,13 @@
semant = ConstituentSemantics::RefTransparent;
ExtValue exv = lowerArrayExpression(rhs);
if (explicitSpaceIsActive()) {
- explicitSpace->finalizeContext();
+ if constexpr (std::is_same_v
) {
+ if (rhs.Rank() > 0)
+ explicitSpace->finalizeContext();
+ } else if constexpr (std::is_same_v
) {
+ if (rhs.rank() > 0)
+ explicitSpace->finalizeContext();
+ }
builder.create(loc, fir::getBase(exv));
} else {
builder.create(
@@ -3483,7 +3489,8 @@
assert(destination && "destination must have been set");
ExtValue exv = lowerArrayExpression(rhsCC, resultTy);
if (explicitSpaceIsActive()) {
- explicitSpace->finalizeContext();
+ if (rhs.Rank() > 0)
+ explicitSpace->finalizeContext();
builder.create(loc, fir::getBase(exv));
} else {
builder.create(
@@ -3668,7 +3675,8 @@
semant = ConstituentSemantics::RefTransparent;
auto exv = lowerArrayExpression(rhs);
if (explicitSpaceIsActive()) {
- explicitSpace->finalizeContext();
+ if (rhs.Rank() > 0)
+ explicitSpace->finalizeContext();
builder.create(loc, fir::getBase(exv));
} else {
builder.create(
@@ -3979,6 +3987,8 @@
: defaultStoreToDestination(/*substring=*/nullptr);
mlir::Value updVal = fir::getBase(lambda(iterSpace));
finalizeElementCtx();
+ if (explicitSpaceIsActive() && !resultTy.isa())
+ explicitSpace->finalizeContext();
builder.create(loc, updVal);
builder.restoreInsertionPoint(insPt);
return abstractArrayExtValue(iterSpace.outerResult());
Index: flang/test/Lower/forall/forall-3.f90
===================================================================
--- /dev/null
+++ flang/test/Lower/forall/forall-3.f90
@@ -0,0 +1,66 @@
+! Test forall lowering for explicit space finalization
+
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: func @_QPforall_scalar_to_array_section
+! CHECK: %{{.*}} = fir.do_loop
+! CHECK: %[[VAL_0:.*]] = fir.do_loop
+! CHECK: %[[VAL_1:.*]] = fir.allocmem !fir.array<1xi32>
+! CHECK: %[[VAL_2:.*]] = fir.if %{{.*}} -> (!fir.heap>) {
+! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_1]] : (!fir.heap>) -> !fir.ref
+! CHECK: %[[VAL_4:.*]] = fir.call @realloc(%[[VAL_3]], %{{.*}}) : (!fir.ref, i64) -> !fir.ref
+! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ref) -> !fir.heap>
+! CHECK: fir.result %[[VAL_5]] : !fir.heap>
+! CHECK: } else {
+! CHECK: fir.result %[[VAL_1:.*]] : !fir.heap>
+! CHECK: }
+! CHECK: %[[VAL_6:.*]] = fir.allocmem !fir.array<1xi32>
+! CHECK: fir.freemem %[[VAL_6]] : !fir.heap>
+! CHECK: fir.freemem %[[VAL_2]] : !fir.heap>
+! CHECK: fir.result %{{.*}} : !fir.array<6xi32>
+! CHECK: }
+! CHECK: fir.result %[[VAL_0]] : !fir.array<6xi32>
+! CHECK: }
+subroutine forall_scalar_to_array_section()
+ integer :: arr(6), i
+ forall (i=1:6)
+ arr(i:i+1) = func((/i/))
+ end forall
+
+contains
+ pure function func(a) result(res)
+ integer, intent(in) :: a(:)
+ integer :: res
+ res = a(1)
+ end function
+end subroutine
+
+! CHECK-LABEL: func @_QPforall_array_to_array_section
+! CHECK: %{{.*}} = fir.do_loop
+! CHECK: %[[VAL_0:.*]] = fir.allocmem !fir.array<1xi32>
+! CHECK: %[[VAL_1:.*]] = fir.if %{{.*}} -> (!fir.heap>) {
+! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_0]] : (!fir.heap>) -> !fir.ref
+! CHECK: %[[VAL_3:.*]] = fir.call @realloc(%[[VAL_2]], %{{.*}}) : (!fir.ref, i64) -> !fir.ref
+! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref) -> !fir.heap>
+! CHECK: fir.result %[[VAL_4]] : !fir.heap>
+! CHECK: } else {
+! CHECK: fir.result %[[VAL_0]] : !fir.heap>
+! CHECK: }
+! CHECK: %[[VAL_5:.*]] = fir.allocmem !fir.array<1xi32>
+! CHECK: fir.freemem %[[VAL_5]] : !fir.heap>
+! CHECK: fir.freemem %[[VAL_1]] : !fir.heap>
+! CHECK: fir.result %{{.*}} : !fir.array<6xi32>
+! CHECK: }
+subroutine forall_array_to_array_section()
+ integer :: arr(6), i
+ forall (i=1:6)
+ arr(i:i+1) = func((/i/))
+ end forall
+
+contains
+ pure function func(a) result(res)
+ integer, intent(in) :: a(:)
+ integer :: res(2)
+ res = a(1)
+ end function
+end subroutine