On 10/2/26 11:19 PM, Marek Polacek wrote:
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?-- >8 -- 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 -- if x has static or thread storage duration, x 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. --- gcc/cp/constexpr.cc | 35 +++++++++-------- gcc/cp/cp-tree.h | 1 + gcc/cp/pt.cc | 18 ++++++--- .../g++.dg/reflect/reflect_constant10.C | 38 +++++++++++++++++++ 4 files changed, 68 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/g++.dg/reflect/reflect_constant10.C diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 31ef5bf1111..a99659f9685 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -3276,10 +3276,7 @@ addr_of_non_const_var (tree *tp, int *walk_subtrees, void *data) if (tree var = get_base_address (TREE_OPERAND (*tp, 0))) if (VAR_P (var) && TREE_STATIC (var)) { - if (DECL_NAME (var) == heap_uninit_identifier - || DECL_NAME (var) == heap_identifier - || DECL_NAME (var) == heap_vec_uninit_identifier - || DECL_NAME (var) == heap_vec_identifier) + if (heap_var_p (var))
Why don't we want to include _deleted in all cases? Jason
