157 lines · cpp
1// RUN: %clang_cc1 -std=c++2c -verify %s2// RUN: %clang_cc1 -std=c++2c -verify %s -fexperimental-new-constant-interpreter3 4 5namespace std {6 using size_t = decltype(sizeof(0));7}8 9void *operator new(std::size_t, void *p) { return p; }10void* operator new[] (std::size_t, void* p) {return p;}11 12 13consteval int ok() {14 int i;15 new (&i) int(0);16 new (&i) int[1]{1};17 new (static_cast<void*>(&i)) int(0);18 return 0;19}20 21consteval int conversion() {22 int i;23 new (static_cast<void*>(&i)) float(0);24 // expected-note@-1 {{placement new would change type of storage from 'int' to 'float'}}25 return 0;26}27 28consteval int indeterminate() {29 int * indeterminate;30 new (indeterminate) int(0);31 // expected-note@-1 {{read of uninitialized object is not allowed in a constant expression}}32 return 0;33}34 35consteval int array1() {36 int i[2];37 new (&i) int[]{1,2};38 new (&i) int[]{1};39 new (&i) int(0);40 new (static_cast<void*>(&i)) int[]{1,2};41 new (static_cast<void*>(&i)) int[]{1};42 return 0;43}44 45consteval int array2() {46 int i[1];47 new (&i) int[2];48 //expected-note@-1 {{placement new would change type of storage from 'int[1]' to 'int[2]'}}49 return 0;50}51 52struct S{53 int* i;54 constexpr S() : i(new int(42)) {} // #no-deallocation55 constexpr ~S() {delete i;}56};57 58consteval void alloc() {59 S* s = new S();60 s->~S();61 new (s) S();62 delete s;63}64 65 66consteval void alloc_err() {67 S* s = new S();68 new (s) S();69 delete s;70}71 72 73 74int a = ok();75int b = conversion(); // expected-error {{call to consteval function 'conversion' is not a constant expression}} \76 // expected-note {{in call to 'conversion()'}}77int c = indeterminate(); // expected-error {{call to consteval function 'indeterminate' is not a constant expression}} \78 // expected-note {{in call to 'indeterminate()'}}79int d = array1();80int e = array2(); // expected-error {{call to consteval function 'array2' is not a constant expression}} \81 // expected-note {{in call to 'array2()'}}82int alloc1 = (alloc(), 0);83int alloc2 = (alloc_err(), 0); // expected-error {{call to consteval function 'alloc_err' is not a constant expression}}84 // expected-note@#no-deallocation {{allocation performed here was not deallocated}}85 86constexpr int *intptr() {87 return new int;88}89 90constexpr bool yay() {91 int *ptr = new (intptr()) int(42);92 bool ret = *ptr == 42;93 delete ptr;94 return ret;95}96static_assert(yay());97 98constexpr bool blah() {99 int *ptr = new (intptr()) int[3]{ 1, 2, 3 }; // expected-note {{placement new would change type of storage from 'int' to 'int[3]'}}100 bool ret = ptr[0] == 1 && ptr[1] == 2 && ptr[2] == 3;101 delete [] ptr;102 return ret;103}104static_assert(blah()); // expected-error {{not an integral constant expression}} \105 // expected-note {{in call to 'blah()'}}106 107constexpr int *get_indeterminate() {108 int *evil;109 return evil; // expected-note {{read of uninitialized object is not allowed in a constant expression}}110}111 112constexpr bool bleh() {113 int *ptr = new (get_indeterminate()) int; // expected-note {{in call to 'get_indeterminate()'}}114 return true;115}116static_assert(bleh()); // expected-error {{not an integral constant expression}} \117 // expected-note {{in call to 'bleh()'}}118 119constexpr int modify_const_variable() {120 const int a = 10;121 new ((int *)&a) int(12); // expected-note {{modification of object of const-qualified type 'const int' is not allowed in a constant expression}}122 return a;123}124static_assert(modify_const_variable()); // expected-error {{not an integral constant expression}} \125 // expected-note {{in call to}}126 127typedef const int T0;128typedef T0 T1;129constexpr T1 modify_const_variable_td() {130 T1 a = 10;131 new ((int *)&a) int(12); // expected-note {{modification of object of const-qualified type 'T1' (aka 'const int') is not allowed in a constant expression}}132 return a;133}134static_assert(modify_const_variable_td()); // expected-error {{not an integral constant expression}} \135 // expected-note {{in call to}}136 137template<typename T>138constexpr T modify_const_variable_tmpl() {139 T a = 10;140 new ((int *)&a) int(12); // expected-note {{modification of object of const-qualified type 'const int' is not allowed in a constant expression}}141 return a;142}143static_assert(modify_const_variable_tmpl<const int>()); // expected-error {{not an integral constant expression}} \144 // expected-note {{in call to}}145 146namespace ModifyMutableMember {147 struct S {148 mutable int a {10};149 };150 constexpr int modify_mutable_member() {151 const S s;152 new ((int *)&s.a) int(12);153 return s.a;154 }155 static_assert(modify_mutable_member() == 12);156}157