[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCXX / cxx2c-constexpr-placement-new.cpp
bloba29fb981cedbf0af98c19483631f7153bed889e5
1 // RUN: %clang_cc1 -std=c++2c -verify %s
4 namespace std {
5 using size_t = decltype(sizeof(0));
8 void *operator new(std::size_t, void *p) { return p; }
9 void* operator new[] (std::size_t, void* p) {return p;}
12 consteval int ok() {
13 int i;
14 new (&i) int(0);
15 new (&i) int[1]{1};
16 new (static_cast<void*>(&i)) int(0);
17 return 0;
20 consteval int conversion() {
21 int i;
22 new (static_cast<void*>(&i)) float(0);
23 // expected-note@-1 {{placement new would change type of storage from 'int' to 'float'}}
24 return 0;
27 consteval int indeterminate() {
28 int * indeterminate;
29 new (indeterminate) int(0);
30 // expected-note@-1 {{read of uninitialized object is not allowed in a constant expression}}
31 return 0;
34 consteval int array1() {
35 int i[2];
36 new (&i) int[]{1,2};
37 new (&i) int[]{1};
38 new (&i) int(0);
39 new (static_cast<void*>(&i)) int[]{1,2};
40 new (static_cast<void*>(&i)) int[]{1};
41 return 0;
44 consteval int array2() {
45 int i[1];
46 new (&i) int[2];
47 //expected-note@-1 {{placement new would change type of storage from 'int[1]' to 'int[2]'}}
48 return 0;
51 struct S{
52 int* i;
53 constexpr S() : i(new int(42)) {} // #no-deallocation
54 constexpr ~S() {delete i;}
57 consteval void alloc() {
58 S* s = new S();
59 s->~S();
60 new (s) S();
61 delete s;
65 consteval void alloc_err() {
66 S* s = new S();
67 new (s) S();
68 delete s;
73 int a = ok();
74 int b = conversion(); // expected-error {{call to consteval function 'conversion' is not a constant expression}} \
75 // expected-note {{in call to 'conversion()'}}
76 int c = indeterminate(); // expected-error {{call to consteval function 'indeterminate' is not a constant expression}} \
77 // expected-note {{in call to 'indeterminate()'}}
78 int d = array1();
79 int e = array2(); // expected-error {{call to consteval function 'array2' is not a constant expression}} \
80 // expected-note {{in call to 'array2()'}}
81 int alloc1 = (alloc(), 0);
82 int alloc2 = (alloc_err(), 0); // expected-error {{call to consteval function 'alloc_err' is not a constant expression}}
83 // expected-note@#no-deallocation {{allocation performed here was not deallocated}}
85 constexpr int *intptr() {
86 return new int;
89 constexpr bool yay() {
90 int *ptr = new (intptr()) int(42);
91 bool ret = *ptr == 42;
92 delete ptr;
93 return ret;
95 static_assert(yay());
97 constexpr bool blah() {
98 int *ptr = new (intptr()) int[3]{ 1, 2, 3 }; // expected-note {{placement new would change type of storage from 'int' to 'int[3]'}}
99 bool ret = ptr[0] == 1 && ptr[1] == 2 && ptr[2] == 3;
100 delete [] ptr;
101 return ret;
103 static_assert(blah()); // expected-error {{not an integral constant expression}} \
104 // expected-note {{in call to 'blah()'}}
106 constexpr int *get_indeterminate() {
107 int *evil;
108 return evil; // expected-note {{read of uninitialized object is not allowed in a constant expression}}
111 constexpr bool bleh() {
112 int *ptr = new (get_indeterminate()) int; // expected-note {{in call to 'get_indeterminate()'}}
113 return true;
115 static_assert(bleh()); // expected-error {{not an integral constant expression}} \
116 // expected-note {{in call to 'bleh()'}}