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 | } |
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 | } |
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 | } |
78 | |
79 | namespace Unevaluated { |
80 | // We follow the current proposed resolution of core issue 1581: a constexpr |
81 | // function template specialization requires a definition if: |
82 | // * it is odr-used, or would be odr-used except that it appears within the |
83 | // definition of a template, or |
84 | // * it is used within a braced-init-list, where it may be necessary for |
85 | // detecting narrowing conversions. |
86 | // |
87 | // We apply this both for instantiating constexpr function template |
88 | // specializations and for implicitly defining defaulted constexpr special |
89 | // member functions. |
90 | // |
91 | // FIXME: None of this is required by the C++ standard yet. The rules in this |
92 | // area are subject to change. |
93 | namespace NotConstexpr { |
94 | template<typename T> struct S { |
95 | S() : n(0) {} |
96 | S(const S&) : n(T::error) {} |
97 | int n; |
98 | }; |
99 | struct U : S<int> {}; |
100 | decltype(U(U())) u; |
101 | } |
102 | namespace Constexpr { |
103 | template<typename T> struct S { |
104 | constexpr S() : n(0) {} |
105 | constexpr S(const S&) : n(T::error) {} |
106 | int n; |
107 | }; |
108 | struct U : S<int> {}; |
109 | decltype(U(U())) u; |
110 | } |
111 | namespace ConstexprList { |
112 | template<int N> struct S { |
113 | constexpr S() : n(0) { |
114 | static_assert(N >= 0, ""); |
115 | } |
116 | constexpr operator int() const { return 0; } |
117 | int n; |
118 | }; |
119 | struct U : S<0> {}; |
120 | // ok, trigger instantiation within a list |
121 | decltype(char{U()}) t0; |
122 | decltype(new char{S<1>()}) t1; // expected-warning {{side effects}} |
123 | decltype((char){S<2>()}) t2; |
124 | decltype(+(char[1]){{S<3>()}}) t3; |
125 | // do not trigger instantiation outside a list |
126 | decltype(char(S<-1>())) u1; |
127 | decltype(new char(S<-2>())) u2; // expected-warning {{side effects}} |
128 | decltype((char)(S<-3>())) u3; |
129 | } |
130 | |
131 | namespace PR11851_Comment0 { |
132 | template<int x> constexpr int f() { return x; } |
133 | template<int i> void ovf(int (&x)[f<i>()]); |
134 | void f() { int x[10]; ovf<10>(x); } |
135 | } |
136 | |
137 | namespace PR11851_Comment1 { |
138 | template<typename T> |
139 | constexpr bool Integral() { |
140 | return true; |
141 | } |
142 | template<typename T, bool Int = Integral<T>()> |
143 | struct safe_make_unsigned { |
144 | typedef T type; |
145 | }; |
146 | template<typename T> |
147 | using Make_unsigned = typename safe_make_unsigned<T>::type; |
148 | template <typename T> |
149 | struct get_distance_type { |
150 | using type = int; |
151 | }; |
152 | template<typename R> |
153 | auto size(R) -> Make_unsigned<typename get_distance_type<R>::type>; |
154 | auto check() -> decltype(size(0)); |
155 | } |
156 | |
157 | namespace PR11851_Comment6 { |
158 | template<int> struct foo {}; |
159 | template<class> constexpr int bar() { return 0; } |
160 | template<class T> foo<bar<T>()> foobar(); |
161 | auto foobar_ = foobar<int>(); |
162 | } |
163 | |
164 | namespace PR11851_Comment9 { |
165 | struct S1 { |
166 | constexpr S1() {} |
167 | constexpr operator int() const { return 0; } |
168 | }; |
169 | int k1 = sizeof(short{S1(S1())}); |
170 | |
171 | struct S2 { |
172 | constexpr S2() {} |
173 | constexpr operator int() const { return 123456; } |
174 | }; |
175 | int k2 = sizeof(short{S2(S2())}); // expected-error {{cannot be narrowed}} expected-note {{insert an explicit cast to silence this issue}} |
176 | } |
177 | |
178 | namespace PR12288 { |
179 | template <typename> constexpr bool foo() { return true; } |
180 | template <bool> struct bar {}; |
181 | template <typename T> bar<foo<T>()> baz() { return bar<foo<T>()>(); } |
182 | int main() { baz<int>(); } |
183 | } |
184 | |
185 | namespace PR13423 { |
186 | template<bool, typename> struct enable_if {}; |
187 | template<typename T> struct enable_if<true, T> { using type = T; }; |
188 | |
189 | template<typename T> struct F { |
190 | template<typename U> |
191 | static constexpr bool f() { return sizeof(T) < U::size; } |
192 | |
193 | template<typename U> |
194 | static typename enable_if<f<U>(), void>::type g() {} // expected-note {{requirement 'f<Unevaluated::PR13423::U>()' was not satisfied}} |
195 | }; |
196 | |
197 | struct U { static constexpr int size = 2; }; |
198 | |
199 | void h() { F<char>::g<U>(); } |
200 | void i() { F<int>::g<U>(); } // expected-error {{no matching function}} |
201 | } |
202 | |
203 | namespace PR14203 { |
204 | struct duration { constexpr duration() {} }; |
205 | |
206 | template <typename> |
207 | void sleep_for() { |
208 | constexpr duration max = duration(); |
209 | } |
210 | } |
211 | |
212 | // For variables, we instantiate when they are used in a context in which |
213 | // evaluation could be required (odr-used, used in a template whose |
214 | // instantiations would odr-use, or used in list initialization), if they |
215 | // can be used as a constant (const integral or constexpr). |
216 | namespace Variables { |
217 | template<int N> struct A { |
218 | static const int k; |
219 | static int n; |
220 | }; |
221 | template<const int *N> struct B {}; |
222 | template<int N> constexpr int A<N>::k = *(int[N]){N}; // expected-error 1+{{negative}} |
223 | template<int N> int A<N>::n = *(int[N]){0}; |
224 | |
225 | template <typename> void f() { |
226 | (void)A<-1>::n; // ok |
227 | (void)A<-1>::k; // expected-note {{instantiation of }} |
228 | B<&A<-2>::n> b1; // ok |
229 | B<&A<-2>::k> b2; // expected-note {{instantiation of }} |
230 | }; |
231 | |
232 | decltype(A<-3>::k) d1 = 0; // ok |
233 | decltype(char{A<-4>::k}) d2 = 0; // expected-note {{instantiation of }} expected-error {{narrow}} expected-note {{cast}} |
234 | decltype(char{A<1>::k}) d3 = 0; // ok |
235 | decltype(char{A<1 + (unsigned char)-1>::k}) d4 = 0; // expected-error {{narrow}} expected-note {{cast}} |
236 | } |
237 | } |
238 | |
239 | namespace NoInstantiationWhenSelectingOverload { |
240 | // Check that we don't instantiate conversion functions when we're checking |
241 | // for the existence of an implicit conversion sequence, only when a function |
242 | // is actually chosen by overload resolution. |
243 | struct S { |
244 | template<typename T> constexpr S(T) : n(T::error) {} // expected-error {{no members}} |
245 | int n; |
246 | }; |
247 | |
248 | constexpr int f(S) { return 0; } |
249 | constexpr int f(int) { return 0; } |
250 | |
251 | void g() { f(0); } |
252 | void h() { (void)sizeof(char{f(0)}); } |
253 | void i() { (void)sizeof(char{f("oops")}); } // expected-note {{instantiation of}} |
254 | } |
255 | |
256 | namespace PR20090 { |
257 | template <typename T> constexpr T fact(T n) { |
258 | return n == 0 ? 1 : [=] { return n * fact(n - 1); }(); |
259 | } |
260 | static_assert(fact(0) == 1, ""); |
261 | } |
262 | |