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