diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/SemaCXX/constant-expression-cxx11.cpp | 10 | ||||
-rw-r--r-- | test/SemaCXX/constant-expression-cxx1y.cpp | 157 | ||||
-rw-r--r-- | test/SemaCXX/constexpr-printing.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/constexpr-value-init.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/i-c-e-cxx.cpp | 2 |
5 files changed, 165 insertions, 8 deletions
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index b8f57b6c64..b44bb8c907 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -304,16 +304,16 @@ struct Str { expected-note {{reinterpret_cast is not allowed in a constant expression}} int c : (S*)(long)(sptr) == (S*)(long)(sptr); // \ expected-warning {{not an integral constant expression}} \ - expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}} + expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} int d : (S*)(42) == (S*)(42); // \ expected-warning {{not an integral constant expression}} \ - expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}} + expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} int e : (Str*)(sptr) == (Str*)(sptr); // \ expected-warning {{not an integral constant expression}} \ - expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}} + expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} int f : &(U&)(*sptr) == &(U&)(*sptr); // \ expected-warning {{not an integral constant expression}} \ - expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}} + expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} int g : (S*)(void*)(sptr) == sptr; // \ expected-warning {{not an integral constant expression}} \ expected-note {{cast from 'void *' is not allowed in a constant expression}} @@ -362,7 +362,7 @@ constexpr char c0 = "nought index"[0]; constexpr char c1 = "nice index"[10]; constexpr char c2 = "nasty index"[12]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is past the end}} expected-note {{read of dereferenced one-past-the-end pointer}} constexpr char c3 = "negative index"[-1]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is before the beginning}} expected-note {{cannot refer to element -1 of array of 15 elements}} -constexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}} expected-note {{cast which performs the conversions of a reinterpret_cast}} +constexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}} expected-note {{cast that performs the conversions of a reinterpret_cast}} constexpr const char *p = "test" + 2; static_assert(*p == 's', ""); diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp index dab2496ed1..543c7cffdb 100644 --- a/test/SemaCXX/constant-expression-cxx1y.cpp +++ b/test/SemaCXX/constant-expression-cxx1y.cpp @@ -124,3 +124,160 @@ constexpr int namespace_alias() { namespace N = NS; return N::n; } + +namespace assign { + constexpr int a = 0; + const int b = 0; + int c = 0; // expected-note 2{{here}} + + constexpr void set(const int &a, int b) { + const_cast<int&>(a) = b; // expected-note 2{{constant expression cannot modify an object that is visible outside that expression}} + } + constexpr int wrap(int a, int b) { + set(a, b); + return a; + } + + static_assert((set(a, 1), a) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(a, 1)'}} + static_assert((set(b, 1), b) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(b, 1)'}} + static_assert((set(c, 1), c) == 1, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}} + + static_assert(wrap(a, 1) == 1, ""); + static_assert(wrap(b, 1) == 1, ""); + static_assert(wrap(c, 1) == 1, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}} +} + +namespace string_assign { + template<typename T> + constexpr void swap(T &a, T &b) { + T tmp = a; + a = b; + b = tmp; + } + template<typename Iterator> + constexpr void reverse(Iterator begin, Iterator end) { +#if 0 // FIXME: once implementation is complete... + while (begin != end && begin != --end) + swap(*begin++, *end); +#else + if (begin != end) { + end = end - 1; + if (begin == end) + return; + swap(*begin, *end); + begin = begin + 1; + reverse(begin, end); + } +#endif + } + template<typename Iterator1, typename Iterator2> + constexpr bool equal(Iterator1 a, Iterator1 ae, Iterator2 b, Iterator2 be) { +#if 0 // FIXME: once implementation is complete... + while (a != ae && b != be) { + if (*a != *b) + return false; + ++a, ++b; + } +#else + if (a != ae && b != be) { + if (*a != *b) + return false; + a = a + 1; + b = b + 1; + return equal(a, ae, b, be); + } +#endif + return a == ae && b == be; + } + constexpr bool test1(int n) { + char stuff[100] = "foobarfoo"; + const char stuff2[100] = "oofraboof"; + reverse(stuff, stuff + n); // expected-note {{cannot refer to element 101 of array of 100 elements}} + return equal(stuff, stuff + n, stuff2, stuff2 + n); + } + static_assert(!test1(1), ""); + static_assert(test1(3), ""); + static_assert(!test1(6), ""); + static_assert(test1(9), ""); + static_assert(!test1(100), ""); + static_assert(!test1(101), ""); // expected-error {{constant expression}} expected-note {{in call to 'test1(101)'}} + + // FIXME: We should be able to reject this before it's called + constexpr void f() { + char foo[10] = { "z" }; // expected-note {{here}} + foo[10] = 'x'; // expected-warning {{past the end}} expected-note {{assignment to dereferenced one-past-the-end pointer}} + } + constexpr int k = (f(), 0); // expected-error {{constant expression}} expected-note {{in call}} +} + +namespace array_resize { + constexpr int do_stuff(int k1, int k2) { + int arr[1234] = { 1, 2, 3, 4 }; + arr[k1] = 5; // expected-note {{past-the-end}} expected-note {{cannot refer to element 1235}} expected-note {{cannot refer to element -1}} + return arr[k2]; + } + static_assert(do_stuff(1, 2) == 3, ""); + static_assert(do_stuff(0, 0) == 5, ""); + static_assert(do_stuff(1233, 1233) == 5, ""); + static_assert(do_stuff(1233, 0) == 1, ""); + static_assert(do_stuff(1234, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} + static_assert(do_stuff(1235, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} + static_assert(do_stuff(-1, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} +} + +namespace potential_const_expr { + constexpr void set(int &n) { n = 1; } + constexpr int div_zero_1() { int z = 0; set(z); return 100 / z; } // no error + constexpr int div_zero_2() { // expected-error {{never produces a constant expression}} + int z = 0; + return 100 / (set(z), 0); // expected-note {{division by zero}} + } +} + +namespace subobject { + union A { constexpr A() : y(5) {} int x, y; }; + struct B { A a; }; + struct C : B {}; + union D { constexpr D() : c() {} constexpr D(int n) : n(n) {} C c; int n; }; + constexpr void f(D &d) { + d.c.a.y = 3; + // expected-note@-1 {{cannot modify an object that is visible outside}} + // expected-note@-2 {{assignment to member 'c' of union with active member 'n'}} + } + constexpr bool check(D &d) { return d.c.a.y == 3; } + + constexpr bool g() { D d; f(d); return d.c.a.y == 3; } + static_assert(g(), ""); + + D d; + constexpr bool h() { f(d); return check(d); } // expected-note {{in call}} + static_assert(h(), ""); // expected-error {{constant expression}} expected-note {{in call}} + + constexpr bool i() { D d(0); f(d); return check(d); } // expected-note {{in call}} + static_assert(i(), ""); // expected-error {{constant expression}} expected-note {{in call}} + + constexpr bool j() { D d; d.c.a.x = 3; return check(d); } // expected-note {{assignment to member 'x' of union with active member 'y'}} + static_assert(j(), ""); // expected-error {{constant expression}} expected-note {{in call}} +} + +namespace lifetime { + constexpr int &&id(int &&n) { return static_cast<int&&>(n); } + constexpr int &&dead() { return id(0); } // expected-note {{temporary created here}} + constexpr int bad() { int &&n = dead(); n = 1; return n; } // expected-note {{assignment to temporary whose lifetime has ended}} + static_assert(bad(), ""); // expected-error {{constant expression}} expected-note {{in call}} +} + +namespace const_modify { + constexpr int modify(int &n) { return n = 1; } // expected-note {{modification of object of const-qualified type 'const int'}} + constexpr int test1() { int k = 0; return modify(k); } + constexpr int test2() { const int k = 0; return modify(const_cast<int&>(k)); } // expected-note {{in call}} + static_assert(test1() == 1, ""); + static_assert(test2() == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} +} + +namespace null { + constexpr int test(int *p) { + return *p = 123; // expected-note {{assignment to dereferenced null pointer}} + } + static_assert(test(0), ""); // expected-error {{constant expression}} expected-note {{in call}} +} diff --git a/test/SemaCXX/constexpr-printing.cpp b/test/SemaCXX/constexpr-printing.cpp index 9170fa1ec2..e545f45d60 100644 --- a/test/SemaCXX/constexpr-printing.cpp +++ b/test/SemaCXX/constexpr-printing.cpp @@ -9,7 +9,7 @@ struct S { int n, m; }; -constexpr int extract(const S &s) { return s.n; } // expected-note {{read of uninitialized object is not allowed in a constant expression}} +constexpr int extract(const S &s) { return s.n; } // expected-note {{read of object outside its lifetime is not allowed in a constant expression}} constexpr S s1; // ok void f() { diff --git a/test/SemaCXX/constexpr-value-init.cpp b/test/SemaCXX/constexpr-value-init.cpp index e459f097b9..d137bd88db 100644 --- a/test/SemaCXX/constexpr-value-init.cpp +++ b/test/SemaCXX/constexpr-value-init.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -verify struct A { - constexpr A() : a(b + 1), b(a + 1) {} // expected-note {{uninitialized}} + constexpr A() : a(b + 1), b(a + 1) {} // expected-note {{outside its lifetime}} int a; int b; }; diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp index 5631577e0f..c80323ccd7 100644 --- a/test/SemaCXX/i-c-e-cxx.cpp +++ b/test/SemaCXX/i-c-e-cxx.cpp @@ -60,7 +60,7 @@ int* y = reinterpret_cast<const char&>(x); // expected-error {{cannot initialize // This isn't an integral constant expression, but make sure it folds anyway. struct PR8836 { char _; long long a; }; // expected-warning {{long long}} -int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast<const volatile char&>((((PR8836*)0)->a))]; // expected-warning {{folded to constant array as an extension}} expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}} +int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast<const volatile char&>((((PR8836*)0)->a))]; // expected-warning {{folded to constant array as an extension}} expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} const int nonconst = 1.0; // expected-note {{declared here}} int arr[nonconst]; // expected-warning {{folded to constant array as an extension}} expected-note {{initializer of 'nonconst' is not a constant expression}} |