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