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

--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Marek Polacek <[email protected]>:

https://gcc.gnu.org/g:a099b3ef74189650f81b99cc1aa149d78aec1197

commit r17-5654-ga099b3ef74189650f81b99cc1aa149d78aec1197
Author: Marek Polacek <[email protected]>
Date:   Fri Oct 2 12:57:10 2026 -0400

    c++: ICE with reflect_constant and std::allocator::allocate [PR125649]

    In this PR we have

      consteval{
        const int* m = std::allocator<int>().allocate(1);
        std::meta::reflect_constant(m);
      }

    which is invalid: reflect_constant throws meta::exception unless the
    template-id TCls<V> would be valid ([meta.reflection.result]/5).

    [temp.arg.nontype]/1 wants the invented declaration T x = E; to satisfy
    the semantic constraints of a constexpr variable with static storage
duration.

    [dcl.constexpr]/6: A constexpr variable shall be constant-initializable.

    [expr.const.init]/4: A variable v is constant-initializable if [...]
    -- the full-expression of its initialization is a constant expression
    -- immediately after the initializing declaration of v, the object x
       declared by v is constexpr-representable [...]

    [expr.const.init]/3: x is constexpr-representable at P if every object
    that a constituent value of x points to is constexpr-referenceable
    from P.

    [expr.const.init]/2: An object o is constexpr-referenceable from a point P
    if ... it has static storage duration, or automatic storage duration with
    certain scope conditions.

    But the array object allocate gave us has dynamic storage duration as per
    [allocator.members]/5 -> it's not constexpr-referenceable -> this TCls<V>
    is invalid so reflect_constant should throw.  But we trip on the assert
    because decl is a heap variable.

    There is no way AFAIK to check the failure sooner than
invalid_tparm_referent_p
    (here we are called from eval_reflect_constant) so this patch extends the
    existing assert.

            PR c++/125649

    gcc/cp/ChangeLog:

            * constexpr.cc (addr_of_non_const_var): Use heap_var_p.
            (non_const_var_error): Likewise.
            (cxx_eval_constant_expression): Likewise.
            (find_heap_var_refs): Likewise.
            (heap_var_p): New.
            * cp-tree.h (heap_var_p): Declare.
            * pt.cc (invalid_tparm_referent_p): Add heap_var_p to an
            assert.

    gcc/testsuite/ChangeLog:

            * g++.dg/reflect/reflect_constant10.C: New test.

    Reviewed-by: Jason Merrill <[email protected]>

Reply via email to