Files
llvm-project/clang/test/CIR/CodeGen/rtti-member-pointer.cpp
Andy Kaylor 5b938b8c03 [CIR] Fix typeinfo linkage and comdat (#192721)
We weren't properly setting the linkage on typeinfo objects, leading to
multiple definition linking error when typeinfo for a class was
referenced in multiple source files. We had the correct linkage
available in the buildTypeInfo function, but we weren't doing anything
with it. This also prevented us from hitting the diagnostic saying that
we should have set the comdat attribute for the typeinfo. This change
fixes both of those problems.
2026-04-17 14:17:21 -07:00

59 lines
4.7 KiB
C++

// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -fclangir -emit-llvm %s -o %t-cir.ll
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
struct A {
int data;
void func();
};
void throw_data_member_ptr() {
int A::*p = &A::data;
throw p;
}
// CIR-DAG: cir.global {{.*}} @_ZTS1A = #cir.const_array<"1A" : !cir.array<!s8i x 2>, trailing_zeros> : !cir.array<!s8i x 3>
// CIR-DAG: cir.global {{.*}} @_ZTI1A = #cir.typeinfo<{#cir.global_view<@_ZTVN10__cxxabiv117__class_type_infoE, [2 : i32]> : !cir.ptr<!u8i>, #cir.global_view<@_ZTS1A> : !cir.ptr<!u8i>}>
// CIR-DAG: cir.global {{.*}} @_ZTSM1Ai = #cir.const_array<"M1Ai" : !cir.array<!s8i x 4>, trailing_zeros> : !cir.array<!s8i x 5>
// CIR-DAG: cir.global {{.*}} @_ZTIM1Ai = #cir.typeinfo<{#cir.global_view<@_ZTVN10__cxxabiv129__pointer_to_member_type_infoE, [2 : i32]> : !cir.ptr<!u8i>, #cir.global_view<@_ZTSM1Ai> : !cir.ptr<!u8i>, #cir.int<0> : !u32i, #cir.global_view<@_ZTIi> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI1A> : !cir.ptr<!u8i>}>
// CIR-DAG: cir.throw %{{.*}} : !cir.ptr<!s64i>, @_ZTIM1Ai
// LLVM-DAG: @_ZTSM1Ai = linkonce_odr global [5 x i8] c"M1Ai\00", comdat
// LLVM-DAG: @_ZTS1A = linkonce_odr global [3 x i8] c"1A\00", comdat
// LLVM-DAG: @_ZTI1A = linkonce_odr constant { ptr, ptr } { ptr getelementptr (i8, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 16), ptr @_ZTS1A }, comdat
// LLVM-DAG: @_ZTIM1Ai = linkonce_odr constant { ptr, ptr, i32, ptr, ptr } { ptr getelementptr (i8, ptr @_ZTVN10__cxxabiv129__pointer_to_member_type_infoE, i64 16), ptr @_ZTSM1Ai, i32 0, ptr @_ZTIi, ptr @_ZTI1A }, comdat
// LLVM-DAG: call void @__cxa_throw(ptr %{{.*}}, ptr @_ZTIM1Ai, ptr null)
// OGCG-DAG: @_ZTSM1Ai = linkonce_odr constant [5 x i8] c"M1Ai\00", comdat
// OGCG-DAG: @_ZTS1A = linkonce_odr constant [3 x i8] c"1A\00", comdat
// OGCG-DAG: @_ZTI1A = linkonce_odr constant { ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr @_ZTS1A }, comdat
// OGCG-DAG: @_ZTIM1Ai = linkonce_odr constant { ptr, ptr, i32, ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv129__pointer_to_member_type_infoE, i64 2), ptr @_ZTSM1Ai, i32 0, ptr @_ZTIi, ptr @_ZTI1A }, comdat
// OGCG-DAG: call void @__cxa_throw(ptr %{{.*}}, ptr @_ZTIM1Ai, ptr null)
void throw_member_fn_ptr() {
void (A::*p)() = &A::func;
throw p;
}
// CIR-DAG: cir.global {{.*}} @_ZTSM1AFvvE = #cir.const_array<"M1AFvvE" : !cir.array<!s8i x 7>, trailing_zeros> : !cir.array<!s8i x 8>
// CIR-DAG: cir.global {{.*}} @_ZTSFvvE = #cir.const_array<"FvvE" : !cir.array<!s8i x 4>, trailing_zeros> : !cir.array<!s8i x 5>
// CIR-DAG: cir.global {{.*}} @_ZTIFvvE = #cir.typeinfo<{#cir.global_view<@_ZTVN10__cxxabiv120__function_type_infoE, [2 : i32]> : !cir.ptr<!u8i>, #cir.global_view<@_ZTSFvvE> : !cir.ptr<!u8i>}>
// CIR-DAG: cir.global {{.*}} @_ZTIM1AFvvE = #cir.typeinfo<{#cir.global_view<@_ZTVN10__cxxabiv129__pointer_to_member_type_infoE, [2 : i32]> : !cir.ptr<!u8i>, #cir.global_view<@_ZTSM1AFvvE> : !cir.ptr<!u8i>, #cir.int<0> : !u32i, #cir.global_view<@_ZTIFvvE> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI1A> : !cir.ptr<!u8i>}>
// LLVM-DAG: @_ZTSM1AFvvE = linkonce_odr global [8 x i8] c"M1AFvvE\00", comdat
// LLVM-DAG: @_ZTSFvvE = linkonce_odr global [5 x i8] c"FvvE\00", comdat
// LLVM-DAG: @_ZTIFvvE = linkonce_odr constant { ptr, ptr } { ptr getelementptr (i8, ptr @_ZTVN10__cxxabiv120__function_type_infoE, i64 16), ptr @_ZTSFvvE }, comdat
// LLVM-DAG: @_ZTIM1AFvvE = linkonce_odr constant { ptr, ptr, i32, ptr, ptr } { ptr getelementptr (i8, ptr @_ZTVN10__cxxabiv129__pointer_to_member_type_infoE, i64 16), ptr @_ZTSM1AFvvE, i32 0, ptr @_ZTIFvvE, ptr @_ZTI1A }, comdat
// LLVM-DAG: call void @__cxa_throw(ptr %{{.*}}, ptr @_ZTIM1AFvvE, ptr null)
// OGCG-DAG: @_ZTSM1AFvvE = linkonce_odr constant [8 x i8] c"M1AFvvE\00", comdat
// OGCG-DAG: @_ZTSFvvE = linkonce_odr constant [5 x i8] c"FvvE\00", comdat
// OGCG-DAG: @_ZTIFvvE = linkonce_odr constant { ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__function_type_infoE, i64 2), ptr @_ZTSFvvE }, comdat
// OGCG-DAG: @_ZTIM1AFvvE = linkonce_odr constant { ptr, ptr, i32, ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv129__pointer_to_member_type_infoE, i64 2), ptr @_ZTSM1AFvvE, i32 0, ptr @_ZTIFvvE, ptr @_ZTI1A }, comdat
// OGCG-DAG: call void @__cxa_throw(ptr %{{.*}}, ptr @_ZTIM1AFvvE, ptr null)