diff options
Diffstat (limited to 'test/CodeGenCXX/const-init-cxx11.cpp')
-rw-r--r-- | test/CodeGenCXX/const-init-cxx11.cpp | 110 |
1 files changed, 104 insertions, 6 deletions
diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp index 833adba..d21e911 100644 --- a/test/CodeGenCXX/const-init-cxx11.cpp +++ b/test/CodeGenCXX/const-init-cxx11.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s -std=c++11 | FileCheck %s +// RUN: not %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s -std=c++11 | FileCheck %s // FIXME: The padding in all these objects should be zero-initialized. namespace StructUnion { @@ -224,12 +224,50 @@ namespace LiteralReference { 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 + + // This creates a non-const temporary and binds a reference to it. + // CHECK: @[[TEMP:.*]] = private global {{.*}} { i32 5 }, align 4 + // CHECK: @_ZN16LiteralReference3litE = constant {{.*}} @[[TEMP]], align 8 const Lit &lit = Lit(); + + // This creates a const temporary as part of the reference initialization. + // CHECK: @[[TEMP:.*]] = private constant {{.*}} { i32 5 }, align 4 + // CHECK: @_ZN16LiteralReference4lit2E = constant {{.*}} @[[TEMP]], align 8 + const Lit &lit2 = {}; + + struct A { int &&r1; const int &&r2; }; + struct B { A &&a1; const A &&a2; }; + B b = { { 0, 1 }, { 2, 3 } }; + // CHECK: @[[TEMP0:.*]] = private global i32 0, align 4 + // CHECK: @[[TEMP1:.*]] = private constant i32 1, align 4 + // CHECK: @[[TEMPA1:.*]] = private global {{.*}} { i32* @[[TEMP0]], i32* @[[TEMP1]] }, align 8 + // CHECK: @[[TEMP2:.*]] = private global i32 2, align 4 + // CHECK: @[[TEMP3:.*]] = private constant i32 3, align 4 + // CHECK: @[[TEMPA2:.*]] = private constant {{.*}} { i32* @[[TEMP2]], i32* @[[TEMP3]] }, align 8 + // CHECK: @_ZN16LiteralReference1bE = global {{.*}} { {{.*}}* @[[TEMPA1]], {{.*}}* @[[TEMPA2]] }, align 8 + + struct Subobj { + int a, b, c; + }; + // CHECK: @[[TEMP:.*]] = private global {{.*}} { i32 1, i32 2, i32 3 }, align 4 + // CHECK: @_ZN16LiteralReference2soE = constant {{.*}} (i8* getelementptr {{.*}} @[[TEMP]]{{.*}}, i64 4) + constexpr int &&so = Subobj{ 1, 2, 3 }.b; + + struct Dummy { int padding; }; + struct Derived : Dummy, Subobj { + constexpr Derived() : Dummy{200}, Subobj{4, 5, 6} {} + }; + using ConstDerived = const Derived; + // CHECK: @[[TEMPCOMMA:.*]] = private constant {{.*}} { i32 200, i32 4, i32 5, i32 6 } + // CHECK: @_ZN16LiteralReference5commaE = constant {{.*}} getelementptr {{.*}} @[[TEMPCOMMA]]{{.*}}, i64 8) + constexpr const int &comma = (1, (2, ConstDerived{}).b); + + // CHECK: @[[TEMPDERIVED:.*]] = private global {{.*}} { i32 200, i32 4, i32 5, i32 6 } + // CHECK: @_ZN16LiteralReference4baseE = constant {{.*}} getelementptr {{.*}} @[[TEMPDERIVED]]{{.*}}, i64 4) + constexpr Subobj &&base = Derived{}; + + // CHECK: @_ZN16LiteralReference7derivedE = constant {{.*}} @[[TEMPDERIVED]] + constexpr Derived &derived = static_cast<Derived&>(base); } namespace NonLiteralConstexpr { @@ -330,6 +368,32 @@ namespace PR13273 { extern const S s {}; } +namespace ArrayTemporary { + struct A { const int (&x)[3]; }; + struct B { const A (&x)[2]; }; + // CHECK: @[[A1:_ZGRN14ArrayTemporary1bE.*]] = private constant [3 x i32] [i32 1, i32 2, i32 3] + // CHECK: @[[A2:_ZGRN14ArrayTemporary1bE.*]] = private constant [3 x i32] [i32 4, i32 5, i32 6] + // CHECK: @[[ARR:_ZGRN14ArrayTemporary1bE.*]] = private constant [2 x {{.*}}] [{{.*}} { [3 x i32]* @[[A1]] }, {{.*}} { [3 x i32]* @[[A2]] }] + // CHECK: @[[B:_ZGRN14ArrayTemporary1bE.*]] = private global {{.*}} { [2 x {{.*}}]* @[[ARR]] } + // CHECK: @_ZN14ArrayTemporary1bE = constant {{.*}}* @[[B]] + B &&b = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } }; +} + +namespace UnemittedTemporaryDecl { + constexpr int &&ref = 0; + extern constexpr int &ref2 = ref; + // CHECK: @_ZGRN22UnemittedTemporaryDecl3refE = private global i32 0 + + // FIXME: This declaration should not be emitted -- it isn't odr-used. + // CHECK: @_ZN22UnemittedTemporaryDecl3refE + + // CHECK: @_ZN22UnemittedTemporaryDecl4ref2E = constant i32* @_ZGRN22UnemittedTemporaryDecl3refE +} + +// CHECK: @_ZZN12LocalVarInit3aggEvE1a = internal constant {{.*}} i32 101 +// CHECK: @_ZZN12LocalVarInit4ctorEvE1a = internal constant {{.*}} i32 102 +// CHECK: @_ZZN12LocalVarInit8mutable_EvE1a = private unnamed_addr constant {{.*}} i32 103 + // Constant initialization tests go before this point, // dynamic initialization tests go after. @@ -356,6 +420,40 @@ namespace PR13273 { // CHECK-NOT: } // CHECK: call {{.*}}cxa_atexit{{.*}}@_ZN19NonLiteralConstexpr4BothD1Ev +// PR12848: Don't emit dynamic initializers for local constexpr variables. +namespace LocalVarInit { + constexpr int f(int n) { return n; } + struct Agg { int k; }; + struct Ctor { constexpr Ctor(int n) : k(n) {} int k; }; + struct Mutable { constexpr Mutable(int n) : k(n) {} mutable int k; }; + + // CHECK: define {{.*}} @_ZN12LocalVarInit6scalarEv + // CHECK-NOT: call + // CHECK: store i32 100, + // CHECK-NOT: call + // CHECK: ret i32 100 + int scalar() { constexpr int a = { f(100) }; return a; } + + // CHECK: define {{.*}} @_ZN12LocalVarInit3aggEv + // CHECK-NOT: call + // CHECK: ret i32 101 + int agg() { constexpr Agg a = { f(101) }; return a.k; } + + // CHECK: define {{.*}} @_ZN12LocalVarInit4ctorEv + // CHECK-NOT: call + // CHECK: ret i32 102 + int ctor() { constexpr Ctor a = { f(102) }; return a.k; } + + // CHECK: define {{.*}} @_ZN12LocalVarInit8mutable_Ev + // CHECK-NOT: call + // CHECK: call {{.*}}memcpy{{.*}} @_ZZN12LocalVarInit8mutable_EvE1a + // CHECK-NOT: call + // Can't fold return value due to 'mutable'. + // CHECK-NOT: ret i32 103 + // CHECK: } + int mutable_() { constexpr Mutable a = { f(103) }; return a.k; } +} + 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;})); } |