summaryrefslogtreecommitdiffstats
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.cpp110
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;})); }
OpenPOWER on IntegriCloud