Skip to content

Commit 4ac7cd1

Browse files
bruteforceboylanza
authored andcommitted
[CIR][CodeGen] Fix array initialization in CIRGenExprAgg (#852)
Mistakenly closed #850 #850 (review) This PR fixes array initialization for expression arguments. Consider the following code snippet `test.c`: ``` typedef struct { int a; int b[2]; } A; int bar() { return 42; } void foo() { A a = {bar(), {}}; } ``` When ran with `bin/clang test.c -Xclang -fclangir -Xclang -emit-cir -S -o -`, It produces the following error: ``` ~/clangir/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp:483: void {anonymous}::AggExprEmitter::buildArrayInit(cir::Address, mlir::cir::ArrayType, clang::QualType, clang::Expr*, llvm::ArrayRef<clang::Expr*>, clang::Expr*): Assertion `NumInitElements != 0' failed. ``` The error can be traced back to `CIRGenExprAgg.cpp`, and the fix is simple. It is possible to have an empty array initialization as an expression argument!
1 parent 4e66034 commit 4ac7cd1

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,6 @@ void AggExprEmitter::buildArrayInit(Address DestPtr, mlir::cir::ArrayType AType,
480480
uint64_t NumInitElements = Args.size();
481481

482482
uint64_t NumArrayElements = AType.getSize();
483-
assert(NumInitElements != 0 && "expected at least one initializaed value");
484483
assert(NumInitElements <= NumArrayElements);
485484

486485
QualType elementType =

clang/test/CIR/CodeGen/array-init.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s
3+
4+
typedef struct {
5+
int a;
6+
int b[2];
7+
} A;
8+
9+
int bar() {
10+
return 42;
11+
}
12+
13+
void foo() {
14+
A a = {bar(), {}};
15+
}
16+
// CHECK: %[[VAL_0:.*]] = cir.alloca !ty_A, !cir.ptr<!ty_A>, ["a", init]
17+
// CHECK: %[[VAL_1:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["arrayinit.temp", init]
18+
// CHECK: %[[VAL_2:.*]] = cir.get_member %[[VAL_0]][0] {name = "a"} : !cir.ptr<!ty_A> -> !cir.ptr<!s32i>
19+
// CHECK: %[[VAL_3:.*]] = cir.call @_Z3barv() : () -> !s32i
20+
// CHECK: cir.store %[[VAL_3]], %[[VAL_2]] : !s32i, !cir.ptr<!s32i>
21+
// CHECK: %[[VAL_4:.*]] = cir.get_member %[[VAL_0]][1] {name = "b"} : !cir.ptr<!ty_A> -> !cir.ptr<!cir.array<!s32i x 2>>
22+
// CHECK: %[[VAL_5:.*]] = cir.cast(array_to_ptrdecay, %[[VAL_4]] : !cir.ptr<!cir.array<!s32i x 2>>), !cir.ptr<!s32i>
23+
// CHECK: cir.store %[[VAL_5]], %[[VAL_1]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
24+
// CHECK: %[[VAL_6:.*]] = cir.const #cir.int<2> : !s64i
25+
// CHECK: %[[VAL_7:.*]] = cir.ptr_stride(%[[VAL_5]] : !cir.ptr<!s32i>, %[[VAL_6]] : !s64i), !cir.ptr<!s32i>
26+
// CHECK: cir.do {
27+
// CHECK: %[[VAL_8:.*]] = cir.load %[[VAL_1]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
28+
// CHECK: %[[VAL_9:.*]] = cir.const #cir.int<0> : !s32i
29+
// CHECK: cir.store %[[VAL_9]], %[[VAL_8]] : !s32i, !cir.ptr<!s32i>
30+
// CHECK: %[[VAL_10:.*]] = cir.const #cir.int<1> : !s64i
31+
// CHECK: %[[VAL_11:.*]] = cir.ptr_stride(%[[VAL_8]] : !cir.ptr<!s32i>, %[[VAL_10]] : !s64i), !cir.ptr<!s32i>
32+
// CHECK: cir.store %[[VAL_11]], %[[VAL_1]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
33+
// CHECK: cir.yield
34+
// CHECK: } while {
35+
// CHECK: %[[VAL_8:.*]] = cir.load %[[VAL_1]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
36+
// CHECK: %[[VAL_9:.*]] = cir.cmp(ne, %[[VAL_8]], %[[VAL_7]]) : !cir.ptr<!s32i>, !cir.bool
37+
// CHECK: cir.condition(%[[VAL_9]])
38+
// CHECK: }

0 commit comments

Comments
 (0)