Skip to content

Commit 07392e1

Browse files
committed
[Clang] Improve diagnostics when 'placement new' was called with const storage argument
1 parent 5676478 commit 07392e1

File tree

4 files changed

+21
-1
lines changed

4 files changed

+21
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,8 @@ Improvements to Clang's diagnostics
629629
#GH69470, #GH59391, #GH58172, #GH46215, #GH45915, #GH45891, #GH44490,
630630
#GH36703, #GH32903, #GH23312, #GH69874.
631631

632+
- Improve the diagnostics for placement new expression when const-qualified
633+
object was passed as the storage argument.
632634

633635
Improvements to Clang's time-trace
634636
----------------------------------

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8285,6 +8285,9 @@ def err_need_header_before_typeid : Error<
82858285
def err_need_header_before_placement_new : Error<
82868286
"no matching %0 function for non-allocating placement new expression; "
82878287
"include <new>">;
8288+
def err_placement_new_into_const_qualified_storage : Error<
8289+
"placement new expression with a const-qualified argument of type %0 "
8290+
"is not allowed">;
82888291
def err_ms___leave_not_in___try : Error<
82898292
"'__leave' statement not in __try block">;
82908293
def err_uuidof_without_guid : Error<

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2753,10 +2753,18 @@ static bool resolveAllocationOverloadInterior(
27532753
if (Diagnose) {
27542754
// If this is an allocation of the form 'new (p) X' for some object
27552755
// pointer p (or an expression that will decay to such a pointer),
2756-
// diagnose the missing inclusion of <new>.
2756+
// diagnose potential error.
27572757
if (!R.isClassLookup() && Args.size() == 2 &&
27582758
(Args[1]->getType()->isObjectPointerType() ||
27592759
Args[1]->getType()->isArrayType())) {
2760+
if (Args[1]->getType()->isPointerType()) {
2761+
if (Args[1]->getType()->getPointeeType().isConstQualified()) {
2762+
S.Diag(Args[1]->getExprLoc(),
2763+
diag::err_placement_new_into_const_qualified_storage)
2764+
<< Args[1]->getType() << Args[1]->getSourceRange();
2765+
return true;
2766+
}
2767+
}
27602768
S.Diag(R.getNameLoc(), diag::err_need_header_before_placement_new)
27612769
<< R.getLookupName() << Range;
27622770
// Listing the candidates is unlikely to be useful; skip it.

clang/test/SemaCXX/new-delete.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,13 @@ void bad_news(int *ip)
160160
#if __cplusplus < 201103L
161161
(void)new int[]{}; // expected-error {{array size must be specified in new expression with no initializer}}
162162
#endif
163+
struct X { int n; };
164+
const X cx = {5};
165+
(void)new(&cx) X{10}; // expected-error {{placement new expression with a const-qualified argument of type 'const X *' is not allowed}}
166+
const X* const cx2 = 0;
167+
(void)new(cx2) X{10}; // expected-error {{placement new expression with a const-qualified argument of type 'const X *const' is not allowed}}
168+
const int arr[1] = {1};
169+
(void)new(&arr[0]) int(10); // expected-error {{placement new expression with a const-qualified argument of type 'const int *' is not allowed}}
163170
}
164171

165172
void no_matching_placement_new() {

0 commit comments

Comments
 (0)