From 1250540a98e0a1dfa4d7834672d88d8543ea70b1 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 2 Jul 2024 22:09:58 +0200 Subject: [PATCH] c++: Fix ICE on constexpr placement new [PR115754] C++26 is making in P2747R2 paper placement new constexpr. While working on a patch for that, I've noticed we ICE starting with GCC 14 on the following testcase. The problem is that e.g. for the void * to sometype * casts checks, we really assume the casts have their operand constant evaluated as prvalue, but on the testcase the cast itself is evaluated with vc_discard and that means op can end up e.g. a VAR_DECL which the later code doesn't like and asserts on. If the result type is void, we don't really need the cast operand for anything, so can use vc_discard for the recursive call, VIEW_CONVERT_EXPR can appear on the lhs, so we need to honor the lval but otherwise the patch uses vc_prvalue. I'd like to get this patch in before the rest of P2747R2 implementation, so that it can be backported to 14.2 later on. 2024-07-02 Jakub Jelinek Jason Merrill PR c++/115754 * constexpr.cc (cxx_eval_constant_expression) : For conversions to void, pass vc_discard to the recursive call and otherwise for tcode other than VIEW_CONVERT_EXPR pass vc_prvalue. * g++.dg/cpp26/pr115754.C: New test. --- gcc/cp/constexpr.cc | 5 +++- gcc/testsuite/g++.dg/cpp26/pr115754.C | 36 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp26/pr115754.C diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index bd72533491e..0cdac0af7de 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -8103,7 +8103,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, tree oldop = TREE_OPERAND (t, 0); tree op = cxx_eval_constant_expression (ctx, oldop, - lval, + VOID_TYPE_P (TREE_TYPE (t)) + ? vc_discard + : tcode == VIEW_CONVERT_EXPR + ? lval : vc_prvalue, non_constant_p, overflow_p); if (*non_constant_p) return t; diff --git a/gcc/testsuite/g++.dg/cpp26/pr115754.C b/gcc/testsuite/g++.dg/cpp26/pr115754.C new file mode 100644 index 00000000000..45a8efcd9a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/pr115754.C @@ -0,0 +1,36 @@ +// PR c++/115754 +// { dg-do compile { target c++26 } } + +namespace std +{ + using size_t = decltype (sizeof 0); + + template + struct allocator + { + constexpr allocator () noexcept {} + + constexpr T *allocate (size_t n) + { return static_cast (::operator new (n * sizeof(T))); } + + constexpr void + deallocate (T *p, size_t n) + { ::operator delete (p); } + }; +} + +constexpr void * +operator new (std::size_t, void *p) noexcept +{ return p; } + +constexpr bool +foo () +{ + std::allocator a; + auto b = a.allocate (1); + ::new (b) int (); + a.deallocate (b, 1); + return true; +} + +constexpr bool a = foo ();