ldionne created this revision. ldionne added a reviewer: rsmith. ldionne requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This is necessary for std::construct_at to work on arrays inside a constant expression. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D114903 Files: clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp Index: clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp =================================================================== --- clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp +++ clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp @@ -96,14 +96,28 @@ return a == 42; } +void *operator new[](std::size_t, void *p) { return p; } +constexpr bool no_array_placement_new_in_user_code() { // expected-error {{never produces a constant expression}} + int a[3]; + new (&a) int[3](); // expected-note {{call to placement 'operator new[]'}} + return a[0] == 0 && a[1] == 0 && a[2] == 0; +} + namespace std { constexpr bool placement_new_in_stdlib() { int a; new (&a) int(42); return a == 42; } + + constexpr bool array_placement_new_in_stdlib() { + int a[3]; + new (&a) int[3]{42, 43, 44}; + return a[0] == 42 && a[1] == 43 && a[2] == 44; + } } static_assert(std::placement_new_in_stdlib()); +static_assert(std::array_placement_new_in_stdlib()); namespace std { template<typename T, typename ...Args> Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -9358,8 +9358,7 @@ bool IsNothrow = false; bool IsPlacement = false; if (OperatorNew->isReservedGlobalPlacementOperator() && - Info.CurrentCall->isStdFunction() && !E->isArray()) { - // FIXME Support array placement new. + Info.CurrentCall->isStdFunction()) { assert(E->getNumPlacementArgs() == 1); if (!EvaluatePointer(E->getPlacementArg(0), Result, Info)) return false;
Index: clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp =================================================================== --- clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp +++ clang/test/SemaCXX/cxx2a-constexpr-dynalloc.cpp @@ -96,14 +96,28 @@ return a == 42; } +void *operator new[](std::size_t, void *p) { return p; } +constexpr bool no_array_placement_new_in_user_code() { // expected-error {{never produces a constant expression}} + int a[3]; + new (&a) int[3](); // expected-note {{call to placement 'operator new[]'}} + return a[0] == 0 && a[1] == 0 && a[2] == 0; +} + namespace std { constexpr bool placement_new_in_stdlib() { int a; new (&a) int(42); return a == 42; } + + constexpr bool array_placement_new_in_stdlib() { + int a[3]; + new (&a) int[3]{42, 43, 44}; + return a[0] == 42 && a[1] == 43 && a[2] == 44; + } } static_assert(std::placement_new_in_stdlib()); +static_assert(std::array_placement_new_in_stdlib()); namespace std { template<typename T, typename ...Args> Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -9358,8 +9358,7 @@ bool IsNothrow = false; bool IsPlacement = false; if (OperatorNew->isReservedGlobalPlacementOperator() && - Info.CurrentCall->isStdFunction() && !E->isArray()) { - // FIXME Support array placement new. + Info.CurrentCall->isStdFunction()) { assert(E->getNumPlacementArgs() == 1); if (!EvaluatePointer(E->getPlacementArg(0), Result, Info)) return false;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits