Skip to content

Commit 05313ad

Browse files
AmrDevelopermikolaj-pirog
authored andcommitted
[CIR] ConstRecordBuilder check if attribute present before casting (llvm#164575)
Fix the crash because in `ConstRecordBuilder::build` we cast to TypedAttr then we check if it null, but in case that the result from emitter is nullptr, that cast crash, In this PR I fixed the order to check first if it not null, then casting to the TypedAttr
1 parent 5c1f54e commit 05313ad

File tree

2 files changed

+24
-13
lines changed

2 files changed

+24
-13
lines changed

clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -627,10 +627,7 @@ bool ConstRecordBuilder::applyZeroInitPadding(const ASTRecordLayout &layout,
627627
}
628628

629629
bool ConstRecordBuilder::build(InitListExpr *ile, bool allowOverwrite) {
630-
RecordDecl *rd = ile->getType()
631-
->castAs<clang::RecordType>()
632-
->getDecl()
633-
->getDefinitionOrSelf();
630+
RecordDecl *rd = ile->getType()->castAsRecordDecl();
634631
const ASTRecordLayout &layout = cgm.getASTContext().getASTRecordLayout(rd);
635632

636633
// Bail out if we have base classes. We could support these, but they only
@@ -686,17 +683,14 @@ bool ConstRecordBuilder::build(InitListExpr *ile, bool allowOverwrite) {
686683
return false;
687684
}
688685

689-
mlir::TypedAttr eltInit;
690-
if (init)
691-
eltInit = mlir::cast<mlir::TypedAttr>(
692-
emitter.tryEmitPrivateForMemory(init, field->getType()));
693-
else
694-
eltInit = mlir::cast<mlir::TypedAttr>(emitter.emitNullForMemory(
695-
cgm.getLoc(ile->getSourceRange()), field->getType()));
696-
697-
if (!eltInit)
686+
mlir::Attribute eltInitAttr =
687+
init ? emitter.tryEmitPrivateForMemory(init, field->getType())
688+
: emitter.emitNullForMemory(cgm.getLoc(ile->getSourceRange()),
689+
field->getType());
690+
if (!eltInitAttr)
698691
return false;
699692

693+
mlir::TypedAttr eltInit = mlir::cast<mlir::TypedAttr>(eltInitAttr);
700694
if (!field->isBitField()) {
701695
// Handle non-bitfield members.
702696
if (!appendField(field, layout.getFieldOffset(index), eltInit,

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,23 @@ StructWithDefaultInit swdi = {};
4040
// LLVM: @swdi = global %struct.StructWithDefaultInit { i32 2 }, align 4
4141
// OGCG: @swdi = global %struct.StructWithDefaultInit { i32 2 }, align 4
4242

43+
struct StructWithFieldInitFromConst {
44+
int a : 10;
45+
int b = a;
46+
};
47+
48+
StructWithFieldInitFromConst swfifc = {};
49+
50+
// CIR: cir.global external @swfifc = #cir.zero : !rec_anon_struct
51+
// LLVM: @swfifc = global { i8, i8, i32 } zeroinitializer, align 4
52+
// OGCG: @swfifc = global { i8, i8, i32 } zeroinitializer, align 4
53+
54+
StructWithFieldInitFromConst swfifc2 = { 2 };
55+
56+
// CIR: cir.global external @swfifc2 = #cir.const_record<{#cir.int<2> : !u8i, #cir.int<0> : !u8i, #cir.int<2> : !s32i}> : !rec_anon_struct
57+
// LLVM: @swfifc2 = global { i8, i8, i32 } { i8 2, i8 0, i32 2 }, align 4
58+
// OGCG: @swfifc2 = global { i8, i8, i32 } { i8 2, i8 0, i32 2 }, align 4
59+
4360
void init() {
4461
S s1 = {1, 2, 3};
4562
S s2 = {4, 5};

0 commit comments

Comments
 (0)