aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/const-init-cxx11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX/const-init-cxx11.cpp')
-rw-r--r--test/CodeGenCXX/const-init-cxx11.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp
index 6f13faa2fc..70fa2984fa 100644
--- a/test/CodeGenCXX/const-init-cxx11.cpp
+++ b/test/CodeGenCXX/const-init-cxx11.cpp
@@ -185,9 +185,93 @@ namespace MemberPtr {
extern constexpr void (B2::*b2m)() = (void(B2::*)())&D::m;
}
+namespace LiteralReference {
+ struct Lit {
+ constexpr Lit() : n(5) {}
+ int n;
+ };
+ // FIXME: This should have static initialization, but we do not implement
+ // that yet. For now, just check that we don't set the (pointer) value of
+ // the reference to 5!
+ //
+ // CHECK: @_ZN16LiteralReference3litE = global {{.*}} null
+ const Lit &lit = Lit();
+}
+
+namespace NonLiteralConstexpr {
+ constexpr int factorial(int n) {
+ return n ? factorial(n-1) * n : 1;
+ }
+ extern void f(int *p);
+
+ struct NonTrivialDtor {
+ constexpr NonTrivialDtor() : n(factorial(5)), p(&n) {}
+ ~NonTrivialDtor() {
+ f(p);
+ }
+
+ int n;
+ int *p;
+ };
+ static_assert(!__is_literal(NonTrivialDtor), "");
+ // CHECK: @_ZN19NonLiteralConstexpr3ntdE = global {{.*}} { i32 120, i32* getelementptr
+ NonTrivialDtor ntd;
+
+ struct VolatileMember {
+ constexpr VolatileMember() : n(5) {}
+ volatile int n;
+ };
+ static_assert(!__is_literal(VolatileMember), "");
+ // CHECK: @_ZN19NonLiteralConstexpr2vmE = global {{.*}} { i32 5 }
+ VolatileMember vm;
+
+ struct Both {
+ constexpr Both() : n(10) {}
+ ~Both();
+ volatile int n;
+ };
+ // CHECK: @_ZN19NonLiteralConstexpr1bE = global {{.*}} { i32 10 }
+ Both b;
+
+ void StaticVars() {
+ // CHECK: @_ZZN19NonLiteralConstexpr10StaticVarsEvE3ntd = {{.*}} { i32 120, i32* getelementptr {{.*}}
+ // CHECK: @_ZGVZN19NonLiteralConstexpr10StaticVarsEvE3ntd =
+ static NonTrivialDtor ntd;
+ // CHECK: @_ZZN19NonLiteralConstexpr10StaticVarsEvE2vm = {{.*}} { i32 5 }
+ // CHECK-NOT: @_ZGVZN19NonLiteralConstexpr10StaticVarsEvE2vm =
+ static VolatileMember vm;
+ // CHECK: @_ZZN19NonLiteralConstexpr10StaticVarsEvE1b = {{.*}} { i32 10 }
+ // CHECK: @_ZGVZN19NonLiteralConstexpr10StaticVarsEvE1b =
+ static Both b;
+ }
+}
+
// Constant initialization tests go before this point,
// dynamic initialization tests go after.
+// We must emit a constant initializer for NonLiteralConstexpr::ntd, but also
+// emit an initializer to register its destructor.
+// CHECK: define {{.*}}cxx_global_var_init{{.*}}
+// CHECK-NOT: NonLiteralConstexpr
+// CHECK: call {{.*}}cxa_atexit{{.*}} @_ZN19NonLiteralConstexpr14NonTrivialDtorD1Ev {{.*}} @_ZN19NonLiteralConstexpr3ntdE
+// CHECK-NEXT: ret void
+
+// We don't need to emit any dynamic initialization for NonLiteralConstexpr::vm.
+// CHECK-NOT: NonLiteralConstexpr2vm
+
+// We must emit a constant initializer for NonLiteralConstexpr::b, but also
+// emit an initializer to register its destructor.
+// CHECK: define {{.*}}cxx_global_var_init{{.*}}
+// CHECK-NOT: NonLiteralConstexpr
+// CHECK: call {{.*}}cxa_atexit{{.*}} @_ZN19NonLiteralConstexpr4BothD1Ev {{.*}} @_ZN19NonLiteralConstexpr1bE
+// CHECK-NEXT: ret void
+
+// CHECK: define {{.*}}NonLiteralConstexpr10StaticVars
+// CHECK-NOT: }
+// CHECK: call {{.*}}cxa_atexit{{.*}}@_ZN19NonLiteralConstexpr14NonTrivialDtorD1Ev
+// CHECK-NOT: }
+// CHECK: call {{.*}}cxa_atexit{{.*}}@_ZN19NonLiteralConstexpr4BothD1Ev
+
namespace CrossFuncLabelDiff {
// Make sure we refuse to constant-fold the variable b.
constexpr long a(bool x) { return x ? 0 : (long)&&lbl + (0 && ({lbl: 0;})); }