xref: /aosp_15_r20/external/clang/test/CodeGenCXX/static-destructor.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -o - | FileCheck --check-prefix=X86 %s
2*67e74705SXin Li // RUN: %clang_cc1 %s -triple=wasm32 -emit-llvm -o - | FileCheck --check-prefix=WASM %s
3*67e74705SXin Li // RUN: %clang_cc1 %s -triple=armv7-apple-darwin9 -emit-llvm -o - | FileCheck --check-prefix=ARM %s
4*67e74705SXin Li 
5*67e74705SXin Li // Test that destructors are not passed directly to __cxa_atexit when their
6*67e74705SXin Li // signatures do not match the type of its first argument.
7*67e74705SXin Li // e.g. ARM and WebAssembly have destructors that return this instead of void.
8*67e74705SXin Li 
9*67e74705SXin Li 
10*67e74705SXin Li class Foo {
11*67e74705SXin Li  public:
~Foo()12*67e74705SXin Li   ~Foo() {
13*67e74705SXin Li   }
14*67e74705SXin Li };
15*67e74705SXin Li 
16*67e74705SXin Li Foo global;
17*67e74705SXin Li 
18*67e74705SXin Li // X86 destructors have void return, and are registered directly with __cxa_atexit.
19*67e74705SXin Li // X86: define internal void @__cxx_global_var_init()
20*67e74705SXin Li // X86:   call i32 @__cxa_atexit(void (i8*)* bitcast (void (%class.Foo*)* @_ZN3FooD1Ev to void (i8*)*), i8* getelementptr inbounds (%class.Foo, %class.Foo* @global, i32 0, i32 0), i8* @__dso_handle)
21*67e74705SXin Li 
22*67e74705SXin Li // ARM destructors return this, but can be registered directly with __cxa_atexit
23*67e74705SXin Li // because the calling conventions tolerate the mismatch.
24*67e74705SXin Li // ARM: define internal void @__cxx_global_var_init()
25*67e74705SXin Li // ARM:   call i32 @__cxa_atexit(void (i8*)* bitcast (%class.Foo* (%class.Foo*)* @_ZN3FooD1Ev to void (i8*)*), i8* getelementptr inbounds (%class.Foo, %class.Foo* @global, i32 0, i32 0), i8* @__dso_handle)
26*67e74705SXin Li 
27*67e74705SXin Li // Wasm destructors return this, and use a wrapper function, which is registered
28*67e74705SXin Li // with __cxa_atexit.
29*67e74705SXin Li // WASM: define internal void @__cxx_global_var_init()
30*67e74705SXin Li // WASM: call i32 @__cxa_atexit(void (i8*)* @__cxx_global_array_dtor, i8* null, i8* @__dso_handle)
31*67e74705SXin Li 
32*67e74705SXin Li // WASM: define internal void @__cxx_global_array_dtor(i8*)
33*67e74705SXin Li // WASM: %call = call %class.Foo* @_ZN3FooD1Ev(%class.Foo* @global)
34