brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · 4cf0e9f Raw
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