Skip to content

Conversation

@AmrDeveloper
Copy link
Member

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

@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Oct 22, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 22, 2025

@llvm/pr-subscribers-clangir

@llvm/pr-subscribers-clang

Author: Amr Hesham (AmrDeveloper)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/164575.diff

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+7-13)
  • (modified) clang/test/CIR/CodeGen/struct-init.cpp (+17)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 800262aac8fa4..4d5d0bd78530a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -612,10 +612,7 @@ bool ConstRecordBuilder::applyZeroInitPadding(const ASTRecordLayout &layout, } bool ConstRecordBuilder::build(InitListExpr *ile, bool allowOverwrite) { - RecordDecl *rd = ile->getType() - ->castAs<clang::RecordType>() - ->getDecl() - ->getDefinitionOrSelf(); + RecordDecl *rd = ile->getType()->castAsRecordDecl(); const ASTRecordLayout &layout = cgm.getASTContext().getASTRecordLayout(rd); // Bail out if we have base classes. We could support these, but they only @@ -671,17 +668,14 @@ bool ConstRecordBuilder::build(InitListExpr *ile, bool allowOverwrite) { return false; } - mlir::TypedAttr eltInit; - if (init) - eltInit = mlir::cast<mlir::TypedAttr>( - emitter.tryEmitPrivateForMemory(init, field->getType())); - else - eltInit = mlir::cast<mlir::TypedAttr>(emitter.emitNullForMemory( - cgm.getLoc(ile->getSourceRange()), field->getType())); - - if (!eltInit) + mlir::Attribute eltInitAttr = + init ? emitter.tryEmitPrivateForMemory(init, field->getType()) + : emitter.emitNullForMemory(cgm.getLoc(ile->getSourceRange()), + field->getType()); + if (!eltInitAttr) return false; + mlir::TypedAttr eltInit = mlir::cast<mlir::TypedAttr>(eltInitAttr); if (!field->isBitField()) { // Handle non-bitfield members. if (!appendField(field, layout.getFieldOffset(index), eltInit, diff --git a/clang/test/CIR/CodeGen/struct-init.cpp b/clang/test/CIR/CodeGen/struct-init.cpp index cb509994d1cbf..e1e8cda6fe9fb 100644 --- a/clang/test/CIR/CodeGen/struct-init.cpp +++ b/clang/test/CIR/CodeGen/struct-init.cpp @@ -25,6 +25,23 @@ StructWithDefaultInit swdi = {}; // LLVM: @swdi = global %struct.StructWithDefaultInit { i32 2 }, align 4 // OGCG: @swdi = global %struct.StructWithDefaultInit { i32 2 }, align 4 +struct StructWithFieldInitFromConst { + int a : 10; + int b = a; +}; + +StructWithFieldInitFromConst swfifc = {}; + +// CIR: cir.global external @swfifc = #cir.zero : !rec_anon_struct +// LLVM: @swfifc = global { i8, i8, i32 } zeroinitializer, align 4 +// OGCG: @swfifc = global { i8, i8, i32 } zeroinitializer, align 4 + +StructWithFieldInitFromConst swfifc2 = { 2 }; + +// CIR: cir.global external @swfifc2 = #cir.const_record<{#cir.int<2> : !u8i, #cir.int<0> : !u8i, #cir.int<2> : !s32i}> : !rec_anon_struct +// LLVM: @swfifc2 = global { i8, i8, i32 } { i8 2, i8 0, i32 2 }, align 4 +// OGCG: @swfifc2 = global { i8, i8, i32 } { i8 2, i8 0, i32 2 }, align 4 + void init() { S s1 = {1, 2, 3}; S s2 = {4, 5}; 
Copy link
Contributor

@andykaylor andykaylor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@AmrDeveloper AmrDeveloper enabled auto-merge (squash) October 23, 2025 08:42
@AmrDeveloper AmrDeveloper merged commit 4f99111 into llvm:main Oct 23, 2025
9 of 10 checks passed
mikolaj-pirog pushed a commit to mikolaj-pirog/llvm-project that referenced this pull request Oct 23, 2025
…lvm#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
dvbuka pushed a commit to dvbuka/llvm-project that referenced this pull request Oct 27, 2025
…lvm#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
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Oct 29, 2025
…lvm#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
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 30, 2025
…lvm#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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project

3 participants