xref: /minix3/external/bsd/llvm/dist/clang/test/SemaTemplate/constexpr-instantiate.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -std=c++11 -verify %s
2f4a2713aSLionel Sambuc 
3f4a2713aSLionel Sambuc namespace UseBeforeDefinition {
4f4a2713aSLionel Sambuc   struct A {
getUseBeforeDefinition::A5f4a2713aSLionel Sambuc     template<typename T> static constexpr T get() { return T(); }
6f4a2713aSLionel Sambuc     // ok, not a constant expression.
7f4a2713aSLionel Sambuc     int n = get<int>();
8f4a2713aSLionel Sambuc   };
9f4a2713aSLionel Sambuc 
10f4a2713aSLionel Sambuc   // ok, constant expression.
11f4a2713aSLionel Sambuc   constexpr int j = A::get<int>();
12f4a2713aSLionel Sambuc 
13f4a2713aSLionel Sambuc   template<typename T> constexpr int consume(T);
14f4a2713aSLionel Sambuc   // ok, not a constant expression.
15f4a2713aSLionel Sambuc   const int k = consume(0); // expected-note {{here}}
16f4a2713aSLionel Sambuc 
consume(T)17f4a2713aSLionel Sambuc   template<typename T> constexpr int consume(T) { return 0; }
18f4a2713aSLionel Sambuc   // ok, constant expression.
19f4a2713aSLionel Sambuc   constexpr int l = consume(0);
20f4a2713aSLionel Sambuc 
21f4a2713aSLionel Sambuc   constexpr int m = k; // expected-error {{constant expression}} expected-note {{initializer of 'k'}}
22f4a2713aSLionel Sambuc }
23f4a2713aSLionel Sambuc 
24f4a2713aSLionel Sambuc namespace IntegralConst {
f(T n)25f4a2713aSLionel Sambuc   template<typename T> constexpr T f(T n) { return n; }
26f4a2713aSLionel Sambuc   enum E {
27f4a2713aSLionel Sambuc     v = f(0), w = f(1) // ok
28f4a2713aSLionel Sambuc   };
29f4a2713aSLionel Sambuc   static_assert(w == 1, "");
30f4a2713aSLionel Sambuc 
31f4a2713aSLionel Sambuc   char arr[f('x')]; // ok
32f4a2713aSLionel Sambuc   static_assert(sizeof(arr) == 'x', "");
33f4a2713aSLionel Sambuc }
34f4a2713aSLionel Sambuc 
35f4a2713aSLionel Sambuc namespace ConvertedConst {
f(T n)36f4a2713aSLionel Sambuc   template<typename T> constexpr T f(T n) { return n; }
f()37f4a2713aSLionel Sambuc   int f() {
38f4a2713aSLionel Sambuc     switch (f()) {
39f4a2713aSLionel Sambuc       case f(4): return 0;
40f4a2713aSLionel Sambuc     }
41f4a2713aSLionel Sambuc     return 1;
42f4a2713aSLionel Sambuc   }
43f4a2713aSLionel Sambuc }
44f4a2713aSLionel Sambuc 
45f4a2713aSLionel Sambuc namespace OverloadResolution {
f(T t)46f4a2713aSLionel Sambuc   template<typename T> constexpr T f(T t) { return t; }
47f4a2713aSLionel Sambuc 
48f4a2713aSLionel Sambuc   template<int n> struct S { };
49f4a2713aSLionel Sambuc 
50f4a2713aSLionel Sambuc   template<typename T> auto g(T t) -> S<f(sizeof(T))> &;
51f4a2713aSLionel Sambuc   char &f(...);
52f4a2713aSLionel Sambuc 
h(T t[f (sizeof (T))])53f4a2713aSLionel Sambuc   template<typename T> auto h(T t[f(sizeof(T))]) -> decltype(&*t) {
54f4a2713aSLionel Sambuc     return t;
55f4a2713aSLionel Sambuc   }
56f4a2713aSLionel Sambuc 
57f4a2713aSLionel Sambuc   S<4> &k = g(0);
58f4a2713aSLionel Sambuc   int *p, *q = h(p);
59f4a2713aSLionel Sambuc }
60f4a2713aSLionel Sambuc 
61f4a2713aSLionel Sambuc namespace DataMember {
62f4a2713aSLionel Sambuc   template<typename T> struct S { static const int k; };
63f4a2713aSLionel Sambuc   const int n = S<int>::k; // expected-note {{here}}
64f4a2713aSLionel Sambuc   template<typename T> const int S<T>::k = 0;
65f4a2713aSLionel Sambuc   constexpr int m = S<int>::k; // ok
66f4a2713aSLionel Sambuc   constexpr int o = n; // expected-error {{constant expression}} expected-note {{initializer of 'n'}}
67f4a2713aSLionel Sambuc }
68f4a2713aSLionel Sambuc 
69f4a2713aSLionel Sambuc namespace Reference {
70f4a2713aSLionel Sambuc   const int k = 5;
71f4a2713aSLionel Sambuc   template<typename T> struct S {
72f4a2713aSLionel Sambuc     static volatile int &r;
73f4a2713aSLionel Sambuc   };
74f4a2713aSLionel Sambuc   template<typename T> volatile int &S<T>::r = const_cast<volatile int&>(k);
75f4a2713aSLionel Sambuc   constexpr int n = const_cast<int&>(S<int>::r);
76f4a2713aSLionel Sambuc   static_assert(n == 5, "");
77f4a2713aSLionel Sambuc }
78f4a2713aSLionel Sambuc 
79f4a2713aSLionel Sambuc namespace Unevaluated {
80f4a2713aSLionel Sambuc   // We follow g++ in treating any reference to a constexpr function template
81f4a2713aSLionel Sambuc   // specialization as requiring an instantiation, even if it occurs in an
82f4a2713aSLionel Sambuc   // unevaluated context.
83f4a2713aSLionel Sambuc   //
84f4a2713aSLionel Sambuc   // We go slightly further than g++, and also trigger the implicit definition
85f4a2713aSLionel Sambuc   // of a defaulted special member in the same circumstances. This seems scary,
86f4a2713aSLionel Sambuc   // since a lot of classes have constexpr special members in C++11, but the
87f4a2713aSLionel Sambuc   // only observable impact should be the implicit instantiation of constexpr
88f4a2713aSLionel Sambuc   // special member templates (defaulted special members should only be
89f4a2713aSLionel Sambuc   // generated if they are well-formed, and non-constexpr special members in a
90f4a2713aSLionel Sambuc   // base or member cause the class's special member to not be constexpr).
91f4a2713aSLionel Sambuc   //
92f4a2713aSLionel Sambuc   // FIXME: None of this is required by the C++ standard. The rules in this
93f4a2713aSLionel Sambuc   //        area are poorly specified, so this is subject to change.
94f4a2713aSLionel Sambuc   namespace NotConstexpr {
95f4a2713aSLionel Sambuc     template<typename T> struct S {
SUnevaluated::NotConstexpr::S96f4a2713aSLionel Sambuc       S() : n(0) {}
SUnevaluated::NotConstexpr::S97f4a2713aSLionel Sambuc       S(const S&) : n(T::error) {}
98f4a2713aSLionel Sambuc       int n;
99f4a2713aSLionel Sambuc     };
100f4a2713aSLionel Sambuc     struct U : S<int> {};
101f4a2713aSLionel Sambuc     decltype(U(U())) u; // ok, don't instantiate S<int>::S() because it wasn't declared constexpr
102f4a2713aSLionel Sambuc   }
103f4a2713aSLionel Sambuc   namespace Constexpr {
104f4a2713aSLionel Sambuc     template<typename T> struct S {
SUnevaluated::Constexpr::S105f4a2713aSLionel Sambuc       constexpr S() : n(0) {}
SUnevaluated::Constexpr::S106f4a2713aSLionel Sambuc       constexpr S(const S&) : n(T::error) {} // expected-error {{has no members}}
107f4a2713aSLionel Sambuc       int n;
108f4a2713aSLionel Sambuc     };
109f4a2713aSLionel Sambuc     struct U : S<int> {}; // expected-note {{instantiation}}
110f4a2713aSLionel Sambuc     decltype(U(U())) u; // expected-note {{here}}
111f4a2713aSLionel Sambuc   }
112f4a2713aSLionel Sambuc 
113f4a2713aSLionel Sambuc   namespace PR11851_Comment0 {
f()114f4a2713aSLionel Sambuc     template<int x> constexpr int f() { return x; }
115f4a2713aSLionel Sambuc     template<int i> void ovf(int (&x)[f<i>()]);
f()116f4a2713aSLionel Sambuc     void f() { int x[10]; ovf<10>(x); }
117f4a2713aSLionel Sambuc   }
118f4a2713aSLionel Sambuc 
119f4a2713aSLionel Sambuc   namespace PR11851_Comment1 {
120f4a2713aSLionel Sambuc     template<typename T>
Integral()121f4a2713aSLionel Sambuc     constexpr bool Integral() {
122f4a2713aSLionel Sambuc       return true;
123f4a2713aSLionel Sambuc     }
124f4a2713aSLionel Sambuc     template<typename T, bool Int = Integral<T>()>
125f4a2713aSLionel Sambuc     struct safe_make_unsigned {
126f4a2713aSLionel Sambuc       typedef T type;
127f4a2713aSLionel Sambuc     };
128f4a2713aSLionel Sambuc     template<typename T>
129f4a2713aSLionel Sambuc     using Make_unsigned = typename safe_make_unsigned<T>::type;
130f4a2713aSLionel Sambuc     template <typename T>
131f4a2713aSLionel Sambuc     struct get_distance_type {
132f4a2713aSLionel Sambuc       using type = int;
133f4a2713aSLionel Sambuc     };
134f4a2713aSLionel Sambuc     template<typename R>
135f4a2713aSLionel Sambuc     auto size(R) -> Make_unsigned<typename get_distance_type<R>::type>;
136f4a2713aSLionel Sambuc     auto check() -> decltype(size(0));
137f4a2713aSLionel Sambuc   }
138f4a2713aSLionel Sambuc 
139f4a2713aSLionel Sambuc   namespace PR11851_Comment6 {
140f4a2713aSLionel Sambuc     template<int> struct foo {};
bar()141f4a2713aSLionel Sambuc     template<class> constexpr int bar() { return 0; }
142f4a2713aSLionel Sambuc     template<class T> foo<bar<T>()> foobar();
143f4a2713aSLionel Sambuc     auto foobar_ = foobar<int>();
144f4a2713aSLionel Sambuc   }
145f4a2713aSLionel Sambuc 
146f4a2713aSLionel Sambuc   namespace PR11851_Comment9 {
147f4a2713aSLionel Sambuc     struct S1 {
S1Unevaluated::PR11851_Comment9::S1148f4a2713aSLionel Sambuc       constexpr S1() {}
operator intUnevaluated::PR11851_Comment9::S1149f4a2713aSLionel Sambuc       constexpr operator int() const { return 0; }
150f4a2713aSLionel Sambuc     };
151f4a2713aSLionel Sambuc     int k1 = sizeof(short{S1(S1())});
152f4a2713aSLionel Sambuc 
153f4a2713aSLionel Sambuc     struct S2 {
S2Unevaluated::PR11851_Comment9::S2154f4a2713aSLionel Sambuc       constexpr S2() {}
operator intUnevaluated::PR11851_Comment9::S2155f4a2713aSLionel Sambuc       constexpr operator int() const { return 123456; }
156f4a2713aSLionel Sambuc     };
157*0a6a1f1dSLionel Sambuc     int k2 = sizeof(short{S2(S2())}); // expected-error {{cannot be narrowed}} expected-note {{insert an explicit cast to silence this issue}}
158f4a2713aSLionel Sambuc   }
159f4a2713aSLionel Sambuc 
160f4a2713aSLionel Sambuc   namespace PR12288 {
foo()161f4a2713aSLionel Sambuc     template <typename> constexpr bool foo() { return true; }
162f4a2713aSLionel Sambuc     template <bool> struct bar {};
baz()163f4a2713aSLionel Sambuc     template <typename T> bar<foo<T>()> baz() { return bar<foo<T>()>(); }
main()164f4a2713aSLionel Sambuc     int main() { baz<int>(); }
165f4a2713aSLionel Sambuc   }
166f4a2713aSLionel Sambuc 
167f4a2713aSLionel Sambuc   namespace PR13423 {
168f4a2713aSLionel Sambuc     template<bool, typename> struct enable_if {};
169f4a2713aSLionel Sambuc     template<typename T> struct enable_if<true, T> { using type = T; };
170f4a2713aSLionel Sambuc 
171f4a2713aSLionel Sambuc     template<typename T> struct F {
172f4a2713aSLionel Sambuc       template<typename U>
fUnevaluated::PR13423::F173f4a2713aSLionel Sambuc       static constexpr bool f() { return sizeof(T) < U::size; }
174f4a2713aSLionel Sambuc 
175f4a2713aSLionel Sambuc       template<typename U>
gUnevaluated::PR13423::F176f4a2713aSLionel Sambuc       static typename enable_if<f<U>(), void>::type g() {} // expected-note {{disabled by 'enable_if'}}
177f4a2713aSLionel Sambuc     };
178f4a2713aSLionel Sambuc 
179f4a2713aSLionel Sambuc     struct U { static constexpr int size = 2; };
180f4a2713aSLionel Sambuc 
h()181f4a2713aSLionel Sambuc     void h() { F<char>::g<U>(); }
i()182f4a2713aSLionel Sambuc     void i() { F<int>::g<U>(); } // expected-error {{no matching function}}
183f4a2713aSLionel Sambuc   }
184f4a2713aSLionel Sambuc 
185f4a2713aSLionel Sambuc   namespace PR14203 {
durationUnevaluated::PR14203::duration186f4a2713aSLionel Sambuc     struct duration { constexpr duration() {} };
187f4a2713aSLionel Sambuc 
188f4a2713aSLionel Sambuc     template <typename>
sleep_for()189f4a2713aSLionel Sambuc     void sleep_for() {
190f4a2713aSLionel Sambuc       constexpr duration max = duration();
191f4a2713aSLionel Sambuc     }
192f4a2713aSLionel Sambuc   }
193f4a2713aSLionel Sambuc }
194f4a2713aSLionel Sambuc 
195f4a2713aSLionel Sambuc namespace NoInstantiationWhenSelectingOverload {
196f4a2713aSLionel Sambuc   // Check that we don't instantiate conversion functions when we're checking
197f4a2713aSLionel Sambuc   // for the existence of an implicit conversion sequence, only when a function
198f4a2713aSLionel Sambuc   // is actually chosen by overload resolution.
199f4a2713aSLionel Sambuc   struct S {
SNoInstantiationWhenSelectingOverload::S200f4a2713aSLionel Sambuc     template<typename T> constexpr S(T) : n(T::error) {} // expected-error {{no members}}
201f4a2713aSLionel Sambuc     int n;
202f4a2713aSLionel Sambuc   };
203f4a2713aSLionel Sambuc 
204f4a2713aSLionel Sambuc   int f(S);
205f4a2713aSLionel Sambuc   int f(int);
206f4a2713aSLionel Sambuc 
g()207f4a2713aSLionel Sambuc   void g() { f(0); }
h()208f4a2713aSLionel Sambuc   void h() { (void)sizeof(f(0)); }
i()209f4a2713aSLionel Sambuc   void i() { (void)sizeof(f("oops")); } // expected-note {{instantiation of}}
210f4a2713aSLionel Sambuc }
211