264 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -verify %s2 3namespace 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 24namespace IntegralConst {25 template<typename T> constexpr T f(T n) { return n; }26 enum E {27 v = f(0), w = f(1) // ok28 };29 static_assert(w == 1, "");30 31 char arr[f('x')]; // ok32 static_assert(sizeof(arr) == 'x', "");33}34 35namespace 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 45namespace 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 61namespace 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; // ok66 constexpr int o = n; // expected-error {{constant expression}} expected-note {{initializer of 'n'}}67}68 69namespace 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 79namespace Unevaluated {80 // We follow the current proposed resolution of core issue 1581: a constexpr81 // function template specialization requires a definition if:82 // * it is odr-used, or would be odr-used except that it appears within the83 // definition of a template, or84 // * it is used within a braced-init-list, where it may be necessary for85 // detecting narrowing conversions.86 //87 // We apply this both for instantiating constexpr function template88 // specializations and for implicitly defining defaulted constexpr special89 // member functions.90 //91 // FIXME: None of this is required by the C++ standard yet. The rules in this92 // 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 list121 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 list126 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 which213 // evaluation could be required (odr-used, used in a template whose214 // instantiations would odr-use, or used in list initialization), if they215 // 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}} expected-note 1+{{not valid in a constant expression}} expected-note 1+{{declared here}}223 // expected-error@-1 1+{{must be initialized by a constant expression}}224 225 template<int N> int A<N>::n = *(int[N]){0};226 227 template <typename> void f() {228 (void)A<-1>::n; // ok229 (void)A<-1>::k; // expected-note {{instantiation of }}230 B<&A<-2>::n> b1; // ok231 B<&A<-2>::k> b2; // expected-note {{instantiation of }}232 };233 234 decltype(A<-3>::k) d1 = 0; // ok235 decltype(char{A<-4>::k}) d2 = 0; // expected-note 1+{{instantiation of }} expected-error {{narrow}} expected-note {{cast}}236 decltype(char{A<1>::k}) d3 = 0; // expected-note 1+{{instantiation of }} expected-error {{narrow}} expected-note {{cast}}237 decltype(char{A<1 + (unsigned char)-1>::k}) d4 = 0; // expected-error {{narrow}} expected-note {{cast}} expected-note {{instantiation of}}238 }239}240 241namespace NoInstantiationWhenSelectingOverload {242 // Check that we don't instantiate conversion functions when we're checking243 // for the existence of an implicit conversion sequence, only when a function244 // is actually chosen by overload resolution.245 struct S {246 template<typename T> constexpr S(T) : n(T::error) {} // expected-error {{no members}}247 int n;248 };249 250 constexpr int f(S) { return 0; }251 constexpr int f(int) { return 0; }252 253 void g() { f(0); }254 void h() { (void)sizeof(char{f(0)}); }255 void i() { (void)sizeof(char{f("oops")}); } // expected-note {{instantiation of}}256}257 258namespace PR20090 {259 template <typename T> constexpr T fact(T n) {260 return n == 0 ? 1 : [=] { return n * fact(n - 1); }();261 }262 static_assert(fact(0) == 1, "");263}264