Skip to content

Commit 0042fbf

Browse files
committed
Do not make it an extension as there is no good way to introduce a warning for it
1 parent 67201d1 commit 0042fbf

File tree

6 files changed

+89
-86
lines changed

6 files changed

+89
-86
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1506,7 +1506,6 @@ Attributes on Structured Bindings __cpp_structured_bindings C+
15061506
Pack Indexing __cpp_pack_indexing C++26 C++03
15071507
``= delete ("should have a reason");`` __cpp_deleted_function C++26 C++03
15081508
Variadic Friends __cpp_variadic_friend C++26 C++03
1509-
``constexpr`` placement new __cpp_constexpr C++26 C++20
15101509
-------------------------------------------- -------------------------------- ------------- -------------
15111510
Designated initializers (N494) C99 C89
15121511
Array & element qualification (N2607) C23 C89

clang/lib/AST/ExprConstant.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10025,7 +10025,9 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
1002510025
if (!EvaluateLValue(E->getPlacementArg(0), Nothrow, Info))
1002610026
return false;
1002710027
IsNothrow = true;
10028-
} else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10028+
} else if (OperatorNew->isReservedGlobalPlacementOperator() &&
10029+
(Info.CurrentCall->isStdFunction() ||
10030+
Info.getLangOpts().CPlusPlus26)) {
1002910031
if (!EvaluatePointer(E->getPlacementArg(0), Result, Info))
1003010032
return false;
1003110033
if (Result.Designator.Invalid)

clang/test/AST/ByteCode/new-delete.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ namespace std {
245245
namespace PlacementNew {
246246
constexpr int foo() { // both-error {{never produces a constant expression}}
247247
char c[sizeof(int)];
248-
new (c) int{12}; // ref-note {{placement new would change type of storage from 'char' to 'int'}} \
248+
new (c) int{12}; // ref-note {{this placement new expression is not yet supported in constant expressions}} \
249249
// expected-note {{subexpression not valid in a constant expression}}
250250
return 0;
251251
}

clang/test/CXX/drs/cwg29xx.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct S {
2424
};
2525
} // namespace cwg2917
2626

27-
#if __cplusplus >= 202002
27+
#if __cplusplus >= 202400L
2828

2929
namespace std {
3030
using size_t = decltype(sizeof(0));

clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp

Lines changed: 6 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
// RUN: %clang_cc1 -std=c++2a -verify %s -DNEW=__builtin_operator_new -DDELETE=__builtin_operator_delete
2-
// RUN: %clang_cc1 -std=c++2a -verify %s "-DNEW=operator new" "-DDELETE=operator delete"
3-
// RUN: %clang_cc1 -std=c++2a -verify %s "-DNEW=::operator new" "-DDELETE=::operator delete"
1+
// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx20 %s -DNEW=__builtin_operator_new -DDELETE=__builtin_operator_delete
2+
// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx20 %s "-DNEW=operator new" "-DDELETE=operator delete"
3+
// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx20 %s "-DNEW=::operator new" "-DDELETE=::operator delete"
4+
// RUN: %clang_cc1 -std=c++2c -verify=expected,cxx26 %s "-DNEW=::operator new" "-DDELETE=::operator delete"
45

56
constexpr bool alloc_from_user_code() {
67
void *p = NEW(sizeof(int)); // expected-note {{cannot allocate untyped memory in a constant expression; use 'std::allocator<T>::allocate'}}
@@ -91,9 +92,9 @@ constexpr int no_deallocate_nonalloc = (std::allocator<int>().deallocate((int*)&
9192

9293
void *operator new(std::size_t, void *p) { return p; }
9394
void* operator new[] (std::size_t, void* p) {return p;}
94-
constexpr bool no_placement_new_in_user_code() {
95+
constexpr bool no_placement_new_in_user_code() { // cxx20-error {{constexpr function never produces a constant expression}}
9596
int a;
96-
new (&a) int(42);
97+
new (&a) int(42); // cxx20-note {{this placement new expression is not yet supported in constant expressions}}
9798
return a == 42;
9899
}
99100

@@ -240,80 +241,3 @@ void f() {
240241
}
241242

242243
}
243-
244-
namespace placement_new {
245-
246-
template <typename T, typename U>
247-
constexpr void f(T* t, U u) {
248-
new (t) U(u);
249-
}
250-
251-
consteval int ok() {
252-
int i;
253-
new (&i) int(0);
254-
new (&i) int[1]{1};
255-
new (static_cast<void*>(&i)) int(0);
256-
return 0;
257-
}
258-
259-
consteval int conversion() { // expected-error {{consteval function never produces a constant expression}}
260-
int i;
261-
new (static_cast<void*>(&i)) float(0);
262-
// expected-note@-1 {{placement new would change type of storage from 'int' to 'float'}}
263-
return 0;
264-
}
265-
266-
consteval int indeterminate() {
267-
int * indeterminate;
268-
new (indeterminate) int(0);
269-
// expected-note@-1 {{read of uninitialized object is not allowed in a constant expression}}
270-
return 0;
271-
}
272-
273-
consteval int array1() {
274-
int i[2];
275-
new (&i) int[]{1,2};
276-
new (&i) int[]{1};
277-
new (&i) int(0);
278-
new (static_cast<void*>(&i)) int[]{1,2};
279-
new (static_cast<void*>(&i)) int[]{1};
280-
return 0;
281-
}
282-
283-
consteval int array2() { // expected-error {{consteval function never produces a constant expression}}
284-
int i[1];
285-
new (&i) int[2];
286-
//expected-note@-1 {{placement new would change type of storage from 'int[1]' to 'int[2]'}}
287-
return 0;
288-
}
289-
290-
struct S{
291-
int* i;
292-
constexpr S() : i(new int(42)) {} // expected-note {{allocation performed here was not deallocated}}
293-
constexpr ~S() {delete i;}
294-
};
295-
296-
consteval void alloc() {
297-
S* s = new S();
298-
s->~S();
299-
new (s) S();
300-
delete s;
301-
}
302-
303-
304-
consteval void alloc_err() {
305-
S* s = new S();
306-
new (s) S();
307-
delete s;
308-
}
309-
310-
311-
312-
int a = ok();
313-
int c = indeterminate(); // expected-error {{call to consteval function 'placement_new::indeterminate' is not a constant expression}} \
314-
// expected-note {{in call to 'indeterminate()'}}
315-
int d = array1();
316-
int alloc1 = (alloc(), 0);
317-
int alloc2 = (alloc_err(), 0); // expected-error {{call to consteval function 'placement_new::alloc_err' is not a constant expression}}
318-
319-
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// RUN: %clang_cc1 -std=c++2c -verify %s
2+
3+
4+
namespace std {
5+
using size_t = decltype(sizeof(0));
6+
}
7+
8+
void *operator new(std::size_t, void *p) { return p; }
9+
void* operator new[] (std::size_t, void* p) {return p;}
10+
11+
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;
18+
}
19+
20+
consteval int conversion() { // expected-error {{consteval function never produces a constant expression}}
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;
25+
}
26+
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;
32+
}
33+
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;
42+
}
43+
44+
consteval int array2() { // expected-error {{consteval function never produces a constant expression}}
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;
49+
}
50+
51+
struct S{
52+
int* i;
53+
constexpr S() : i(new int(42)) {} // expected-note {{allocation performed here was not deallocated}}
54+
constexpr ~S() {delete i;}
55+
};
56+
57+
consteval void alloc() {
58+
S* s = new S();
59+
s->~S();
60+
new (s) S();
61+
delete s;
62+
}
63+
64+
65+
consteval void alloc_err() {
66+
S* s = new S();
67+
new (s) S();
68+
delete s;
69+
}
70+
71+
72+
73+
int a = ok();
74+
int c = indeterminate(); // expected-error {{call to consteval function 'placement_new::indeterminate' is not a constant expression}} \
75+
// expected-note {{in call to 'indeterminate()'}}
76+
int d = array1();
77+
int alloc1 = (alloc(), 0);
78+
int alloc2 = (alloc_err(), 0); // expected-error {{call to consteval function 'placement_new::alloc_err' is not a constant expression}}

0 commit comments

Comments
 (0)