There was code in the CIR CXXABILowering pass that was assuming ConstArrayAttr::getElts() would return an ArrayAttr. This isn't true in the case of string constants with trailing zeros, so we had a crash in a mlir::cast<> call. The problem only appeared when a string array appeared in the same initializer as a type that required CXXABI-specific lowering, such as a member pointer. This change fixes the CXXABILowering to simply keep the existing string attribute, which is known to be legal for the purposes of that pass. Assisted-by: Cursor / claude-4.7-opus-high
30 lines
1.1 KiB
C++
30 lines
1.1 KiB
C++
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
|
|
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
|
|
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
|
|
// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
|
|
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
|
|
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
|
|
|
|
// Regression test for a CXXABILowering crash when a record that requires
|
|
// CXX-ABI lowering (because it contains a pointer-to-data-member field) also
|
|
// has a sibling char-array field initialized from a string literal.
|
|
|
|
struct B { int x; int y; };
|
|
|
|
struct S {
|
|
int B::*pm;
|
|
char buf[32];
|
|
};
|
|
|
|
const S g = { &B::y, "abc" };
|
|
|
|
const S *get() { return &g; }
|
|
|
|
// CIR: !rec_S = !cir.record<struct "S" {!s64i, !cir.array<!s8i x 32>}>
|
|
// CIR: cir.global {{.*}} @_ZL1g = #cir.const_record<{
|
|
// CIR-SAME: #cir.int<4> : !s64i,
|
|
// CIR-SAME: #cir.const_array<"abc" : !cir.array<!s8i x 3>, trailing_zeros> : !cir.array<!s8i x 32>
|
|
// CIR-SAME: }> : !rec_S
|
|
|
|
// LLVM: @_ZL1g = internal constant %struct.S { i64 4, [32 x i8] c"abc\00{{(\\00)+}}" }
|