• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -std=c++11 -verify %s
2 
3 namespace UseBeforeDefinition {
4   struct A {
getUseBeforeDefinition::A5     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 
consume(T)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 {
f(T n)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 {
f(T n)36   template<typename T> constexpr T f(T n) { return n; }
f()37   int f() {
38     switch (f()) {
39       case f(4): return 0;
40     }
41     return 1;
42   }
43 }
44 
45 namespace OverloadResolution {
f(T t)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 
h(T t[f (sizeof (T))])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 {
SUnevaluated::NotConstexpr::S95       S() : n(0) {}
SUnevaluated::NotConstexpr::S96       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 {
SUnevaluated::Constexpr::S104       constexpr S() : n(0) {}
SUnevaluated::Constexpr::S105       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 {
SUnevaluated::ConstexprList::S113       constexpr S() : n(0) {
114         static_assert(N >= 0, "");
115       }
operator intUnevaluated::ConstexprList::S116       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 {
f()132     template<int x> constexpr int f() { return x; }
133     template<int i> void ovf(int (&x)[f<i>()]);
f()134     void f() { int x[10]; ovf<10>(x); }
135   }
136 
137   namespace PR11851_Comment1 {
138     template<typename T>
Integral()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 {};
bar()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 {
S1Unevaluated::PR11851_Comment9::S1166       constexpr S1() {}
operator intUnevaluated::PR11851_Comment9::S1167       constexpr operator int() const { return 0; }
168     };
169     int k1 = sizeof(short{S1(S1())});
170 
171     struct S2 {
S2Unevaluated::PR11851_Comment9::S2172       constexpr S2() {}
operator intUnevaluated::PR11851_Comment9::S2173       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 {
foo()179     template <typename> constexpr bool foo() { return true; }
180     template <bool> struct bar {};
baz()181     template <typename T> bar<foo<T>()> baz() { return bar<foo<T>()>(); }
main()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>
fUnevaluated::PR13423::F191       static constexpr bool f() { return sizeof(T) < U::size; }
192 
193       template<typename U>
gUnevaluated::PR13423::F194       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 
h()199     void h() { F<char>::g<U>(); }
i()200     void i() { F<int>::g<U>(); } // expected-error {{no matching function}}
201   }
202 
203   namespace PR14203 {
durationUnevaluated::PR14203::duration204     struct duration { constexpr duration() {} };
205 
206     template <typename>
sleep_for()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 
f()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 {
SNoInstantiationWhenSelectingOverload::S244     template<typename T> constexpr S(T) : n(T::error) {} // expected-error {{no members}}
245     int n;
246   };
247 
f(S)248   constexpr int f(S) { return 0; }
f(int)249   constexpr int f(int) { return 0; }
250 
g()251   void g() { f(0); }
h()252   void h() { (void)sizeof(char{f(0)}); }
i()253   void i() { (void)sizeof(char{f("oops")}); } // expected-note {{instantiation of}}
254 }
255 
256 namespace PR20090 {
fact(T n)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