Skip to content

Commit 1094641

Browse files
authored
[Clang] allow usage of placement new operator in [[msvc::constexpr]] context outside of the std namespace (llvm#119153)
Fixes llvm#74924
1 parent 10ef00f commit 1094641

File tree

4 files changed

+28
-3
lines changed

4 files changed

+28
-3
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,9 @@ Attribute Changes in Clang
527527

528528
- The ``target_version`` attribute is now only supported for AArch64 and RISC-V architectures.
529529

530+
- Clang now permits the usage of the placement new operator in ``[[msvc::constexpr]]``
531+
context outside of the std namespace. (#GH74924)
532+
530533
Improvements to Clang's diagnostics
531534
-----------------------------------
532535

clang/lib/AST/ExprConstant.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10172,7 +10172,9 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
1017210172
return false;
1017310173
IsNothrow = true;
1017410174
} else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10175-
if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26) {
10175+
if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10176+
(Info.CurrentCall->CanEvalMSConstexpr &&
10177+
OperatorNew->hasAttr<MSConstexprAttr>())) {
1017610178
if (!EvaluatePointer(E->getPlacementArg(0), Result, Info))
1017710179
return false;
1017810180
if (Result.Designator.Invalid)

clang/test/AST/ms-constexpr-new.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.33 -std=c++20 -ast-dump %s | FileCheck %s
2+
3+
// CHECK: used operator new
4+
// CHECK: MSConstexprAttr 0x{{[0-9a-f]+}} <col:17, col:23>
5+
[[nodiscard]] [[msvc::constexpr]] inline void* __cdecl operator new(decltype(sizeof(void*)), void* p) noexcept { return p; }
6+
7+
// CHECK: used constexpr construct_at
8+
// CHECK: AttributedStmt 0x{{[0-9a-f]+}} <col:46, col:88>
9+
// CHECK-NEXT: MSConstexprAttr 0x{{[0-9a-f]+}} <col:48, col:54>
10+
// CHECK-NEXT: ReturnStmt 0x{{[0-9a-f]+}} <col:66, col:88>
11+
constexpr int* construct_at(int* p, int v) { [[msvc::constexpr]] return ::new (p) int(v); }
12+
constexpr bool check_construct_at() { int x; return *construct_at(&x, 42) == 42; }
13+
static_assert(check_construct_at());

clang/test/SemaCXX/ms-constexpr-new.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,12 @@ namespace std {
1212
}
1313
}
1414

15-
constexpr bool check_construct_at() { int x; return *std::construct_at(&x, 42) == 42; }
16-
static_assert(check_construct_at());
15+
constexpr bool check_std_construct_at() { int x; return *std::construct_at(&x, 42) == 42; }
16+
static_assert(check_std_construct_at());
17+
18+
constexpr int* construct_at(int* p, int v) { [[msvc::constexpr]] return ::new (p) int(v); } // unsupported-error {{constexpr function never produces a constant expression}} \
19+
// unsupported-warning {{unknown attribute 'constexpr' ignored}} \
20+
// unsupported-note 2{{this placement new expression is not supported in constant expressions before C++2c}}
21+
constexpr bool check_construct_at() { int x; return *construct_at(&x, 42) == 42; } // unsupported-note {{in call to 'construct_at(&x, 42)'}}
22+
static_assert(check_construct_at()); // unsupported-error {{static assertion expression is not an integral constant expression}}\
23+
// unsupported-note {{in call to 'check_construct_at()'}}

0 commit comments

Comments
 (0)