diff --git a/flang/lib/Lower/Allocatable.cpp b/flang/lib/Lower/Allocatable.cpp --- a/flang/lib/Lower/Allocatable.cpp +++ b/flang/lib/Lower/Allocatable.cpp @@ -220,7 +220,7 @@ : fir::runtime::getRuntimeFunc( loc, builder); llvm::SmallVector args{ - fir::factory::getMutableIRBox(builder, loc, box), fir::getBase(mold), + box.getAddr(), fir::getBase(mold), builder.createIntegerConstant( loc, callee.getFunctionType().getInputs()[2], rank)}; llvm::SmallVector operands; @@ -373,11 +373,15 @@ if (sourceExpr) { genSourceAllocation(alloc, boxAddr); - } else if (moldExpr) { + } else if ((moldExpr && moldExpr->Rank() != 0) && + alloc.type.category() != + Fortran::semantics::DeclTypeSpec::Category::Character) + // When the MOLD is a scalar and the allocation is not CHARACTER, just + // use simple allocation because the MOLD argument doesn't have any + // relevant information. genMoldAllocation(alloc, boxAddr); - } else { + else genSimpleAllocation(alloc, boxAddr); - } } static bool lowerBoundsAreOnes(const Allocation &alloc) { diff --git a/flang/test/Lower/allocate-mold.f90 b/flang/test/Lower/allocate-mold.f90 --- a/flang/test/Lower/allocate-mold.f90 +++ b/flang/test/Lower/allocate-mold.f90 @@ -10,10 +10,28 @@ ! CHECK-LABEL: func.func @_QPscalar_mold_allocation() { ! CHECK: %[[A:.*]] = fir.alloca !fir.box> {bindc_name = "a", uniq_name = "_QFscalar_mold_allocationEa"} ! CHECK: %[[HEAP_A:.*]] = fir.alloca !fir.heap {uniq_name = "_QFscalar_mold_allocationEa.addr"} -! CHECK: %[[ADDR_A:.*]] = fir.load %[[HEAP_A]] : !fir.ref> -! CHECK: %[[BOX_ADDR_A:.*]] = fir.embox %[[ADDR_A]] : (!fir.heap) -> !fir.box> -! CHECK: fir.store %[[BOX_ADDR_A]] to %[[A]] : !fir.ref>> -! CHECK: %[[A_REF_BOX_NONE1:.*]] = fir.convert %[[A]] : (!fir.ref>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableApplyMold(%[[A_REF_BOX_NONE1]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, !fir.box, i32) -> none -! CHECK: %[[A_REF_BOX_NONE2:.*]] = fir.convert %[[A]] : (!fir.ref>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[A_REF_BOX_NONE2]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap +! CHECK: fir.store %[[ZERO]] to %[[HEAP_A]] : !fir.ref> +! CHECK: %[[ALLOCATED:.*]] = fir.allocmem i32 {fir.must_be_heap = true, uniq_name = "_QFscalar_mold_allocationEa.alloc"} +! CHECK: fir.store %[[ALLOCATED]] to %[[HEAP_A]] : !fir.ref> + + +subroutine array_scalar_mold_allocation() + real, allocatable :: a(:) + + allocate (a(10), mold=3.0) +end subroutine array_scalar_mold_allocation + +! CHECK-LABEL: func.func @_QParray_scalar_mold_allocation() { +! CHECK: %[[HEAP_A:.*]] = fir.alloca !fir.heap> {uniq_name = "_QFarray_scalar_mold_allocationEa.addr"} +! CHECK: %[[EXT0:.*]] = fir.alloca index {uniq_name = "_QFarray_scalar_mold_allocationEa.ext0"} +! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap> +! CHECK: fir.store %[[ZERO]] to %[[HEAP_A]] : !fir.ref>> +! CHECK: %[[C10:.*]] = arith.constant 10 : i32 +! CHECK: %[[C10I:.*]] = fir.convert %[[C10]] : (i32) -> index +! CHECK: %[[C0:.*]] = arith.constant 0 : index +! CHECK: %[[COMPARE:.*]] = arith.cmpi sgt, %[[C10I]], %[[C0]] : index +! CHECK: %[[CHOICE:.*]] = arith.select %[[COMPARE]], %[[C10I]], %[[C0]] : index +! CHECK: %[[ALLOCATED:.*]] = fir.allocmem !fir.array, %[[CHOICE]] {fir.must_be_heap = true, uniq_name = "_QFarray_scalar_mold_allocationEa.alloc"} +! CHECK: fir.store %[[ALLOCATED]] to %[[HEAP_A]] : !fir.ref>> +! CHECK: fir.store %[[CHOICE]] to %[[EXT0]] : !fir.ref