aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/constant-expression-cxx11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX/constant-expression-cxx11.cpp')
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp108
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
+