brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.1 KiB · 0a34f63 Raw
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