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 | } |
Richard Smith | ce2661f | 2012-11-07 01:14:25 +0000 | [diff] [blame] | 78 | |
| 79 | namespace Unevaluated { |
| 80 | // We follow g++ in treating any reference to a constexpr function template |
| 81 | // specialization as requiring an instantiation, even if it occurs in an |
| 82 | // unevaluated context. |
| 83 | // |
| 84 | // We go slightly further than g++, and also trigger the implicit definition |
| 85 | // of a defaulted special member in the same circumstances. This seems scary, |
| 86 | // since a lot of classes have constexpr special members in C++11, but the |
| 87 | // only observable impact should be the implicit instantiation of constexpr |
| 88 | // special member templates (defaulted special members should only be |
| 89 | // generated if they are well-formed, and non-constexpr special members in a |
| 90 | // base or member cause the class's special member to not be constexpr). |
| 91 | // |
| 92 | // FIXME: None of this is required by the C++ standard. The rules in this |
| 93 | // area are poorly specified, so this is subject to change. |
| 94 | namespace NotConstexpr { |
| 95 | template<typename T> struct S { |
| 96 | S() : n(0) {} |
| 97 | S(const S&) : n(T::error) {} |
| 98 | int n; |
| 99 | }; |
| 100 | struct U : S<int> {}; |
| 101 | decltype(U(U())) u; // ok, don't instantiate S<int>::S() because it wasn't declared constexpr |
| 102 | } |
| 103 | namespace Constexpr { |
| 104 | template<typename T> struct S { |
| 105 | constexpr S() : n(0) {} |
| 106 | constexpr S(const S&) : n(T::error) {} // expected-error {{has no members}} |
| 107 | int n; |
| 108 | }; |
| 109 | struct U : S<int> {}; // expected-note {{instantiation}} |
| 110 | decltype(U(U())) u; // expected-note {{here}} |
| 111 | } |
| 112 | |
| 113 | namespace PR11851_Comment0 { |
| 114 | template<int x> constexpr int f() { return x; } |
| 115 | template<int i> void ovf(int (&x)[f<i>()]); |
| 116 | void f() { int x[10]; ovf<10>(x); } |
| 117 | } |
| 118 | |
| 119 | namespace PR11851_Comment1 { |
| 120 | template<typename T> |
| 121 | constexpr bool Integral() { |
| 122 | return true; |
| 123 | } |
| 124 | template<typename T, bool Int = Integral<T>()> |
| 125 | struct safe_make_unsigned { |
| 126 | typedef T type; |
| 127 | }; |
| 128 | template<typename T> |
| 129 | using Make_unsigned = typename safe_make_unsigned<T>::type; |
| 130 | template <typename T> |
| 131 | struct get_distance_type { |
| 132 | using type = int; |
| 133 | }; |
| 134 | template<typename R> |
| 135 | auto size(R) -> Make_unsigned<typename get_distance_type<R>::type>; |
| 136 | auto check() -> decltype(size(0)); |
| 137 | } |
| 138 | |
| 139 | namespace PR11851_Comment6 { |
| 140 | template<int> struct foo {}; |
| 141 | template<class> constexpr int bar() { return 0; } |
| 142 | template<class T> foo<bar<T>()> foobar(); |
| 143 | auto foobar_ = foobar<int>(); |
| 144 | } |
| 145 | |
| 146 | namespace PR11851_Comment9 { |
| 147 | struct S1 { |
| 148 | constexpr S1() {} |
| 149 | constexpr operator int() const { return 0; } |
| 150 | }; |
| 151 | int k1 = sizeof(short{S1(S1())}); |
| 152 | |
| 153 | struct S2 { |
| 154 | constexpr S2() {} |
| 155 | constexpr operator int() const { return 123456; } |
| 156 | }; |
| 157 | int k2 = sizeof(short{S2(S2())}); // expected-error {{cannot be narrowed}} expected-note {{override}} |
| 158 | } |
| 159 | |
| 160 | namespace PR12288 { |
| 161 | template <typename> constexpr bool foo() { return true; } |
| 162 | template <bool> struct bar {}; |
| 163 | template <typename T> bar<foo<T>()> baz() { return bar<foo<T>()>(); } |
| 164 | int main() { baz<int>(); } |
| 165 | } |
| 166 | |
| 167 | namespace PR13423 { |
| 168 | template<bool, typename> struct enable_if {}; |
| 169 | template<typename T> struct enable_if<true, T> { using type = T; }; |
| 170 | |
| 171 | template<typename T> struct F { |
| 172 | template<typename U> |
| 173 | static constexpr bool f() { return sizeof(T) < U::size; } |
| 174 | |
| 175 | template<typename U> |
| 176 | static typename enable_if<f<U>(), void>::type g() {} // expected-note {{disabled by 'enable_if'}} |
| 177 | }; |
| 178 | |
| 179 | struct U { static constexpr int size = 2; }; |
| 180 | |
| 181 | void h() { F<char>::g<U>(); } |
| 182 | void i() { F<int>::g<U>(); } // expected-error {{no matching function}} |
| 183 | } |
| 184 | |
| 185 | namespace PR14203 { |
| 186 | struct duration { constexpr duration() {} }; |
| 187 | |
| 188 | template <typename> |
| 189 | void sleep_for() { |
| 190 | constexpr duration max = duration(); |
| 191 | } |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | namespace NoInstantiationWhenSelectingOverload { |
| 196 | // Check that we don't instantiate conversion functions when we're checking |
| 197 | // for the existence of an implicit conversion sequence, only when a function |
| 198 | // is actually chosen by overload resolution. |
| 199 | struct S { |
| 200 | template<typename T> constexpr S(T) : n(T::error) {} // expected-error {{no members}} |
| 201 | int n; |
| 202 | }; |
| 203 | |
| 204 | void f(S); |
| 205 | void f(int); |
| 206 | |
| 207 | void g() { f(0); } |
| 208 | void h() { (void)sizeof(f(0)); } |
| 209 | void i() { (void)sizeof(f("oops")); } // expected-note {{instantiation of}} |
| 210 | } |