Richard Smith | 57b9c4e | 2012-02-14 22:25:15 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++11 -verify %s |
| 2 | |
| 3 | namespace UseBeforeDefinition { |
| 4 | struct A { |
| 5 | template<typename T> static constexpr T get() { return T(); } |
| 6 | // ok, not a constant expression. |
| 7 | int n = get<int>(); |
| 8 | }; |
| 9 | |
| 10 | // ok, constant expression. |
| 11 | constexpr int j = A::get<int>(); |
| 12 | |
| 13 | template<typename T> constexpr int consume(T); |
| 14 | // ok, not a constant expression. |
| 15 | const int k = consume(0); // expected-note {{here}} |
| 16 | |
| 17 | template<typename T> constexpr int consume(T) { return 0; } |
| 18 | // ok, constant expression. |
| 19 | constexpr int l = consume(0); |
| 20 | |
| 21 | constexpr int m = k; // expected-error {{constant expression}} expected-note {{initializer of 'k'}} |
| 22 | } |
| 23 | |
| 24 | namespace IntegralConst { |
| 25 | template<typename T> constexpr T f(T n) { return n; } |
| 26 | enum E { |
| 27 | v = f(0), w = f(1) // ok |
| 28 | }; |
| 29 | static_assert(w == 1, ""); |
| 30 | |
| 31 | char arr[f('x')]; // ok |
| 32 | static_assert(sizeof(arr) == 'x', ""); |
| 33 | } |
| 34 | |
| 35 | namespace ConvertedConst { |
| 36 | template<typename T> constexpr T f(T n) { return n; } |
| 37 | int f() { |
| 38 | switch (f()) { |
| 39 | case f(4): return 0; |
| 40 | } |
| 41 | return 1; |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | namespace OverloadResolution { |
| 46 | template<typename T> constexpr T f(T t) { return t; } |
| 47 | |
| 48 | template<int n> struct S { }; |
| 49 | |
| 50 | template<typename T> auto g(T t) -> S<f(sizeof(T))> &; |
| 51 | char &f(...); |
| 52 | |
| 53 | template<typename T> auto h(T t[f(sizeof(T))]) -> decltype(&*t) { |
| 54 | return t; |
| 55 | } |
| 56 | |
| 57 | S<4> &k = g(0); |
| 58 | int *p, *q = h(p); |
| 59 | } |
Richard Smith | 37ce010 | 2012-02-15 02:42:50 +0000 | [diff] [blame] | 60 | |
| 61 | namespace DataMember { |
| 62 | template<typename T> struct S { static const int k; }; |
| 63 | const int n = S<int>::k; // expected-note {{here}} |
| 64 | template<typename T> const int S<T>::k = 0; |
| 65 | constexpr int m = S<int>::k; // ok |
| 66 | constexpr int o = n; // expected-error {{constant expression}} expected-note {{initializer of 'n'}} |
| 67 | } |
Richard Smith | 1658133 | 2012-03-02 04:14:40 +0000 | [diff] [blame] | 68 | |
| 69 | namespace Reference { |
| 70 | const int k = 5; |
| 71 | template<typename T> struct S { |
| 72 | static volatile int &r; |
| 73 | }; |
| 74 | template<typename T> volatile int &S<T>::r = const_cast<volatile int&>(k); |
| 75 | constexpr int n = const_cast<int&>(S<int>::r); |
| 76 | static_assert(n == 5, ""); |
| 77 | } |