https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115754

            Bug ID: 115754
           Summary: C++26 ICE on constexpr new
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jakub at gcc dot gnu.org
                CC: jason at gcc dot gnu.org, unassigned at gcc dot gnu.org
        Depends on: 115744
            Blocks: 110338
  Target Milestone: ---

+++ This bug was initially created as a clone of Bug #115744 +++

While working on the PR115744 patch, I've noticed that vanilla trunk or GCC 14
ICE on

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

  template <typename T>
  struct allocator
  {
    constexpr allocator () noexcept {}

    constexpr T *allocate (size_t n)
    { return static_cast<T *> (::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<int> a;
  auto b = a.allocate (1);
  ::new (b) int ();
  a.deallocate (b, 1);
  return true;
}

constexpr bool a = foo ();

with -std=c++26.  Of course, the C++26 constexpr placement new support isn't
there and users shouldn't be declaring placement operator new themselves,
especially with constexpr when it is not, but still we shouldn't ICE.

Filing separately in case we want to backport it.

The fix for this in the WIP patch was the
@@ -8103,7 +8103,10 @@ cxx_eval_constant_expression (const cons
        tree oldop = TREE_OPERAND (t, 0);

        tree op = cxx_eval_constant_expression (ctx, oldop,
-                                               lval,
+                                               (VOID_TYPE_P (TREE_TYPE (t))
+                                                || (tcode == VIEW_CONVERT_EXPR
+                                                    && lval == vc_glvalue))
+                                               ? lval : vc_prvalue,
                                                non_constant_p, overflow_p);
        if (*non_constant_p)
          return t;
hunk in constexpr.cc, if lval is vc_discard but we aren't really discarding the
result,
I think the void * -> something * cast code at least but most likely various
other checks rely on op being actually an rvalue.  If this is a (void) cast,
discarding it is fine, we won't process anything.  And I think
VIEW_CONVERT_EXPR can be around various VAR_DECLs on the lhs, so I think we
also need at least vc_glvalue handling for that.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110338
[Bug 110338] Implement C++26 language features
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115744
[Bug 115744] [C++26] P2747R2 - constexpr placement new

Reply via email to