llvm-project/clang/test/CodeGenCXX/const-init-cxx2a.cpp
Hans Wennborg 7a85aa918c Emit const globals with constexpr destructor as constant LLVM values
This follows 2b4fa53 which made Clang not emit destructor calls for such
objects. However, they would still not get emitted as constants since
CodeGenModule::isTypeConstant() returns false if the destructor is
constexpr. This change adds a param to make isTypeConstant() ignore the
dtor, allowing the caller to check it instead.

Fixes Issue #61212

Differential revision: https://reviews.llvm.org/D145369
2023-03-16 11:02:27 +01:00

59 lines
1.4 KiB
C++

// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -std=c++2a | FileCheck %s --implicit-check-not=cxx_global_var_init --implicit-check-not=cxa_atexit
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-pch -o %t.pch %s -std=c++2a
// RUN: %clang_cc1 -triple x86_64-linux-gnu -include-pch %t.pch -x c++ /dev/null -emit-llvm -o - -std=c++2a | FileCheck %s --implicit-check-not=cxx_global_var_init --implicit-check-not=cxa_atexit
// CHECK: @a ={{.*}} global i32 123,
int a = (delete new int, 123);
struct B {
constexpr B() {}
constexpr ~B() { n *= 5; }
int n = 123;
};
// CHECK: @b ={{.*}} constant {{.*}} i32 123
extern constexpr B b = B();
// CHECK: @_ZL1c = internal constant {{.*}} i32 123
const B c;
int use_c() { return c.n; }
struct D {
int n;
constexpr ~D() {}
};
D d;
// CHECK: @d ={{.*}} global {{.*}} zeroinitializer
D d_arr[3];
// CHECK: @d_arr ={{.*}} global {{.*}} zeroinitializer
thread_local D d_tl;
// CHECK: @d_tl ={{.*}} thread_local global {{.*}} zeroinitializer
// CHECK-NOT: @llvm.global_ctors
// CHECK-LABEL: define {{.*}} @_Z1fv(
void f() {
// CHECK-NOT: call
// CHECK: call {{.*}}memcpy
// CHECK-NOT: call
// CHECK: call {{.*}}memset
// CHECK-NOT: call
// CHECK: }
constexpr B b;
D d = D();
}
// CHECK-LABEL: define {{.*}} @_Z1gv(
void g() {
// CHECK-NOT: call
// CHECK-NOT: cxa_guard
// CHECK-NOT: _ZGV
// CHECK: }
static constexpr B b1;
static const B b2;
static D d;
thread_local D d_tl;
}