Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -std=c++1y -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu
      2 
      3 struct S {
      4   // dummy ctor to make this a literal type
      5   constexpr S(int);
      6 
      7   S();
      8 
      9   int arr[10];
     10 
     11   constexpr int &get(int n) { return arr[n]; }
     12   constexpr const int &get(int n) const { return arr[n]; }
     13 };
     14 
     15 S s = S();
     16 const S &sr = s;
     17 static_assert(&s.get(4) - &sr.get(2) == 2, "");
     18 
     19 // Compound-statements can be used in constexpr functions.
     20 constexpr int e() {{{{}} return 5; }}
     21 static_assert(e() == 5, "");
     22 
     23 // Types can be defined in constexpr functions.
     24 constexpr int f() {
     25   enum E { e1, e2, e3 };
     26 
     27   struct S {
     28     constexpr S(E e) : e(e) {}
     29     constexpr int get() { return e; }
     30     E e;
     31   };
     32 
     33   return S(e2).get();
     34 }
     35 static_assert(f() == 1, "");
     36 
     37 // Variables can be declared in constexpr functions.
     38 constexpr int g(int k) {
     39   const int n = 9;
     40   int k2 = k * k;
     41   int k3 = k2 * k;
     42   return 3 * k3 + 5 * k2 + n * k - 20;
     43 }
     44 static_assert(g(2) == 42, "");
     45 constexpr int h(int n) {
     46   static const int m = n; // expected-error {{static variable not permitted in a constexpr function}}
     47   return m;
     48 }
     49 constexpr int i(int n) {
     50   thread_local const int m = n; // expected-error {{thread_local variable not permitted in a constexpr function}}
     51   return m;
     52 }
     53 
     54 // if-statements can be used in constexpr functions.
     55 constexpr int j(int k) {
     56   if (k == 5)
     57     return 1;
     58   if (k == 1)
     59     return 5;
     60   else {
     61     if (int n = 2 * k - 4) {
     62       return n + 1;
     63       return 2;
     64     }
     65   }
     66 } // expected-note 2{{control reached end of constexpr function}}
     67 static_assert(j(0) == -3, "");
     68 static_assert(j(1) == 5, "");
     69 static_assert(j(2), ""); // expected-error {{constant expression}} expected-note {{in call to 'j(2)'}}
     70 static_assert(j(3) == 3, "");
     71 static_assert(j(4) == 5, "");
     72 static_assert(j(5) == 1, "");
     73 
     74 // There can be 0 return-statements.
     75 constexpr void k() {
     76 }
     77 
     78 // If the return type is not 'void', no return statements => never a constant
     79 // expression, so still diagnose that case.
     80 [[noreturn]] constexpr int fn() { // expected-error {{no return statement in constexpr function}}
     81   fn();
     82 }
     83 
     84 // We evaluate the body of a constexpr constructor, to check for side-effects.
     85 struct U {
     86   constexpr U(int n) {
     87     if (j(n)) {} // expected-note {{in call to 'j(2)'}}
     88   }
     89 };
     90 constexpr U u1{1};
     91 constexpr U u2{2}; // expected-error {{constant expression}} expected-note {{in call to 'U(2)'}}
     92 
     93 // We allow expression-statements.
     94 constexpr int l(bool b) {
     95   if (b)
     96     throw "invalid value for b!"; // expected-note {{subexpression not valid}}
     97   return 5;
     98 }
     99 static_assert(l(false) == 5, "");
    100 static_assert(l(true), ""); // expected-error {{constant expression}} expected-note {{in call to 'l(true)'}}
    101 
    102 // Potential constant expression checking is still applied where possible.
    103 constexpr int htonl(int x) { // expected-error {{never produces a constant expression}}
    104   typedef unsigned char uchar;
    105   uchar arr[4] = { uchar(x >> 24), uchar(x >> 16), uchar(x >> 8), uchar(x) };
    106   return *reinterpret_cast<int*>(arr); // expected-note {{reinterpret_cast is not allowed in a constant expression}}
    107 }
    108 
    109 constexpr int maybe_htonl(bool isBigEndian, int x) {
    110   if (isBigEndian)
    111     return x;
    112 
    113   typedef unsigned char uchar;
    114   uchar arr[4] = { uchar(x >> 24), uchar(x >> 16), uchar(x >> 8), uchar(x) };
    115   return *reinterpret_cast<int*>(arr); // expected-note {{reinterpret_cast is not allowed in a constant expression}}
    116 }
    117 
    118 constexpr int swapped = maybe_htonl(false, 123); // expected-error {{constant expression}} expected-note {{in call}}
    119 
    120 namespace NS {
    121   constexpr int n = 0;
    122 }
    123 constexpr int namespace_alias() {
    124   namespace N = NS;
    125   return N::n;
    126 }
    127 
    128 namespace assign {
    129   constexpr int a = 0;
    130   const int b = 0;
    131   int c = 0; // expected-note {{here}}
    132 
    133   constexpr void set(const int &a, int b) {
    134     const_cast<int&>(a) = b; // expected-note 3{{constant expression cannot modify an object that is visible outside that expression}}
    135   }
    136   constexpr int wrap(int a, int b) {
    137     set(a, b);
    138     return a;
    139   }
    140 
    141   static_assert((set(a, 1), a) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(a, 1)'}}
    142   static_assert((set(b, 1), b) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(b, 1)'}}
    143   static_assert((set(c, 1), c) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(c, 1)'}}
    144 
    145   static_assert(wrap(a, 1) == 1, "");
    146   static_assert(wrap(b, 1) == 1, "");
    147   static_assert(wrap(c, 1) == 1, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}}
    148 }
    149 
    150 namespace string_assign {
    151   template<typename T>
    152   constexpr void swap(T &a, T &b) {
    153     T tmp = a;
    154     a = b;
    155     b = tmp;
    156   }
    157   template<typename Iterator>
    158   constexpr void reverse(Iterator begin, Iterator end) {
    159     while (begin != end && begin != --end)
    160       swap(*begin++, *end);
    161   }
    162   template<typename Iterator1, typename Iterator2>
    163   constexpr bool equal(Iterator1 a, Iterator1 ae, Iterator2 b, Iterator2 be) {
    164     while (a != ae && b != be)
    165       if (*a++ != *b++)
    166         return false;
    167     return a == ae && b == be;
    168   }
    169   constexpr bool test1(int n) {
    170     char stuff[100] = "foobarfoo";
    171     const char stuff2[100] = "oofraboof";
    172     reverse(stuff, stuff + n); // expected-note {{cannot refer to element 101 of array of 100 elements}}
    173     return equal(stuff, stuff + n, stuff2, stuff2 + n);
    174   }
    175   static_assert(!test1(1), "");
    176   static_assert(test1(3), "");
    177   static_assert(!test1(6), "");
    178   static_assert(test1(9), "");
    179   static_assert(!test1(100), "");
    180   static_assert(!test1(101), ""); // expected-error {{constant expression}} expected-note {{in call to 'test1(101)'}}
    181 
    182   constexpr void f() { // expected-error{{constexpr function never produces a constant expression}} expected-note@+2{{assignment to dereferenced one-past-the-end pointer is not allowed in a constant expression}}
    183     char foo[10] = { "z" }; // expected-note {{here}}
    184     foo[10] = 'x'; // expected-warning {{past the end}}
    185   }
    186 }
    187 
    188 namespace array_resize {
    189   constexpr int do_stuff(int k1, int k2) {
    190     int arr[1234] = { 1, 2, 3, 4 };
    191     arr[k1] = 5; // expected-note {{past-the-end}} expected-note {{cannot refer to element 1235}} expected-note {{cannot refer to element -1}}
    192     return arr[k2];
    193   }
    194   static_assert(do_stuff(1, 2) == 3, "");
    195   static_assert(do_stuff(0, 0) == 5, "");
    196   static_assert(do_stuff(1233, 1233) == 5, "");
    197   static_assert(do_stuff(1233, 0) == 1, "");
    198   static_assert(do_stuff(1234, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}}
    199   static_assert(do_stuff(1235, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}}
    200   static_assert(do_stuff(-1, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}}
    201 }
    202 
    203 namespace potential_const_expr {
    204   constexpr void set(int &n) { n = 1; }
    205   constexpr int div_zero_1() { int z = 0; set(z); return 100 / z; } // no error
    206   constexpr int div_zero_2() { // expected-error {{never produces a constant expression}}
    207     int z = 0;
    208     return 100 / (set(z), 0); // expected-note {{division by zero}}
    209   }
    210   int n; // expected-note {{declared here}}
    211   constexpr int ref() { // expected-error {{never produces a constant expression}}
    212     int &r = n;
    213     return r; // expected-note {{read of non-const variable 'n'}}
    214   }
    215 }
    216 
    217 namespace subobject {
    218   union A { constexpr A() : y(5) {} int x, y; };
    219   struct B { A a; };
    220   struct C : B {};
    221   union D { constexpr D() : c() {} constexpr D(int n) : n(n) {} C c; int n; };
    222   constexpr void f(D &d) {
    223     d.c.a.y = 3;
    224     // expected-note@-1 {{cannot modify an object that is visible outside}}
    225     // expected-note@-2 {{assignment to member 'c' of union with active member 'n'}}
    226   }
    227   constexpr bool check(D &d) { return d.c.a.y == 3; }
    228 
    229   constexpr bool g() { D d; f(d); return d.c.a.y == 3; }
    230   static_assert(g(), "");
    231 
    232   D d;
    233   constexpr bool h() { f(d); return check(d); } // expected-note {{in call}}
    234   static_assert(h(), ""); // expected-error {{constant expression}} expected-note {{in call}}
    235 
    236   constexpr bool i() { D d(0); f(d); return check(d); } // expected-note {{in call}}
    237   static_assert(i(), ""); // expected-error {{constant expression}} expected-note {{in call}}
    238 
    239   constexpr bool j() { D d; d.c.a.x = 3; return check(d); } // expected-note {{assignment to member 'x' of union with active member 'y'}}
    240   static_assert(j(), ""); // expected-error {{constant expression}} expected-note {{in call}}
    241 }
    242 
    243 namespace lifetime {
    244   constexpr int &&id(int &&n) { return static_cast<int&&>(n); }
    245   constexpr int &&dead() { return id(0); } // expected-note {{temporary created here}}
    246   constexpr int bad() { int &&n = dead(); n = 1; return n; } // expected-note {{assignment to temporary whose lifetime has ended}}
    247   static_assert(bad(), ""); // expected-error {{constant expression}} expected-note {{in call}}
    248 }
    249 
    250 namespace const_modify {
    251   constexpr int modify(int &n) { return n = 1; } // expected-note 2 {{modification of object of const-qualified type 'const int'}}
    252   constexpr int test1() { int k = 0; return modify(k); }
    253   constexpr int test2() { const int k = 0; return modify(const_cast<int&>(k)); } // expected-note 2 {{in call}}
    254   static_assert(test1() == 1, "");
    255   static_assert(test2() == 1, ""); // expected-error {{constant expression}} expected-note {{in call}}
    256   constexpr int i = test2(); // expected-error {{constant expression}} expected-note {{in call}}
    257 }
    258 
    259 namespace null {
    260   constexpr int test(int *p) {
    261     return *p = 123; // expected-note {{assignment to dereferenced null pointer}}
    262   }
    263   static_assert(test(0), ""); // expected-error {{constant expression}} expected-note {{in call}}
    264 }
    265 
    266 namespace incdec {
    267   template<typename T> constexpr T &ref(T &&r) { return r; }
    268   template<typename T> constexpr T postinc(T &&r) { return (r++, r); }
    269   template<typename T> constexpr T postdec(T &&r) { return (r--, r); }
    270 
    271   static_assert(++ref(0) == 1, "");
    272   static_assert(ref(0)++ == 0, "");
    273   static_assert(postinc(0) == 1, "");
    274   static_assert(--ref(0) == -1, "");
    275   static_assert(ref(0)-- == 0, "");
    276   static_assert(postdec(0) == -1, "");
    277 
    278   constexpr int overflow_int_inc_1 = ref(0x7fffffff)++; // expected-error {{constant}} expected-note {{2147483648}}
    279   constexpr int overflow_int_inc_1_ok = ref(0x7ffffffe)++;
    280   constexpr int overflow_int_inc_2 = ++ref(0x7fffffff); // expected-error {{constant}} expected-note {{2147483648}}
    281   constexpr int overflow_int_inc_2_ok = ++ref(0x7ffffffe);
    282 
    283   // inc/dec on short can't overflow because we promote to int first
    284   static_assert(++ref<short>(0x7fff) == (int)0xffff8000u, "");
    285   static_assert(--ref<short>(0x8000) == 0x7fff, "");
    286 
    287   // inc on bool sets to true
    288   static_assert(++ref(false), ""); // expected-warning {{deprecated}}
    289   static_assert(++ref(true), ""); // expected-warning {{deprecated}}
    290 
    291   int arr[10];
    292   static_assert(++ref(&arr[0]) == &arr[1], "");
    293   static_assert(++ref(&arr[9]) == &arr[10], "");
    294   static_assert(++ref(&arr[10]) == &arr[11], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}}
    295   static_assert(ref(&arr[0])++ == &arr[0], "");
    296   static_assert(ref(&arr[10])++ == &arr[10], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}}
    297   static_assert(postinc(&arr[0]) == &arr[1], "");
    298   static_assert(--ref(&arr[10]) == &arr[9], "");
    299   static_assert(--ref(&arr[1]) == &arr[0], "");
    300   static_assert(--ref(&arr[0]) != &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}}
    301   static_assert(ref(&arr[1])-- == &arr[1], "");
    302   static_assert(ref(&arr[0])-- == &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}}
    303   static_assert(postdec(&arr[1]) == &arr[0], "");
    304 
    305   int x;
    306   static_assert(++ref(&x) == &x + 1, "");
    307 
    308   static_assert(++ref(0.0) == 1.0, "");
    309   static_assert(ref(0.0)++ == 0.0, "");
    310   static_assert(postinc(0.0) == 1.0, "");
    311   static_assert(--ref(0.0) == -1.0, "");
    312   static_assert(ref(0.0)-- == 0.0, "");
    313   static_assert(postdec(0.0) == -1.0, "");
    314 
    315   static_assert(++ref(1e100) == 1e100, "");
    316   static_assert(--ref(1e100) == 1e100, "");
    317 
    318   union U {
    319     int a, b;
    320   };
    321   constexpr int f(U u) {
    322     return ++u.b; // expected-note {{increment of member 'b' of union with active member 'a'}}
    323   }
    324   constexpr int wrong_member = f({0}); // expected-error {{constant}} expected-note {{in call to 'f({.a = 0})'}}
    325   constexpr int vol = --ref<volatile int>(0); // expected-error {{constant}} expected-note {{decrement of volatile-qualified}}
    326 
    327   constexpr int incr(int k) {
    328     int x = k;
    329     if (x++ == 100)
    330       return x;
    331     return incr(x);
    332   }
    333   static_assert(incr(0) == 101, "");
    334 }
    335 
    336 namespace compound_assign {
    337   constexpr bool test_int() {
    338     int a = 3;
    339     a += 6;
    340     if (a != 9) return false;
    341     a -= 2;
    342     if (a != 7) return false;
    343     a *= 3;
    344     if (a != 21) return false;
    345     if (&(a /= 10) != &a) return false;
    346     if (a != 2) return false;
    347     a <<= 3;
    348     if (a != 16) return false;
    349     a %= 6;
    350     if (a != 4) return false;
    351     a >>= 1;
    352     if (a != 2) return false;
    353     a ^= 10;
    354     if (a != 8) return false;
    355     a |= 5;
    356     if (a != 13) return false;
    357     a &= 14;
    358     if (a != 12) return false;
    359     return true;
    360   }
    361   static_assert(test_int(), "");
    362 
    363   constexpr bool test_float() {
    364     float f = 123.;
    365     f *= 2;
    366     if (f != 246.) return false;
    367     if ((f -= 0.5) != 245.5) return false;
    368     if (f != 245.5) return false;
    369     f /= 0.5;
    370     if (f != 491.) return false;
    371     f += -40;
    372     if (f != 451.) return false;
    373     return true;
    374   }
    375   static_assert(test_float(), "");
    376 
    377   constexpr bool test_ptr() {
    378     int arr[123] = {};
    379     int *p = arr;
    380     if ((p += 4) != &arr[4]) return false;
    381     if (p != &arr[4]) return false;
    382     p += -1;
    383     if (p != &arr[3]) return false;
    384     if ((p -= -10) != &arr[13]) return false;
    385     if (p != &arr[13]) return false;
    386     p -= 11;
    387     if (p != &arr[2]) return false;
    388     return true;
    389   }
    390   static_assert(test_ptr(), "");
    391 
    392   template<typename T>
    393   constexpr bool test_overflow() {
    394     T a = 1;
    395     while (a != a / 2)
    396       a *= 2; // expected-note {{value 2147483648 is outside the range}} expected-note {{ 9223372036854775808 }} expected-note {{floating point arithmetic produces an infinity}}
    397     return true;
    398   }
    399 
    400   static_assert(test_overflow<int>(), ""); // expected-error {{constant}} expected-note {{call}}
    401   static_assert(test_overflow<unsigned>(), ""); // ok, unsigned overflow is defined
    402   static_assert(test_overflow<short>(), ""); // ok, short is promoted to int before multiplication
    403   static_assert(test_overflow<unsigned short>(), ""); // ok
    404   static_assert(test_overflow<unsigned long long>(), ""); // ok
    405   static_assert(test_overflow<long long>(), ""); // expected-error {{constant}} expected-note {{call}}
    406   static_assert(test_overflow<float>(), ""); // expected-error {{constant}} expected-note {{call}}
    407 
    408   constexpr short test_promotion(short k) {
    409     short s = k;
    410     s *= s;
    411     return s;
    412   }
    413   static_assert(test_promotion(100) == 10000, "");
    414   static_assert(test_promotion(200) == -25536, "");
    415   static_assert(test_promotion(256) == 0, "");
    416 
    417   constexpr const char *test_bounds(const char *p, int o) {
    418     return p += o; // expected-note {{element 5 of}} expected-note {{element -1 of}} expected-note {{element 1000 of}}
    419   }
    420   static_assert(test_bounds("foo", 0)[0] == 'f', "");
    421   static_assert(test_bounds("foo", 3)[0] == 0, "");
    422   static_assert(test_bounds("foo", 4)[-3] == 'o', "");
    423   static_assert(test_bounds("foo" + 4, -4)[0] == 'f', "");
    424   static_assert(test_bounds("foo", 5) != 0, ""); // expected-error {{constant}} expected-note {{call}}
    425   static_assert(test_bounds("foo", -1) != 0, ""); // expected-error {{constant}} expected-note {{call}}
    426   static_assert(test_bounds("foo", 1000) != 0, ""); // expected-error {{constant}} expected-note {{call}}
    427 }
    428 
    429 namespace loops {
    430   constexpr int fib_loop(int a) {
    431     int f_k = 0, f_k_plus_one = 1;
    432     for (int k = 1; k != a; ++k) {
    433       int f_k_plus_two = f_k + f_k_plus_one;
    434       f_k = f_k_plus_one;
    435       f_k_plus_one = f_k_plus_two;
    436     }
    437     return f_k_plus_one;
    438   }
    439   static_assert(fib_loop(46) == 1836311903, "");
    440 
    441   constexpr bool breaks_work() {
    442     int a = 0;
    443     for (int n = 0; n != 100; ++n) {
    444       ++a;
    445       if (a == 5) continue;
    446       if ((a % 5) == 0) break;
    447     }
    448 
    449     int b = 0;
    450     while (b != 17) {
    451       ++b;
    452       if (b == 6) continue;
    453       if ((b % 6) == 0) break;
    454     }
    455 
    456     int c = 0;
    457     do {
    458       ++c;
    459       if (c == 7) continue;
    460       if ((c % 7) == 0) break;
    461     } while (c != 21);
    462 
    463     return a == 10 && b == 12 && c == 14;
    464   }
    465   static_assert(breaks_work(), "");
    466 
    467   void not_constexpr();
    468   constexpr bool no_cont_after_break() {
    469     for (;;) {
    470       break;
    471       not_constexpr();
    472     }
    473     while (true) {
    474       break;
    475       not_constexpr();
    476     }
    477     do {
    478       break;
    479       not_constexpr();
    480     } while (true);
    481     return true;
    482   }
    483   static_assert(no_cont_after_break(), "");
    484 
    485   constexpr bool cond() {
    486     for (int a = 1; bool b = a != 3; ++a) {
    487       if (!b)
    488         return false;
    489     }
    490     while (bool b = true) {
    491       b = false;
    492       break;
    493     }
    494     return true;
    495   }
    496   static_assert(cond(), "");
    497 
    498   constexpr int range_for() {
    499     int arr[] = { 1, 2, 3, 4, 5 };
    500     int sum = 0;
    501     for (int x : arr)
    502       sum += x;
    503     return sum;
    504   }
    505   static_assert(range_for() == 15, "");
    506 
    507   template<int...N> struct ints {};
    508   template<typename A, typename B> struct join_ints;
    509   template<int...As, int...Bs> struct join_ints<ints<As...>, ints<Bs...>> {
    510     using type = ints<As..., sizeof...(As) + Bs...>;
    511   };
    512   template<unsigned N> struct make_ints {
    513     using type = typename join_ints<typename make_ints<N/2>::type, typename make_ints<(N+1)/2>::type>::type;
    514   };
    515   template<> struct make_ints<0> { using type = ints<>; };
    516   template<> struct make_ints<1> { using type = ints<0>; };
    517 
    518   struct ignore { template<typename ...Ts> constexpr ignore(Ts &&...) {} };
    519 
    520   template<typename T, unsigned N> struct array {
    521     constexpr array() : arr{} {}
    522     template<typename ...X>
    523     constexpr array(X ...x) : arr{} {
    524       init(typename make_ints<sizeof...(X)>::type{}, x...);
    525     }
    526     template<int ...I, typename ...X> constexpr void init(ints<I...>, X ...x) {
    527       ignore{arr[I] = x ...};
    528     }
    529     T arr[N];
    530     struct iterator {
    531       T *p;
    532       constexpr explicit iterator(T *p) : p(p) {}
    533       constexpr bool operator!=(iterator o) { return p != o.p; }
    534       constexpr iterator &operator++() { ++p; return *this; }
    535       constexpr T &operator*() { return *p; }
    536     };
    537     constexpr iterator begin() { return iterator(arr); }
    538     constexpr iterator end() { return iterator(arr + N); }
    539   };
    540 
    541   constexpr int range_for_2() {
    542     array<int, 5> arr { 1, 2, 3, 4, 5 };
    543     int sum = 0;
    544     for (int k : arr) {
    545       sum += k;
    546       if (sum > 8) break;
    547     }
    548     return sum;
    549   }
    550   static_assert(range_for_2() == 10, "");
    551 }
    552 
    553 namespace assignment_op {
    554   struct A {
    555     constexpr A() : n(5) {}
    556     int n;
    557     struct B {
    558       int k = 1;
    559       union U {
    560         constexpr U() : y(4) {}
    561         int x;
    562         int y;
    563       } u;
    564     } b;
    565   };
    566   constexpr bool testA() {
    567     A a, b;
    568     a.n = 7;
    569     a.b.u.y = 5;
    570     b = a;
    571     return b.n == 7 && b.b.u.y == 5 && b.b.k == 1;
    572   }
    573   static_assert(testA(), "");
    574 
    575   struct B {
    576     bool assigned = false;
    577     constexpr B &operator=(const B&) {
    578       assigned = true;
    579       return *this;
    580     }
    581   };
    582   struct C : B {
    583     B b;
    584     int n = 5;
    585   };
    586   constexpr bool testC() {
    587     C c, d;
    588     c.n = 7;
    589     d = c;
    590     c.n = 3;
    591     return d.n == 7 && d.assigned && d.b.assigned;
    592   }
    593   static_assert(testC(), "");
    594 }
    595 
    596 namespace switch_stmt {
    597   constexpr int f(char k) {
    598     bool b = false;
    599     int z = 6;
    600     switch (k) {
    601       return -1;
    602     case 0:
    603       if (false) {
    604       case 1:
    605         z = 1;
    606         for (; b;) {
    607           return 5;
    608           while (0)
    609             case 2: return 2;
    610           case 7: z = 7;
    611           do case 6: {
    612             return z;
    613             if (false)
    614               case 3: return 3;
    615             case 4: z = 4;
    616           } while (1);
    617           case 5: b = true;
    618           case 9: z = 9;
    619         }
    620         return z;
    621       } else if (false) case 8: z = 8;
    622       else if (false) {
    623       case 10:
    624         z = -10;
    625         break;
    626       }
    627       else z = 0;
    628       return z;
    629     default:
    630       return -1;
    631     }
    632     return -z;
    633   }
    634   static_assert(f(0) == 0, "");
    635   static_assert(f(1) == 1, "");
    636   static_assert(f(2) == 2, "");
    637   static_assert(f(3) == 3, "");
    638   static_assert(f(4) == 4, "");
    639   static_assert(f(5) == 5, "");
    640   static_assert(f(6) == 6, "");
    641   static_assert(f(7) == 7, "");
    642   static_assert(f(8) == 8, "");
    643   static_assert(f(9) == 9, "");
    644   static_assert(f(10) == 10, "");
    645 
    646   // Check that we can continue an outer loop from within a switch.
    647   constexpr bool contin() {
    648     for (int n = 0; n != 10; ++n) {
    649       switch (n) {
    650       case 0:
    651         ++n;
    652         continue;
    653       case 1:
    654         return false;
    655       case 2:
    656         return true;
    657       }
    658     }
    659     return false;
    660   }
    661   static_assert(contin(), "");
    662 
    663   constexpr bool switch_into_for() {
    664     int n = 0;
    665     switch (n) {
    666       for (; n == 1; ++n) {
    667         return n == 1;
    668       case 0: ;
    669       }
    670     }
    671     return false;
    672   }
    673   static_assert(switch_into_for(), "");
    674 
    675   constexpr void duff_copy(char *a, const char *b, int n) {
    676     switch ((n - 1) % 8 + 1) {
    677       for ( ; n; n = (n - 1) & ~7) {
    678       case 8: a[n-8] = b[n-8];
    679       case 7: a[n-7] = b[n-7];
    680       case 6: a[n-6] = b[n-6];
    681       case 5: a[n-5] = b[n-5];
    682       case 4: a[n-4] = b[n-4];
    683       case 3: a[n-3] = b[n-3];
    684       case 2: a[n-2] = b[n-2];
    685       case 1: a[n-1] = b[n-1];
    686       }
    687       case 0: ;
    688     }
    689   }
    690 
    691   constexpr bool test_copy(const char *str, int n) {
    692     char buffer[16] = {};
    693     duff_copy(buffer, str, n);
    694     for (int i = 0; i != sizeof(buffer); ++i)
    695       if (buffer[i] != (i < n ? str[i] : 0))
    696         return false;
    697     return true;
    698   }
    699   static_assert(test_copy("foo", 0), "");
    700   static_assert(test_copy("foo", 1), "");
    701   static_assert(test_copy("foo", 2), "");
    702   static_assert(test_copy("hello world", 0), "");
    703   static_assert(test_copy("hello world", 7), "");
    704   static_assert(test_copy("hello world", 8), "");
    705   static_assert(test_copy("hello world", 9), "");
    706   static_assert(test_copy("hello world", 10), "");
    707   static_assert(test_copy("hello world", 10), "");
    708 }
    709 
    710 namespace deduced_return_type {
    711   constexpr auto f() { return 0; }
    712   template<typename T> constexpr auto g(T t) { return t; }
    713   static_assert(f() == 0, "");
    714   static_assert(g(true), "");
    715 }
    716 
    717 namespace modify_temporary_during_construction {
    718   struct A { int &&temporary; int x; int y; };
    719   constexpr int f(int &r) { r *= 9; return r - 12; }
    720   constexpr A a = { 6, f(a.temporary), a.temporary }; // expected-note {{temporary created here}}
    721   static_assert(a.x == 42, "");
    722   static_assert(a.y == 54, "");
    723   constexpr int k = a.temporary++; // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}}
    724 }
    725 
    726 namespace std {
    727   typedef decltype(sizeof(int)) size_t;
    728 
    729   template <class _E>
    730   class initializer_list
    731   {
    732     const _E* __begin_;
    733     size_t    __size_;
    734 
    735     constexpr initializer_list(const _E* __b, size_t __s)
    736       : __begin_(__b),
    737         __size_(__s)
    738     {}
    739 
    740   public:
    741     typedef _E        value_type;
    742     typedef const _E& reference;
    743     typedef const _E& const_reference;
    744     typedef size_t    size_type;
    745 
    746     typedef const _E* iterator;
    747     typedef const _E* const_iterator;
    748 
    749     constexpr initializer_list() : __begin_(nullptr), __size_(0) {}
    750 
    751     constexpr size_t    size()  const {return __size_;}
    752     constexpr const _E* begin() const {return __begin_;}
    753     constexpr const _E* end()   const {return __begin_ + __size_;}
    754   };
    755 }
    756 
    757 namespace InitializerList {
    758   constexpr int sum(std::initializer_list<int> ints) {
    759     int total = 0;
    760     for (int n : ints) total += n;
    761     return total;
    762   }
    763   static_assert(sum({1, 2, 3, 4, 5}) == 15, "");
    764 }
    765 
    766 namespace StmtExpr {
    767   constexpr int f(int k) {
    768     switch (k) {
    769     case 0:
    770       return 0;
    771 
    772       ({
    773         case 1: // expected-note {{not supported}}
    774           return 1;
    775       });
    776     }
    777   }
    778   static_assert(f(1) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}}
    779 
    780   constexpr int g() { // expected-error {{never produces a constant}}
    781     return ({ int n; n; }); // expected-note {{object of type 'int' is not initialized}}
    782   }
    783 
    784   // FIXME: We should handle the void statement expression case.
    785   constexpr int h() { // expected-error {{never produces a constant}}
    786     ({ if (true) {} }); // expected-note {{not supported}}
    787     return 0;
    788   }
    789 }
    790 
    791 namespace VirtualFromBase {
    792   struct S1 {
    793     virtual int f() const;
    794   };
    795   struct S2 {
    796     virtual int f();
    797   };
    798   template <typename T> struct X : T {
    799     constexpr X() {}
    800     double d = 0.0;
    801     constexpr int f() { return sizeof(T); }
    802   };
    803 
    804   // Non-virtual f(), OK.
    805   constexpr X<X<S1>> xxs1;
    806   constexpr X<S1> *p = const_cast<X<X<S1>>*>(&xxs1);
    807   static_assert(p->f() == sizeof(S1), "");
    808 
    809   // Virtual f(), not OK.
    810   constexpr X<X<S2>> xxs2;
    811   constexpr X<S2> *q = const_cast<X<X<S2>>*>(&xxs2);
    812   static_assert(q->f() == sizeof(X<S2>), ""); // expected-error {{constant expression}} expected-note {{virtual function call}}
    813 }
    814 
    815 namespace Lifetime {
    816   constexpr int &get(int &&r) { return r; }
    817   constexpr int f() {
    818     int &r = get(123);
    819     return r; // expected-note {{read of object outside its lifetime}}
    820   }
    821   static_assert(f() == 123, ""); // expected-error {{constant expression}} expected-note {{in call}}
    822 
    823   constexpr int g() {
    824     int *p = 0;
    825     {
    826       int n = 0;
    827       p = &n;
    828       n = 42;
    829     }
    830     *p = 123; // expected-note {{assignment to object outside its lifetime}}
    831     return *p;
    832   }
    833   static_assert(g() == 42, ""); // expected-error {{constant expression}} expected-note {{in call}}
    834 
    835   constexpr int h(int n) {
    836     int *p[4] = {};
    837     int &&r = 1;
    838     p[0] = &r;
    839     while (int a = 1) {
    840       p[1] = &a;
    841       for (int b = 1; int c = 1; ) {
    842         p[2] = &b, p[3] = &c;
    843         break;
    844       }
    845       break;
    846     }
    847     *p[n] = 0; // expected-note 3{{assignment to object outside its lifetime}}
    848     return *p[n];
    849   }
    850   static_assert(h(0) == 0, ""); // ok, lifetime-extended
    851   static_assert(h(1) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
    852   static_assert(h(2) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
    853   static_assert(h(3) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
    854 
    855   // FIXME: This function should be treated as non-constant.
    856   constexpr void lifetime_versus_loops() {
    857     int *p = 0;
    858     for (int i = 0; i != 2; ++i) {
    859       int *q = p;
    860       int n = 0;
    861       p = &n;
    862       if (i)
    863         // This modifies the 'n' from the previous iteration of the loop outside
    864         // its lifetime.
    865         ++*q;
    866     }
    867   }
    868   static_assert((lifetime_versus_loops(), true), "");
    869 }
    870 
    871 namespace Bitfields {
    872   struct A {
    873     bool b : 1;
    874     int n : 4;
    875     unsigned u : 5;
    876   };
    877   constexpr bool test() {
    878     A a {};
    879     a.b += 2;
    880     --a.n;
    881     --a.u;
    882     a.n = -a.n * 3;
    883     return a.b == false && a.n == 3 && a.u == 31;
    884   }
    885   static_assert(test(), "");
    886 }
    887 
    888 namespace PR17615 {
    889   struct A {
    890     int &&r;
    891     constexpr A(int &&r) : r(static_cast<int &&>(r)) {}
    892     constexpr A() : A(0) {
    893       (void)+r; // expected-note {{outside its lifetime}}
    894     }
    895   };
    896   constexpr int k = A().r; // expected-error {{constant expression}} expected-note {{in call to}}
    897 }
    898 
    899 namespace PR17331 {
    900   template<typename T, unsigned int N>
    901   constexpr T sum(const T (&arr)[N]) {
    902     T result = 0;
    903     for (T i : arr)
    904       result += i;
    905     return result;
    906   }
    907 
    908   constexpr int ARR[] = { 1, 2, 3, 4, 5 };
    909   static_assert(sum(ARR) == 15, "");
    910 }
    911 
    912 namespace EmptyClass {
    913   struct E1 {} e1;
    914   union E2 {} e2; // expected-note 4{{here}}
    915   struct E3 : E1 {} e3;
    916 
    917   template<typename E>
    918   constexpr int f(E &a, int kind) {
    919     switch (kind) {
    920     case 0: { E e(a); return 0; } // expected-note {{read}} expected-note {{in call}}
    921     case 1: { E e(static_cast<E&&>(a)); return 0; } // expected-note {{read}} expected-note {{in call}}
    922     case 2: { E e; e = a; return 0; } // expected-note {{read}} expected-note {{in call}}
    923     case 3: { E e; e = static_cast<E&&>(a); return 0; } // expected-note {{read}} expected-note {{in call}}
    924     }
    925   }
    926   constexpr int test1 = f(e1, 0);
    927   constexpr int test2 = f(e2, 0); // expected-error {{constant expression}} expected-note {{in call}}
    928   constexpr int test3 = f(e3, 0);
    929   constexpr int test4 = f(e1, 1);
    930   constexpr int test5 = f(e2, 1); // expected-error {{constant expression}} expected-note {{in call}}
    931   constexpr int test6 = f(e3, 1);
    932   constexpr int test7 = f(e1, 2);
    933   constexpr int test8 = f(e2, 2); // expected-error {{constant expression}} expected-note {{in call}}
    934   constexpr int test9 = f(e3, 2);
    935   constexpr int testa = f(e1, 3);
    936   constexpr int testb = f(e2, 3); // expected-error {{constant expression}} expected-note {{in call}}
    937   constexpr int testc = f(e3, 3);
    938 }
    939 
    940 namespace SpeculativeEvalWrites {
    941   // Ensure that we don't try to speculatively evaluate writes.
    942   constexpr int f() {
    943     int i = 0;
    944     int a = 0;
    945     // __builtin_object_size speculatively evaluates its first argument.
    946     __builtin_object_size((i = 1, &a), 0);
    947     return i;
    948   }
    949 
    950   static_assert(!f(), "");
    951 }
    952 
    953 namespace PR27989 {
    954   constexpr int f(int n) {
    955     int a = (n = 1, 0);
    956     return n;
    957   }
    958   static_assert(f(0) == 1, "");
    959 }
    960