Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -std=c++11 -verify %s
      2 
      3 namespace 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 
     24 namespace IntegralConst {
     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 {
     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 
     45 namespace 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 
     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