• 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 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 {
SUnevaluated::NotConstexpr::S96       S() : n(0) {}
SUnevaluated::NotConstexpr::S97       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 {
SUnevaluated::Constexpr::S105       constexpr S() : n(0) {}
SUnevaluated::Constexpr::S106       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 {
f()114     template<int x> constexpr int f() { return x; }
115     template<int i> void ovf(int (&x)[f<i>()]);
f()116     void f() { int x[10]; ovf<10>(x); }
117   }
118 
119   namespace PR11851_Comment1 {
120     template<typename T>
Integral()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 {};
bar()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 {
S1Unevaluated::PR11851_Comment9::S1148       constexpr S1() {}
operator intUnevaluated::PR11851_Comment9::S1149       constexpr operator int() const { return 0; }
150     };
151     int k1 = sizeof(short{S1(S1())});
152 
153     struct S2 {
S2Unevaluated::PR11851_Comment9::S2154       constexpr S2() {}
operator intUnevaluated::PR11851_Comment9::S2155       constexpr operator int() const { return 123456; }
156     };
157     int k2 = sizeof(short{S2(S2())}); // expected-error {{cannot be narrowed}} expected-note {{insert an explicit cast to silence this issue}}
158   }
159 
160   namespace PR12288 {
foo()161     template <typename> constexpr bool foo() { return true; }
162     template <bool> struct bar {};
baz()163     template <typename T> bar<foo<T>()> baz() { return bar<foo<T>()>(); }
main()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>
fUnevaluated::PR13423::F173       static constexpr bool f() { return sizeof(T) < U::size; }
174 
175       template<typename U>
gUnevaluated::PR13423::F176       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 
h()181     void h() { F<char>::g<U>(); }
i()182     void i() { F<int>::g<U>(); } // expected-error {{no matching function}}
183   }
184 
185   namespace PR14203 {
durationUnevaluated::PR14203::duration186     struct duration { constexpr duration() {} };
187 
188     template <typename>
sleep_for()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 {
SNoInstantiationWhenSelectingOverload::S200     template<typename T> constexpr S(T) : n(T::error) {} // expected-error {{no members}}
201     int n;
202   };
203 
204   int f(S);
205   int f(int);
206 
g()207   void g() { f(0); }
h()208   void h() { (void)sizeof(f(0)); }
i()209   void i() { (void)sizeof(f("oops")); } // expected-note {{instantiation of}}
210 }
211