diff options
Diffstat (limited to 'test/SemaCXX/constant-expression-cxx11.cpp')
-rw-r--r-- | test/SemaCXX/constant-expression-cxx11.cpp | 108 |
1 files changed, 89 insertions, 19 deletions
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index e2b3f091f70f..581a524339e7 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -279,17 +279,17 @@ static_assert(&s.x > &s.y, "false"); // expected-error {{false}} static_assert(0 == &y, "false"); // expected-error {{false}} static_assert(0 != &y, ""); -constexpr bool n3 = 0 <= &y; // expected-error {{must be initialized by a constant expression}} -constexpr bool n4 = 0 >= &y; // expected-error {{must be initialized by a constant expression}} -constexpr bool n5 = 0 < &y; // expected-error {{must be initialized by a constant expression}} -constexpr bool n6 = 0 > &y; // expected-error {{must be initialized by a constant expression}} +constexpr bool n3 = (int*)0 <= &y; // expected-error {{must be initialized by a constant expression}} +constexpr bool n4 = (int*)0 >= &y; // expected-error {{must be initialized by a constant expression}} +constexpr bool n5 = (int*)0 < &y; // expected-error {{must be initialized by a constant expression}} +constexpr bool n6 = (int*)0 > &y; // expected-error {{must be initialized by a constant expression}} static_assert(&x == 0, "false"); // expected-error {{false}} static_assert(&x != 0, ""); -constexpr bool n9 = &x <= 0; // expected-error {{must be initialized by a constant expression}} -constexpr bool n10 = &x >= 0; // expected-error {{must be initialized by a constant expression}} -constexpr bool n11 = &x < 0; // expected-error {{must be initialized by a constant expression}} -constexpr bool n12 = &x > 0; // expected-error {{must be initialized by a constant expression}} +constexpr bool n9 = &x <= (int*)0; // expected-error {{must be initialized by a constant expression}} +constexpr bool n10 = &x >= (int*)0; // expected-error {{must be initialized by a constant expression}} +constexpr bool n11 = &x < (int*)0; // expected-error {{must be initialized by a constant expression}} +constexpr bool n12 = &x > (int*)0; // expected-error {{must be initialized by a constant expression}} static_assert(&x == &x, ""); static_assert(&x != &x, "false"); // expected-error {{false}} @@ -386,6 +386,18 @@ namespace FakeInitList { constexpr init_list_2_init_list_3_ints ils = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } }; } +namespace ConstAddedByReference { + const int &r = (0); + constexpr int n = r; + + struct A { constexpr operator int() const { return 0; }}; + struct B { constexpr operator const int() const { return 0; }}; + const int &ra = A(); + const int &rb = B(); + constexpr int na = ra; + constexpr int nb = rb; +} + } constexpr int strcmp_ce(const char *p, const char *q) { @@ -554,6 +566,21 @@ struct ArrayRVal { }; static_assert(ArrayRVal().elems[3].f() == 0, ""); +namespace CopyCtor { + struct A { + constexpr A() {} + constexpr A(const A &) {} + }; + struct B { + A a; + int arr[10]; + }; + constexpr B b{{}, {1, 2, 3, 4, 5}}; + constexpr B c = b; + static_assert(c.arr[2] == 3, ""); + static_assert(c.arr[7] == 0, ""); +} + constexpr int selfref[2][2][2] = { selfref[1][1][1] + 1, selfref[0][0][0] + 1, selfref[1][0][1] + 1, selfref[0][1][0] + 1, @@ -1156,7 +1183,7 @@ constexpr int m1b = const_cast<const int&>(n1); // expected-error {{constant exp constexpr int m2b = const_cast<const int&>(n2); // expected-error {{constant expression}} expected-note {{read of volatile object 'n2'}} struct T { int n; }; -const T t = { 42 }; // expected-note {{declared here}} +const T t = { 42 }; constexpr int f(volatile int &&r) { return r; // expected-note {{read of volatile-qualified type 'volatile int'}} @@ -1168,7 +1195,7 @@ struct S { int j : f(0); // expected-error {{constant expression}} expected-note {{in call to 'f(0)'}} int k : g(0); // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'g(0)'}} int l : n3; // expected-error {{constant expression}} expected-note {{read of non-const variable}} - int m : t.n; // expected-error {{constant expression}} expected-note {{read of non-constexpr variable}} + int m : t.n; // expected-warning{{width of bit-field 'm' (42 bits)}} expected-warning{{expression is not an integral constant expression}} expected-note{{read of non-constexpr variable 't' is not allowed}} }; } @@ -1467,13 +1494,26 @@ namespace VLASizeof { } namespace CompoundLiteral { - // FIXME: - // We don't model the semantics of this correctly: the compound literal is - // represented as a prvalue in the AST, but actually behaves like an lvalue. - // We treat the compound literal as a temporary and refuse to produce a - // pointer to it. This is OK: we're not required to treat this as a constant - // in C++, and in C we model compound literals as lvalues. - constexpr int *p = (int*)(int[1]){0}; // expected-warning {{C99}} expected-error {{constant expression}} expected-note 2{{temporary}} + // Matching GCC, file-scope array compound literals initialized by constants + // are lifetime-extended. + constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}} + static_assert(*p == 3, ""); + static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}} + + // Other kinds are not. + struct X { int a[2]; }; + constexpr int *n = (X){1, 2}.a; // expected-warning {{C99}} expected-warning {{temporary array}} + // expected-error@-1 {{constant expression}} + // expected-note@-2 {{pointer to subobject of temporary}} + // expected-note@-3 {{temporary created here}} + + void f() { + static constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}} + // expected-error@-1 {{constant expression}} + // expected-note@-2 {{pointer to subobject of temporary}} + // expected-note@-3 {{temporary created here}} + static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}} + } } namespace Vector { @@ -1862,8 +1902,8 @@ namespace ZeroSizeTypes { namespace BadDefaultInit { template<int N> struct X { static const int n = N; }; - struct A { - int k = // expected-error {{cannot use defaulted default constructor of 'A' within the class outside of member functions because 'k' has an initializer}} + struct A { // expected-error {{default member initializer for 'k' needed within definition of enclosing class}} + int k = // expected-note {{default member initializer declared here}} X<A().k>::n; // expected-error {{not a constant expression}} expected-note {{implicit default constructor for 'BadDefaultInit::A' first required here}} }; @@ -2066,3 +2106,33 @@ namespace InheritedCtor { constexpr Z z(1); static_assert(z.w == 1 && z.x == 2 && z.y == 3 && z.z == 4, ""); } + + +namespace PR28366 { +namespace ns1 { + +void f(char c) { //expected-note2{{declared here}} + struct X { + static constexpr char f() { //expected-error{{never produces a constant expression}} + return c; //expected-error{{reference to local}} expected-note{{non-const variable}} + } + }; + int I = X::f(); +} + +void g() { + const int c = 'c'; + static const int d = 'd'; + struct X { + static constexpr int f() { + return c + d; + } + }; + static_assert(X::f() == 'c' + 'd',""); +} + + +} // end ns1 + +} //end ns PR28366 + |