[PATCH] c++, libstdc++, v2: Implement LWG4483 - Multidimensional arrays are not supported by meta::reflect_constant_array and related functions
Jason Merrill
jason@redhat.com
Tue Apr 14 19:02:51 GMT 2026
On 4/10/26 11:45 AM, Jakub Jelinek wrote:
> On Fri, Apr 10, 2026 at 05:29:13PM +0200, Tomasz Kaminski wrote:
>> Could you add a line:
>> static_assert(foo() == std::meta::reflect_constant_array(std::span
>> <int[3][3]>(m)));
>> I.e. we check that only content matters, and not type of the range.
>
> Here is an updated patch.
>
> Interdiff is just
> +static_assert (foo () == std::meta::reflect_constant_array (m));
> +static_assert (foo () == std::meta::reflect_constant_array (std::span <const int[3][3]> (m)));
> ...
> +static_assert (bar () == std::meta::reflect_constant_array (n));
> +static_assert (bar () == std::meta::reflect_constant_array (std::span <const int[3][3]> (n)));
> in reflect_constant_array10.C test.
>
> 2026-04-10 Jakub Jelinek <jakub@redhat.com>
>
> * reflect.cc (adjust_array_elt): New function.
> (get_range_elts): Implement LWG4483 - Multidimensional arrays are not
> supported by meta::reflect_constant_array and related functions.
> Handle ARRAY_TYPE valuet. Don't unshare_expr in the class valuet case,
> get_template_param_object will unshare.
>
> * g++.dg/reflect/reflect_constant_array9.C: New test.
> * g++.dg/reflect/reflect_constant_array10.C: New test.
> * g++.dg/reflect/reflect_constant_array11.C: New test.
> * g++.dg/reflect/define_static_array6.C: New test.
> * g++.dg/reflect/define_static_object2.C: Uncomment older tests and
> fix them, add tests for unions.
>
> * include/std/meta (define_static_object): Adjust for LWG4483 changes
> - handle unions and arrays differently.
>
> --- gcc/cp/reflect.cc.jj 2026-04-10 08:45:20.716811803 +0200
> +++ gcc/cp/reflect.cc 2026-04-10 15:32:30.747654790 +0200
> @@ -394,6 +394,47 @@ replace_parm_r (tree *tp, int *walk_subt
> static tree throw_exception (location_t, const constexpr_ctx *, const char *,
> tree, bool *, tree *);
>
> +/* Helper function for get_range_elts, handle adjustment of ARRAY_TYPE elts
> + of a retvec. */
> +
> +static tree
> +adjust_array_elt (location_t loc, const constexpr_ctx *ctx, tree valuet,
> + tree expr, tree fun, bool *non_constant_p, tree *jump_target)
> +{
> + if (TREE_CODE (valuet) == ARRAY_TYPE)
> + {
> + if (TREE_CODE (expr) != CONSTRUCTOR
> + || TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
> + return throw_exception (loc, ctx, "reflect_constant_array failed",
> + fun, non_constant_p, jump_target);
> + unsigned int i;
> + tree val;
> + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, val)
> + {
> + CONSTRUCTOR_ELT (expr, i)->value
> + = adjust_array_elt (loc, ctx, TREE_TYPE (valuet), val, fun,
> + non_constant_p, jump_target);
> + if (*jump_target || *non_constant_p)
> + return NULL_TREE;
> + }
> + return expr;
> + }
> + else if (INTEGRAL_TYPE_P (valuet))
Why this special case instead of using convert_reflect_constant_arg for
integers as well?
> + {
> + if (TREE_CODE (expr) == INTEGER_CST)
> + return expr;
> + return throw_exception (loc, ctx, "array element not a constant integer",
> + fun, non_constant_p, jump_target);
> + }
> + expr = convert_reflect_constant_arg (valuet, expr);
> + if (expr == error_mark_node)
> + return throw_exception (loc, ctx, "reflect_constant failed",
> + fun, non_constant_p, jump_target);
> + if (VAR_P (expr))
> + expr = DECL_INITIAL (expr);
> + return expr;
> +}
> +
> /* Kinds for get_range_elts. */
>
> enum get_range_elts_kind {
> @@ -551,7 +593,23 @@ get_range_elts (location_t loc, const co
> }
> tree referencet = TYPE_MAIN_VARIANT (instr);
> TREE_VEC_ELT (args, 0) = referencet;
> - if (!is_xible (INIT_EXPR, valuet, args))
> + if (valuete != valuet)
> + {
> + tree rt = referencet;
> + if (TYPE_REF_P (rt))
> + rt = TREE_TYPE (rt);
> + if (!same_type_ignoring_top_level_qualifiers_p (valuet, rt))
You could use non_reference (referencet) here.
Jason
More information about the Libstdc++
mailing list