constant-expression-cxx1y.cpp revision 284b3cbfd1cd5b6585437fbb8b95fe136f273efb
1a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith// RUN: %clang_cc1 -std=c++1y -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu 2a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 3a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstruct S { 4a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith // dummy ctor to make this a literal type 5a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith constexpr S(int); 6a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 7a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith S(); 8a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 9a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith int arr[10]; 10a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 11a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith constexpr int &get(int n) { return arr[n]; } 12a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith constexpr const int &get(int n) const { return arr[n]; } 13a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith}; 14a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 15a10b97898ee6339c3110e6ca33f178ff52f05238Richard SmithS s = S(); 16a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconst S &sr = s; 17a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstatic_assert(&s.get(4) - &sr.get(2) == 2, ""); 18a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 19a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith// Compound-statements can be used in constexpr functions. 20a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr int e() {{{{}} return 5; }} 21a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstatic_assert(e() == 5, ""); 22a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 23a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith// Types can be defined in constexpr functions. 24a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr int f() { 25a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith enum E { e1, e2, e3 }; 26a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 27a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith struct S { 28a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith constexpr S(E e) : e(e) {} 29a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith constexpr int get() { return e; } 30a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith E e; 31a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith }; 32a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 33a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return S(e2).get(); 34a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith} 35a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstatic_assert(f() == 1, ""); 36a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 37a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith// Variables can be declared in constexpr functions. 38a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr int g(int k) { 39a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith const int n = 9; 40a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith int k2 = k * k; 41a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith int k3 = k2 * k; 42a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return 3 * k3 + 5 * k2 + n * k - 20; 43a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith} 44a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstatic_assert(g(2) == 42, ""); 45a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr int h(int n) { 46a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith static const int m = n; // expected-error {{static variable not permitted in a constexpr function}} 47a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return m; 48a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith} 49a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr int i(int n) { 50a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith thread_local const int m = n; // expected-error {{thread_local variable not permitted in a constexpr function}} 51a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return m; 52a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith} 53a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 54a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith// if-statements can be used in constexpr functions. 55a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr int j(int k) { 56a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith if (k == 5) 57a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return 1; 58a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith if (k == 1) 59a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return 5; 60a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith else { 61a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith if (int n = 2 * k - 4) { 62a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return n + 1; 63a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return 2; 64a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith } 65a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith } 66a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith} // expected-note 2{{control reached end of constexpr function}} 67a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstatic_assert(j(0) == -3, ""); 68a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstatic_assert(j(1) == 5, ""); 69a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstatic_assert(j(2), ""); // expected-error {{constant expression}} expected-note {{in call to 'j(2)'}} 70a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstatic_assert(j(3) == 3, ""); 71a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstatic_assert(j(4) == 5, ""); 72a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstatic_assert(j(5) == 1, ""); 73a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 74a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith// There can be 0 return-statements. 75a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr void k() { 76a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith} 77a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 78a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith// If the return type is not 'void', no return statements => never a constant 79a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith// expression, so still diagnose that case. 80a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith[[noreturn]] constexpr int fn() { // expected-error {{no return statement in constexpr function}} 81a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith fn(); 82a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith} 83a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 84a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith// We evaluate the body of a constexpr constructor, to check for side-effects. 85a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstruct U { 86a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith constexpr U(int n) { 87a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith if (j(n)) {} // expected-note {{in call to 'j(2)'}} 88a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith } 89a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith}; 90a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr U u1{1}; 91a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr U u2{2}; // expected-error {{constant expression}} expected-note {{in call to 'U(2)'}} 92a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 93a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith// We allow expression-statements. 94a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr int l(bool b) { 95a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith if (b) 96a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith throw "invalid value for b!"; // expected-note {{subexpression not valid}} 97a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return 5; 98a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith} 99a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstatic_assert(l(false) == 5, ""); 100a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithstatic_assert(l(true), ""); // expected-error {{constant expression}} expected-note {{in call to 'l(true)'}} 101a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 102a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith// Potential constant expression checking is still applied where possible. 103a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr int htonl(int x) { // expected-error {{never produces a constant expression}} 104a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith typedef unsigned char uchar; 105a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith uchar arr[4] = { uchar(x >> 24), uchar(x >> 16), uchar(x >> 8), uchar(x) }; 106a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return *reinterpret_cast<int*>(arr); // expected-note {{reinterpret_cast is not allowed in a constant expression}} 107a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith} 108a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 109a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr int maybe_htonl(bool isBigEndian, int x) { 110a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith if (isBigEndian) 111a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return x; 112a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 113a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith typedef unsigned char uchar; 114a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith uchar arr[4] = { uchar(x >> 24), uchar(x >> 16), uchar(x >> 8), uchar(x) }; 115a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return *reinterpret_cast<int*>(arr); // expected-note {{reinterpret_cast is not allowed in a constant expression}} 116a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith} 117a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 118a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr int swapped = maybe_htonl(false, 123); // expected-error {{constant expression}} expected-note {{in call}} 119a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith 120a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithnamespace NS { 121a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith constexpr int n = 0; 122a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith} 123a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smithconstexpr int namespace_alias() { 124a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith namespace N = NS; 125a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith return N::n; 126a10b97898ee6339c3110e6ca33f178ff52f05238Richard Smith} 127bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 128bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smithnamespace assign { 129bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int a = 0; 130bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith const int b = 0; 131bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith int c = 0; // expected-note 2{{here}} 132bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 133bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr void set(const int &a, int b) { 134bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith const_cast<int&>(a) = b; // expected-note 2{{constant expression cannot modify an object that is visible outside that expression}} 135bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith } 136bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int wrap(int a, int b) { 137bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith set(a, b); 138bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith return a; 139bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith } 140bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 141bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert((set(a, 1), a) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(a, 1)'}} 142bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert((set(b, 1), b) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(b, 1)'}} 143bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert((set(c, 1), c) == 1, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}} 144bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 145bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(wrap(a, 1) == 1, ""); 146bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(wrap(b, 1) == 1, ""); 147bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(wrap(c, 1) == 1, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}} 148bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith} 149bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 150bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smithnamespace string_assign { 151bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith template<typename T> 152bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr void swap(T &a, T &b) { 153bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith T tmp = a; 154bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith a = b; 155bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith b = tmp; 156bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith } 157bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith template<typename Iterator> 158bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr void reverse(Iterator begin, Iterator end) { 159bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith while (begin != end && begin != --end) 160bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith swap(*begin++, *end); 161bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith } 162bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith template<typename Iterator1, typename Iterator2> 163bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr bool equal(Iterator1 a, Iterator1 ae, Iterator2 b, Iterator2 be) { 164ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith while (a != ae && b != be) 1655528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith if (*a++ != *b++) 166bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith return false; 167bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith return a == ae && b == be; 168bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith } 169bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr bool test1(int n) { 170bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith char stuff[100] = "foobarfoo"; 171bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith const char stuff2[100] = "oofraboof"; 172bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith reverse(stuff, stuff + n); // expected-note {{cannot refer to element 101 of array of 100 elements}} 173bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith return equal(stuff, stuff + n, stuff2, stuff2 + n); 174bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith } 175bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(!test1(1), ""); 176bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(test1(3), ""); 177bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(!test1(6), ""); 178bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(test1(9), ""); 179bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(!test1(100), ""); 180bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(!test1(101), ""); // expected-error {{constant expression}} expected-note {{in call to 'test1(101)'}} 181bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 182bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith // FIXME: We should be able to reject this before it's called 183bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr void f() { 184bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith char foo[10] = { "z" }; // expected-note {{here}} 185bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith foo[10] = 'x'; // expected-warning {{past the end}} expected-note {{assignment to dereferenced one-past-the-end pointer}} 186bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith } 187bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int k = (f(), 0); // expected-error {{constant expression}} expected-note {{in call}} 188bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith} 189bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 190bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smithnamespace array_resize { 191bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int do_stuff(int k1, int k2) { 192bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith int arr[1234] = { 1, 2, 3, 4 }; 193bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith arr[k1] = 5; // expected-note {{past-the-end}} expected-note {{cannot refer to element 1235}} expected-note {{cannot refer to element -1}} 194bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith return arr[k2]; 195bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith } 196bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(do_stuff(1, 2) == 3, ""); 197bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(do_stuff(0, 0) == 5, ""); 198bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(do_stuff(1233, 1233) == 5, ""); 199bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(do_stuff(1233, 0) == 1, ""); 200bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(do_stuff(1234, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 201bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(do_stuff(1235, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 202bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(do_stuff(-1, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 203bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith} 204bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 205bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smithnamespace potential_const_expr { 206bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr void set(int &n) { n = 1; } 207bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int div_zero_1() { int z = 0; set(z); return 100 / z; } // no error 208bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int div_zero_2() { // expected-error {{never produces a constant expression}} 209bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith int z = 0; 210bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith return 100 / (set(z), 0); // expected-note {{division by zero}} 211bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith } 212b476a14e9b35ef2448b42b033e1f0cceaa3f2778Richard Smith int n; // expected-note {{declared here}} 213b476a14e9b35ef2448b42b033e1f0cceaa3f2778Richard Smith constexpr int ref() { // expected-error {{never produces a constant expression}} 214b476a14e9b35ef2448b42b033e1f0cceaa3f2778Richard Smith int &r = n; 215b476a14e9b35ef2448b42b033e1f0cceaa3f2778Richard Smith return r; // expected-note {{read of non-const variable 'n'}} 216b476a14e9b35ef2448b42b033e1f0cceaa3f2778Richard Smith } 217bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith} 218bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 219bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smithnamespace subobject { 220bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith union A { constexpr A() : y(5) {} int x, y; }; 221bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith struct B { A a; }; 222bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith struct C : B {}; 223bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith union D { constexpr D() : c() {} constexpr D(int n) : n(n) {} C c; int n; }; 224bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr void f(D &d) { 225bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith d.c.a.y = 3; 226bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith // expected-note@-1 {{cannot modify an object that is visible outside}} 227bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith // expected-note@-2 {{assignment to member 'c' of union with active member 'n'}} 228bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith } 229bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr bool check(D &d) { return d.c.a.y == 3; } 230bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 231bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr bool g() { D d; f(d); return d.c.a.y == 3; } 232bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(g(), ""); 233bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 234bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith D d; 235bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr bool h() { f(d); return check(d); } // expected-note {{in call}} 236bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(h(), ""); // expected-error {{constant expression}} expected-note {{in call}} 237bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 238bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr bool i() { D d(0); f(d); return check(d); } // expected-note {{in call}} 239bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(i(), ""); // expected-error {{constant expression}} expected-note {{in call}} 240bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 241bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 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'}} 242bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(j(), ""); // expected-error {{constant expression}} expected-note {{in call}} 243bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith} 244bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 245bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smithnamespace lifetime { 246bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int &&id(int &&n) { return static_cast<int&&>(n); } 247bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int &&dead() { return id(0); } // expected-note {{temporary created here}} 248bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int bad() { int &&n = dead(); n = 1; return n; } // expected-note {{assignment to temporary whose lifetime has ended}} 249bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(bad(), ""); // expected-error {{constant expression}} expected-note {{in call}} 250bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith} 251bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 252bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smithnamespace const_modify { 253bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int modify(int &n) { return n = 1; } // expected-note {{modification of object of const-qualified type 'const int'}} 254bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int test1() { int k = 0; return modify(k); } 255bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int test2() { const int k = 0; return modify(const_cast<int&>(k)); } // expected-note {{in call}} 256bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(test1() == 1, ""); 257bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(test2() == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 258bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith} 259bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith 260bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smithnamespace null { 261bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith constexpr int test(int *p) { 262bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith return *p = 123; // expected-note {{assignment to dereferenced null pointer}} 263bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith } 264bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith static_assert(test(0), ""); // expected-error {{constant expression}} expected-note {{in call}} 265bebf5b1bcfbf591dd3cd80c4aebd6486bb34f41cRichard Smith} 2665528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith 2675528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smithnamespace incdec { 2685528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith template<typename T> constexpr T &ref(T &&r) { return r; } 2695528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith template<typename T> constexpr T postinc(T &&r) { return (r++, r); } 2705528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith template<typename T> constexpr T postdec(T &&r) { return (r--, r); } 2715528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith 2725528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(++ref(0) == 1, ""); 2735528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(ref(0)++ == 0, ""); 2745528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(postinc(0) == 1, ""); 2755528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(--ref(0) == -1, ""); 2765528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(ref(0)-- == 0, ""); 2775528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(postdec(0) == -1, ""); 2785528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith 2795528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith constexpr int overflow_int_inc_1 = ref(0x7fffffff)++; // expected-error {{constant}} expected-note {{2147483648}} 2805528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith constexpr int overflow_int_inc_1_ok = ref(0x7ffffffe)++; 2815528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith constexpr int overflow_int_inc_2 = ++ref(0x7fffffff); // expected-error {{constant}} expected-note {{2147483648}} 2825528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith constexpr int overflow_int_inc_2_ok = ++ref(0x7ffffffe); 2835528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith 2845528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith // inc/dec on short can't overflow because we promote to int first 2855528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(++ref<short>(0x7fff) == (int)0xffff8000u, ""); 2865528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(--ref<short>(0x8000) == 0x7fff, ""); 2875528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith 2885528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith // inc on bool sets to true 2895528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(++ref(false), ""); // expected-warning {{deprecated}} 2905528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(++ref(true), ""); // expected-warning {{deprecated}} 2915528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith 2925528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith int arr[10]; 2935528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(++ref(&arr[0]) == &arr[1], ""); 2945528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(++ref(&arr[9]) == &arr[10], ""); 2955528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(++ref(&arr[10]) == &arr[11], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}} 2965528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(ref(&arr[0])++ == &arr[0], ""); 2975528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(ref(&arr[10])++ == &arr[10], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}} 2985528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(postinc(&arr[0]) == &arr[1], ""); 2995528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(--ref(&arr[10]) == &arr[9], ""); 3005528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(--ref(&arr[1]) == &arr[0], ""); 3015528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(--ref(&arr[0]) != &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}} 3025528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(ref(&arr[1])-- == &arr[1], ""); 3035528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(ref(&arr[0])-- == &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}} 3045528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(postdec(&arr[1]) == &arr[0], ""); 3055528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith 3065528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith int x; 3075528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(++ref(&x) == &x + 1, ""); 3085528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith 3095528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(++ref(0.0) == 1.0, ""); 3105528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(ref(0.0)++ == 0.0, ""); 3115528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(postinc(0.0) == 1.0, ""); 3125528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(--ref(0.0) == -1.0, ""); 3135528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(ref(0.0)-- == 0.0, ""); 3145528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(postdec(0.0) == -1.0, ""); 3155528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith 3165528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(++ref(1e100) == 1e100, ""); 3175528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(--ref(1e100) == 1e100, ""); 3185528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith 3195528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith union U { 3205528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith int a, b; 3215528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith }; 3225528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith constexpr int f(U u) { 3235528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith return ++u.b; // expected-note {{increment of member 'b' of union with active member 'a'}} 3245528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith } 3255528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith constexpr int wrong_member = f({0}); // expected-error {{constant}} expected-note {{in call to 'f({.a = 0})'}} 3265528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith constexpr int vol = --ref<volatile int>(0); // expected-error {{constant}} expected-note {{decrement of volatile-qualified}} 3275528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith 3285528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith constexpr int incr(int k) { 3295528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith int x = k; 3305528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith if (x++ == 100) 3315528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith return x; 3325528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith return incr(x); 3335528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith } 3345528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith static_assert(incr(0) == 101, ""); 3355528ac9f40ec6cb54e7096908bf2beeed511bce4Richard Smith} 336ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith 337d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smithnamespace compound_assign { 338d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith constexpr bool test_int() { 339d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith int a = 3; 340d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith a += 6; 341a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (a != 9) return false; 342d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith a -= 2; 343a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (a != 7) return false; 344d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith a *= 3; 345a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (a != 21) return false; 346a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (&(a /= 10) != &a) return false; 347a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (a != 2) return false; 348d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith a <<= 3; 349a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (a != 16) return false; 350d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith a %= 6; 351a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (a != 4) return false; 352d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith a >>= 1; 353a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (a != 2) return false; 354d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith a ^= 10; 355a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (a != 8) return false; 356d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith a |= 5; 357a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (a != 13) return false; 358d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith a &= 14; 359a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (a != 12) return false; 360d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith return true; 361d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith } 362d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith static_assert(test_int(), ""); 363d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith 364a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith constexpr bool test_float() { 365a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith float f = 123.; 366a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith f *= 2; 367a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (f != 246.) return false; 368a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if ((f -= 0.5) != 245.5) return false; 369a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (f != 245.5) return false; 370a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith f /= 0.5; 371a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (f != 491.) return false; 372a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith f += -40; 373a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (f != 451.) return false; 374a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith return true; 375a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith } 376a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith static_assert(test_float(), ""); 377a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith 378a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith constexpr bool test_ptr() { 379a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith int arr[123] = {}; 380a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith int *p = arr; 381a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if ((p += 4) != &arr[4]) return false; 382a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (p != &arr[4]) return false; 383a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith p += -1; 384a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (p != &arr[3]) return false; 385a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if ((p -= -10) != &arr[13]) return false; 386a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (p != &arr[13]) return false; 387a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith p -= 11; 388a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith if (p != &arr[2]) return false; 389a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith return true; 390a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith } 391a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith static_assert(test_ptr(), ""); 392a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith 393d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith template<typename T> 394d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith constexpr bool test_overflow() { 395d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith T a = 1; 396a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith while (a != a / 2) 397a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith a *= 2; // expected-note {{value 2147483648 is outside the range}} expected-note {{ 9223372036854775808 }} expected-note {{floating point arithmetic produces an infinity}} 398d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith return true; 399d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith } 400d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith 401d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith static_assert(test_overflow<int>(), ""); // expected-error {{constant}} expected-note {{call}} 402d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith static_assert(test_overflow<unsigned>(), ""); // ok, unsigned overflow is defined 403d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith static_assert(test_overflow<short>(), ""); // ok, short is promoted to int before multiplication 404d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith static_assert(test_overflow<unsigned short>(), ""); // ok 405d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith static_assert(test_overflow<unsigned long long>(), ""); // ok 406d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith static_assert(test_overflow<long long>(), ""); // expected-error {{constant}} expected-note {{call}} 407a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith static_assert(test_overflow<float>(), ""); // expected-error {{constant}} expected-note {{call}} 408d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith 409d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith constexpr short test_promotion(short k) { 410d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith short s = k; 411d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith s *= s; 412d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith return s; 413d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith } 414d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith static_assert(test_promotion(100) == 10000, ""); 415d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith static_assert(test_promotion(200) == -25536, ""); 416d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith static_assert(test_promotion(256) == 0, ""); 417a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith 418a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith constexpr const char *test_bounds(const char *p, int o) { 419a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith return p += o; // expected-note {{element 5 of}} expected-note {{element -1 of}} expected-note {{element 1000 of}} 420a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith } 421a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith static_assert(test_bounds("foo", 0)[0] == 'f', ""); 422a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith static_assert(test_bounds("foo", 3)[0] == 0, ""); 423a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith static_assert(test_bounds("foo", 4)[-3] == 'o', ""); 424a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith static_assert(test_bounds("foo" + 4, -4)[0] == 'f', ""); 425a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith static_assert(test_bounds("foo", 5) != 0, ""); // expected-error {{constant}} expected-note {{call}} 426a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith static_assert(test_bounds("foo", -1) != 0, ""); // expected-error {{constant}} expected-note {{call}} 427a49a7fe2a7c1881402be25ca9124d3883637198fRichard Smith static_assert(test_bounds("foo", 1000) != 0, ""); // expected-error {{constant}} expected-note {{call}} 428d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith} 429d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith 430ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smithnamespace loops { 431ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith constexpr int fib_loop(int a) { 432ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith int f_k = 0, f_k_plus_one = 1; 433ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith for (int k = 1; k != a; ++k) { 434ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith int f_k_plus_two = f_k + f_k_plus_one; 435ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith f_k = f_k_plus_one; 436ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith f_k_plus_one = f_k_plus_two; 437ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } 438ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith return f_k_plus_one; 439ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } 440ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith static_assert(fib_loop(46) == 1836311903, ""); 441ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith 442ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith constexpr bool breaks_work() { 443ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith int a = 0; 444ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith for (int n = 0; n != 100; ++n) { 445ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith ++a; 446ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith if (a == 5) continue; 447ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith if ((a % 5) == 0) break; 448ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } 449ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith 450ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith int b = 0; 451ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith while (b != 17) { 452ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith ++b; 453ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith if (b == 6) continue; 454ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith if ((b % 6) == 0) break; 455ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } 456ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith 457ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith int c = 0; 458ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith do { 459ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith ++c; 460ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith if (c == 7) continue; 461ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith if ((c % 7) == 0) break; 462ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } while (c != 21); 463ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith 464ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith return a == 10 && b == 12 & c == 14; 465ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } 466ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith static_assert(breaks_work(), ""); 467ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith 468ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith void not_constexpr(); 469ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith constexpr bool no_cont_after_break() { 470ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith for (;;) { 471ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith break; 472ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith not_constexpr(); 473ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } 474ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith while (true) { 475ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith break; 476ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith not_constexpr(); 477ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } 478ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith do { 479ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith break; 480ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith not_constexpr(); 481ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } while (true); 482ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith return true; 483ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } 484ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith static_assert(no_cont_after_break(), ""); 485ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith 486ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith constexpr bool cond() { 487ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith for (int a = 1; bool b = a != 3; ++a) { 488ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith if (!b) 489ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith return false; 490ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } 491ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith while (bool b = true) { 492ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith b = false; 493ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith break; 494ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } 495ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith return true; 496ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith } 497ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith static_assert(cond(), ""); 498692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith 499692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith constexpr int range_for() { 500692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith int arr[] = { 1, 2, 3, 4, 5 }; 501692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith int sum = 0; 502692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith for (int x : arr) 503d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith sum += x; 504692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith return sum; 505692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith } 506692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith static_assert(range_for() == 15, ""); 507692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith 508692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith template<int...N> struct ints {}; 509692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith template<typename A, typename B> struct join_ints; 510692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith template<int...As, int...Bs> struct join_ints<ints<As...>, ints<Bs...>> { 511692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith using type = ints<As..., sizeof...(As) + Bs...>; 512692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith }; 513692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith template<unsigned N> struct make_ints { 514692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith using type = typename join_ints<typename make_ints<N/2>::type, typename make_ints<(N+1)/2>::type>::type; 515692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith }; 516692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith template<> struct make_ints<0> { using type = ints<>; }; 517692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith template<> struct make_ints<1> { using type = ints<0>; }; 518692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith 519692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith struct ignore { template<typename ...Ts> constexpr ignore(Ts &&...) {} }; 520692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith 521692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith template<typename T, unsigned N> struct array { 522692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith constexpr array() : arr{} {} 523692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith template<typename ...X> 524692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith constexpr array(X ...x) : arr{} { 525692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith init(typename make_ints<sizeof...(X)>::type{}, x...); 526692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith } 527692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith template<int ...I, typename ...X> constexpr void init(ints<I...>, X ...x) { 528692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith ignore{arr[I] = x ...}; 529692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith } 530692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith T arr[N]; 531692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith struct iterator { 532692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith T *p; 533692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith constexpr explicit iterator(T *p) : p(p) {} 534692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith constexpr bool operator!=(iterator o) { return p != o.p; } 535692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith constexpr iterator &operator++() { ++p; return *this; } 536692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith constexpr T &operator*() { return *p; } 537692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith }; 538692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith constexpr iterator begin() { return iterator(arr); } 539692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith constexpr iterator end() { return iterator(arr + N); } 540692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith }; 541692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith 542692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith constexpr int range_for_2() { 543692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith array<int, 5> arr { 1, 2, 3, 4, 5 }; 544692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith int sum = 0; 545692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith for (int k : arr) { 546d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smith sum += k; 547692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith if (sum > 8) break; 548692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith } 549692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith return sum; 550692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith } 551692eafd2052fb6ca581530d6f3569eea9520a508Richard Smith static_assert(range_for_2() == 10, ""); 552ce61715606b5f55ccc023720cdf9c1a796b0d526Richard Smith} 553a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith 554d20afcbe94f0daed15d040d98d2aa8ef8ed368e4Richard Smithnamespace assignment_op { 555a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith struct A { 556a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith constexpr A() : n(5) {} 557a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith int n; 558a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith struct B { 559a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith int k = 1; 560a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith union U { 561a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith constexpr U() : y(4) {} 562a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith int x; 563a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith int y; 564a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith } u; 565a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith } b; 566a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith }; 567a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith constexpr bool testA() { 568a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith A a, b; 569a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith a.n = 7; 570a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith a.b.u.y = 5; 571a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith b = a; 572a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith return b.n == 7 && b.b.u.y == 5 && b.b.k == 1; 573a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith } 574a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith static_assert(testA(), ""); 575a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith 576a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith struct B { 577a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith bool assigned = false; 578a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith constexpr B &operator=(const B&) { 579a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith assigned = true; 580a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith return *this; 581a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith } 582a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith }; 583a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith struct C : B { 584a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith B b; 585a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith int n = 5; 586a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith }; 587a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith constexpr bool testC() { 588a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith C c, d; 589a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith c.n = 7; 590a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith d = c; 591a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith c.n = 3; 592a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith return d.n == 7 && d.assigned && d.b.assigned; 593a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith } 594a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith static_assert(testC(), ""); 595a8942d7686dde6d221a176c502ce857bdc409dabRichard Smith} 596284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith 597284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smithnamespace switch_stmt { 598284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith constexpr int f(char k) { 599284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith bool b = false; 600284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith int z = 6; 601284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith switch (k) { 602284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return -1; 603284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 0: 604284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith if (false) { 605284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 1: 606284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith z = 1; 607284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith for (; b;) { 608284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return 5; 609284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith while (0) 610284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 2: return 2; 611284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 7: z = 7; 612284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith do case 6: { 613284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return z; 614284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith if (false) 615284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 3: return 3; 616284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 4: z = 4; 617284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } while (1); 618284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 5: b = true; 619284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 9: z = 9; 620284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 621284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return z; 622284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } else if (false) case 8: z = 8; 623284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith else if (false) { 624284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 10: 625284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith z = -10; 626284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith break; 627284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 628284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith else z = 0; 629284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return z; 630284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith default: 631284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return -1; 632284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 633284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return -z; 634284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 635284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(f(0) == 0, ""); 636284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(f(1) == 1, ""); 637284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(f(2) == 2, ""); 638284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(f(3) == 3, ""); 639284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(f(4) == 4, ""); 640284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(f(5) == 5, ""); 641284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(f(6) == 6, ""); 642284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(f(7) == 7, ""); 643284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(f(8) == 8, ""); 644284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(f(9) == 9, ""); 645284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(f(10) == 10, ""); 646284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith 647284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith // Check that we can continue an outer loop from within a switch. 648284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith constexpr bool contin() { 649284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith for (int n = 0; n != 10; ++n) { 650284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith switch (n) { 651284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 0: 652284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith ++n; 653284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith continue; 654284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 1: 655284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return false; 656284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 2: 657284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return true; 658284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 659284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 660284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return false; 661284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 662284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(contin(), ""); 663284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith 664284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith constexpr bool switch_into_for() { 665284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith int n = 0; 666284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith switch (n) { 667284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith for (; n == 1; ++n) { 668284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return n == 1; 669284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 0: ; 670284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 671284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 672284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return false; 673284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 674284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(switch_into_for(), ""); 675284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith 676284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith constexpr void duff_copy(char *a, const char *b, int n) { 677284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith switch ((n - 1) % 8 + 1) { 678284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith for ( ; n; n = (n - 1) & ~7) { 679284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 8: a[n-8] = b[n-8]; 680284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 7: a[n-7] = b[n-7]; 681284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 6: a[n-6] = b[n-6]; 682284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 5: a[n-5] = b[n-5]; 683284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 4: a[n-4] = b[n-4]; 684284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 3: a[n-3] = b[n-3]; 685284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 2: a[n-2] = b[n-2]; 686284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 1: a[n-1] = b[n-1]; 687284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 688284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith case 0: ; 689284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 690284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 691284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith 692284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith constexpr bool test_copy(const char *str, int n) { 693284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith char buffer[16] = {}; 694284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith duff_copy(buffer, str, n); 695284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith for (int i = 0; i != sizeof(buffer); ++i) 696284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith if (buffer[i] != (i < n ? str[i] : 0)) 697284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return false; 698284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith return true; 699284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith } 700284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(test_copy("foo", 0), ""); 701284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(test_copy("foo", 1), ""); 702284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(test_copy("foo", 2), ""); 703284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(test_copy("hello world", 0), ""); 704284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(test_copy("hello world", 7), ""); 705284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(test_copy("hello world", 8), ""); 706284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(test_copy("hello world", 9), ""); 707284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(test_copy("hello world", 10), ""); 708284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith static_assert(test_copy("hello world", 10), ""); 709284b3cbfd1cd5b6585437fbb8b95fe136f273efbRichard Smith} 710