Skip to content

Commit 8ea361b

Browse files
committed
[flang] handle allocation of zero-sized objects
1 parent 1c6422c commit 8ea361b

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,9 +1119,19 @@ struct AllocMemOpConversion : public fir::FIROpConversion<fir::AllocMemOp> {
11191119
mlir::Value size = genTypeSizeInBytes(loc, ity, rewriter, llvmObjectTy);
11201120
if (auto scaleSize = genAllocationScaleSize(heap, ity, rewriter))
11211121
size = rewriter.create<mlir::LLVM::MulOp>(loc, ity, size, scaleSize);
1122-
for (mlir::Value opnd : adaptor.getOperands())
1123-
size = rewriter.create<mlir::LLVM::MulOp>(
1124-
loc, ity, size, integerCast(loc, rewriter, ity, opnd));
1122+
for (mlir::Value opnd : adaptor.getOperands()) {
1123+
auto arg = integerCast(loc, rewriter, ity, opnd);
1124+
auto val = fir::getIntIfConstant(arg);
1125+
if (val && *val == 0) {
1126+
// As the return value of malloc(0) is implementation defined, allocate
1127+
// one byte to ensure the allocation status being true. This behavior
1128+
// aligns to what the runtime has.
1129+
size = genConstantIndex(loc, ity, rewriter, 1);
1130+
break;
1131+
} else {
1132+
size = rewriter.create<mlir::LLVM::MulOp>(loc, ity, size, arg);
1133+
}
1134+
}
11251135
auto mallocTyWidth = lowerTy().getIndexTypeBitwidth();
11261136
auto mallocTy =
11271137
mlir::IntegerType::get(rewriter.getContext(), mallocTyWidth);

flang/test/Lower/zero-size2.f90

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
! RUN: %flang_fc1 -emit-llvm -o - %s | FileCheck %s
2+
3+
subroutine sub1()
4+
integer, allocatable :: arr(:)
5+
allocate(arr(0))
6+
! CHECK-LABEL: @sub1_
7+
! CHECK: %[[p:.*]] = call ptr @malloc(i64 1)
8+
end
9+
10+
subroutine sub2()
11+
real, allocatable :: arr(:,:)
12+
allocate(arr(10,0))
13+
! CHECK-LABEL: @sub2_
14+
! CHECK: %[[p:.*]] = call ptr @malloc(i64 1)
15+
end
16+
17+
subroutine sub3(i)
18+
integer :: i
19+
real, allocatable :: arr(:,:)
20+
allocate(arr(i,0))
21+
! CHECK-LABEL: @sub3_
22+
! CHECK: %[[p:.*]] = call ptr @malloc(i64 1)
23+
end
24+
25+
subroutine sub4()
26+
character(:), allocatable :: c
27+
allocate(character(0)::c)
28+
! CHECK-LABEL: @sub4_
29+
! CHECK: %[[p:.*]] = call ptr @malloc(i64 1)
30+
end
31+
32+
subroutine sub5()
33+
character(:), allocatable :: c(:)
34+
allocate(character(5)::c(0))
35+
! CHECK-LABEL: @sub5_
36+
! CHECK: %[[p:.*]] = call ptr @malloc(i64 1)
37+
end

0 commit comments

Comments
 (0)