[{"id":3677100,"web_url":"http://patchwork.ozlabs.org/comment/3677100/","msgid":"<ad4MlBSpP64Hdw73@zen.kayari.org>","list_archive_url":null,"date":"2026-04-14T09:44:52","subject":"Re: [PATCH] c++, libstdc++, v2: Implement LWG4483 - Multidimensional\n arrays are not supported by meta::reflect_constant_array and related\n functions","submitter":{"id":48004,"url":"http://patchwork.ozlabs.org/api/people/48004/","name":"Jonathan Wakely","email":"jwakely@redhat.com"},"content":"On Fri, 10 Apr 2026 at 17:45 +0200, Jakub Jelinek wrote:\n>On Fri, Apr 10, 2026 at 05:29:13PM +0200, Tomasz Kaminski wrote:\n>> Could you add a line:\n>>      static_assert(foo() ==  std::meta::reflect_constant_array(std::span\n>> <int[3][3]>(m)));\n>> I.e. we check that only content matters, and not type of the range.\n>\n>Here is an updated patch.\n\nThe library part is OK, thanks.\n\n>Interdiff is just\n>+static_assert (foo () == std::meta::reflect_constant_array (m));\n>+static_assert (foo () == std::meta::reflect_constant_array (std::span <const int[3][3]> (m)));\n>...\n>+static_assert (bar () == std::meta::reflect_constant_array (n));\n>+static_assert (bar () == std::meta::reflect_constant_array (std::span <const int[3][3]> (n)));\n>in reflect_constant_array10.C test.\n>\n>2026-04-10  Jakub Jelinek  <jakub@redhat.com>\n>\n>\t* reflect.cc (adjust_array_elt): New function.\n>\t(get_range_elts): Implement LWG4483 - Multidimensional arrays are not\n>\tsupported by meta::reflect_constant_array and related functions.\n>\tHandle ARRAY_TYPE valuet.  Don't unshare_expr in the class valuet case,\n>\tget_template_param_object will unshare.\n>\n>\t* g++.dg/reflect/reflect_constant_array9.C: New test.\n>\t* g++.dg/reflect/reflect_constant_array10.C: New test.\n>\t* g++.dg/reflect/reflect_constant_array11.C: New test.\n>\t* g++.dg/reflect/define_static_array6.C: New test.\n>\t* g++.dg/reflect/define_static_object2.C: Uncomment older tests and\n>\tfix them, add tests for unions.\n>\n>\t* include/std/meta (define_static_object): Adjust for LWG4483 changes\n>\t- handle unions and arrays differently.\n>\n>--- gcc/cp/reflect.cc.jj\t2026-04-10 08:45:20.716811803 +0200\n>+++ gcc/cp/reflect.cc\t2026-04-10 15:32:30.747654790 +0200\n>@@ -394,6 +394,47 @@ replace_parm_r (tree *tp, int *walk_subt\n> static tree throw_exception (location_t, const constexpr_ctx *, const char *,\n> \t\t\t     tree, bool *, tree *);\n>\n>+/* Helper function for get_range_elts, handle adjustment of ARRAY_TYPE elts\n>+   of a retvec.  */\n>+\n>+static tree\n>+adjust_array_elt (location_t loc, const constexpr_ctx *ctx, tree valuet,\n>+\t\t  tree expr, tree fun, bool *non_constant_p, tree *jump_target)\n>+{\n>+  if (TREE_CODE (valuet) == ARRAY_TYPE)\n>+    {\n>+      if (TREE_CODE (expr) != CONSTRUCTOR\n>+\t  || TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)\n>+\treturn throw_exception (loc, ctx, \"reflect_constant_array failed\",\n>+\t\t\t\tfun, non_constant_p, jump_target);\n>+      unsigned int i;\n>+      tree val;\n>+      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, val)\n>+\t{\n>+\t  CONSTRUCTOR_ELT (expr, i)->value\n>+\t    = adjust_array_elt (loc, ctx, TREE_TYPE (valuet), val, fun,\n>+\t\t\t\tnon_constant_p, jump_target);\n>+\t  if (*jump_target || *non_constant_p)\n>+\t    return NULL_TREE;\n>+\t}\n>+      return expr;\n>+    }\n>+  else if (INTEGRAL_TYPE_P (valuet))\n>+    {\n>+      if (TREE_CODE (expr) == INTEGER_CST)\n>+\treturn expr;\n>+      return throw_exception (loc, ctx, \"array element not a constant integer\",\n>+\t\t\t      fun, non_constant_p, jump_target);\n>+    }\n>+  expr = convert_reflect_constant_arg (valuet, expr);\n>+  if (expr == error_mark_node)\n>+    return throw_exception (loc, ctx, \"reflect_constant failed\",\n>+\t\t\t    fun, non_constant_p, jump_target);\n>+  if (VAR_P (expr))\n>+    expr = DECL_INITIAL (expr);\n>+  return expr;\n>+}\n>+\n> /* Kinds for get_range_elts.  */\n>\n> enum get_range_elts_kind {\n>@@ -513,23 +554,24 @@ get_range_elts (location_t loc, const co\n> \t}\n>       if (kind == REFLECT_CONSTANT_ARRAY)\n> \t{\n>-\t  if (!structural_type_p (valuet))\n>+\t  tree valuete = strip_array_types (valuet);\n>+\t  if (!structural_type_p (valuete))\n> \t    {\n> \t      if (!cxx_constexpr_quiet_p (ctx))\n> \t\t{\n> \t\t  auto_diagnostic_group d;\n> \t\t  error_at (loc, \"%<reflect_constant_array%> argument with \"\n> \t\t\t\t \"%qT which is not a structural type\", inst);\n>-\t\t  structural_type_p (valuet, true);\n>+\t\t  structural_type_p (valuete, true);\n> \t\t}\n> \t      *non_constant_p = true;\n> \t      return NULL_TREE;\n> \t    }\n> \t  TREE_VEC_ELT (args, 0)\n>-\t    = build_stub_type (valuet,\n>-\t\t\t       cp_type_quals (valuet) | TYPE_QUAL_CONST,\n>+\t    = build_stub_type (valuete,\n>+\t\t\t       cp_type_quals (valuete) | TYPE_QUAL_CONST,\n> \t\t\t       false);\n>-\t  if (!is_xible (INIT_EXPR, valuet, args))\n>+\t  if (!is_xible (INIT_EXPR, valuete, args))\n> \t    {\n> \t      if (!cxx_constexpr_quiet_p (ctx))\n> \t\terror_at (loc, \"%<reflect_constant_array%> argument with %qT \"\n>@@ -551,7 +593,23 @@ get_range_elts (location_t loc, const co\n> \t    }\n> \t  tree referencet = TYPE_MAIN_VARIANT (instr);\n> \t  TREE_VEC_ELT (args, 0) = referencet;\n>-\t  if (!is_xible (INIT_EXPR, valuet, args))\n>+\t  if (valuete != valuet)\n>+\t    {\n>+\t      tree rt = referencet;\n>+\t      if (TYPE_REF_P (rt))\n>+\t\trt = TREE_TYPE (rt);\n>+\t      if (!same_type_ignoring_top_level_qualifiers_p (valuet, rt))\n>+\t\t{\n>+\t\t  if (!cxx_constexpr_quiet_p (ctx))\n>+\t\t    error_at (loc, \"%<reflect_constant_array%> argument with \"\n>+\t\t\t\t   \"%qT which is not compatible with %qT \"\n>+\t\t\t\t   \"%<std::ranges::range_reference_t%>\",\n>+\t\t\t      inst, referencet);\n>+\t\t  *non_constant_p = true;\n>+\t\t  return NULL_TREE;\n>+\t\t}\n>+\t    }\n>+\t  else if (!is_xible (INIT_EXPR, valuet, args))\n> \t    {\n> \t      if (!cxx_constexpr_quiet_p (ctx))\n> \t\terror_at (loc, \"%<reflect_constant_array%> argument with %qT \"\n>@@ -595,12 +653,22 @@ get_range_elts (location_t loc, const co\n> \telse\n> \t  {\n> \t    gcc_assert (kind == REFLECT_CONSTANT_ARRAY);\n>+\t    if (TREE_CODE (valuet) == ARRAY_TYPE)\n>+\t      {\n>+\t\tretvec[i]\n>+\t\t  = adjust_array_elt (loc, ctx, valuet,\n>+\t\t\t\t      unshare_expr (retvec[i]), fun,\n>+\t\t\t\t      non_constant_p, jump_target);\n>+\t\tif (*jump_target || *non_constant_p)\n>+\t\t  return NULL_TREE;\n>+\t\tcontinue;\n>+\t      }\n> \t    tree expr = convert_reflect_constant_arg (valuet, retvec[i]);\n> \t    if (expr == error_mark_node)\n> \t      return throw_exception (loc, ctx, \"reflect_constant failed\",\n> \t\t\t\t      fun, non_constant_p, jump_target);\n> \t    if (VAR_P (expr))\n>-\t      expr = unshare_expr (DECL_INITIAL (expr));\n>+\t      expr = DECL_INITIAL (expr);\n> \t    retvec[i] = expr;\n> \t  }\n>       }\n>--- gcc/testsuite/g++.dg/reflect/reflect_constant_array9.C.jj\t2026-04-10 14:58:28.892432782 +0200\n>+++ gcc/testsuite/g++.dg/reflect/reflect_constant_array9.C\t2026-04-10 15:46:45.523823103 +0200\n>@@ -0,0 +1,28 @@\n>+// LWG4483 - Multidimensional arrays are not supported by\n>+// meta::reflect_constant_array and related functions.\n>+// { dg-do compile { target c++26 } }\n>+// { dg-additional-options \"-freflection\" }\n>+\n>+#include <meta>\n>+\n>+consteval auto\n>+foo ()\n>+{\n>+  int a[3][3][3];\n>+  for (int i = 0; i < 3; ++i)\n>+    for (int j = 0; j < 3; ++j)\n>+      for (int k = 0; k < 3; ++k)\n>+\ta[i][j][k] = i + j + k;\n>+  return std::meta::reflect_constant_array (a);\n>+}\n>+\n>+static_assert (foo () == foo ());\n>+static_assert (type_of (foo ()) == ^^const int [3][3][3]);\n>+constexpr auto &m = [: foo () :];\n>+consteval {\n>+  for (int i = 0; i < 3; ++i)\n>+    for (int j = 0; j < 3; ++j)\n>+      for (int k = 0; k < 3; ++k)\n>+\tif (m[i][j][k] != i + j + k)\n>+\t  throw 1;\n>+}\n>--- gcc/testsuite/g++.dg/reflect/reflect_constant_array10.C.jj\t2026-04-10 16:43:43.192287885 +0200\n>+++ gcc/testsuite/g++.dg/reflect/reflect_constant_array10.C\t2026-04-10 17:39:16.165672372 +0200\n>@@ -0,0 +1,57 @@\n>+// LWG4483 - Multidimensional arrays are not supported by\n>+// meta::reflect_constant_array and related functions.\n>+// { dg-do compile { target c++26 } }\n>+// { dg-additional-options \"-freflection\" }\n>+\n>+#include <ranges>\n>+#include <meta>\n>+\n>+consteval auto\n>+foo ()\n>+{\n>+  int a[3][3][3];\n>+  for (int i = 0; i < 3; ++i)\n>+    for (int j = 0; j < 3; ++j)\n>+      for (int k = 0; k < 3; ++k)\n>+\ta[i][j][k] = i + 3 * j + 9 * k;\n>+  std::span <int[3][3]> b = a;\n>+  return std::meta::reflect_constant_array (b);\n>+}\n>+\n>+static_assert (foo () == foo ());\n>+static_assert (type_of (foo ()) == ^^const int [3][3][3]);\n>+constexpr auto &m = [: foo () :];\n>+static_assert (foo () == std::meta::reflect_constant_array (m));\n>+static_assert (foo () == std::meta::reflect_constant_array (std::span <const int[3][3]> (m)));\n>+consteval {\n>+  for (int i = 0; i < 3; ++i)\n>+    for (int j = 0; j < 3; ++j)\n>+      for (int k = 0; k < 3; ++k)\n>+\tif (m[i][j][k] != i + 3 * j + 9 * k)\n>+\t  throw 1;\n>+}\n>+\n>+consteval auto\n>+bar ()\n>+{\n>+  int a[3][3][3];\n>+  for (int i = 0; i < 3; ++i)\n>+    for (int j = 0; j < 3; ++j)\n>+      for (int k = 0; k < 3; ++k)\n>+\ta[i][j][k] = i + 3 * j + 9 * k;\n>+  std::span <int[3][3]> b = a;\n>+  return std::meta::reflect_constant_array (b | std::views::reverse);\n>+}\n>+\n>+static_assert (bar () == bar ());\n>+static_assert (type_of (bar ()) == ^^const int [3][3][3]);\n>+constexpr auto &n = [: bar () :];\n>+static_assert (bar () == std::meta::reflect_constant_array (n));\n>+static_assert (bar () == std::meta::reflect_constant_array (std::span <const int[3][3]> (n)));\n>+consteval {\n>+  for (int i = 0; i < 3; ++i)\n>+    for (int j = 0; j < 3; ++j)\n>+      for (int k = 0; k < 3; ++k)\n>+\tif (n[i][j][k] != (2 - i) + 3 * j + 9 * k)\n>+\t  throw 1;\n>+}\n>--- gcc/testsuite/g++.dg/reflect/reflect_constant_array11.C.jj\t2026-04-10 17:00:44.179663685 +0200\n>+++ gcc/testsuite/g++.dg/reflect/reflect_constant_array11.C\t2026-04-10 17:05:50.683365136 +0200\n>@@ -0,0 +1,18 @@\n>+// { dg-do compile { target c++26 } }\n>+// { dg-additional-options \"-freflection\" }\n>+// Test std::meta::reflect_constant_string.\n>+\n>+#include <meta>\n>+#include <ranges>\n>+#include <span>\n>+\n>+using namespace std::meta;\n>+\n>+struct A { int a, b; mutable int c; };\n>+constexpr A aa[2] = { { 1, 2, 3 }, { 4, 5, 6 } };\n>+constexpr auto a = reflect_constant_array (aa);\n>+// { dg-error \"'reflect_constant_array' argument with 'std::ranges::range_value_t<const A \\\\\\[2\\\\\\]>' \\\\\\{aka 'A'\\\\\\} which is not a structural type\" \"\" { target *-*-* } .-1 }\n>+struct B { constexpr B (int x, int y) : a (x), b (y) {} constexpr ~B () {} B (const B &) = delete; int a, b; };\n>+constexpr B b[2][2] = { { { 1, 2 }, { 2, 3 } }, { { 3, 4 }, { 4, 5 } } };\n>+constexpr auto c = reflect_constant_array (b);\n>+// { dg-error \"'reflect_constant_array' argument with 'std::ranges::range_value_t<const B \\\\\\[2\\\\\\]\\\\\\[2\\\\\\]>' \\\\\\{aka 'B \\\\\\[2\\\\\\]'\\\\\\} which is not copy constructible\" \"\" { target *-*-* } .-1 }\n>--- gcc/testsuite/g++.dg/reflect/define_static_array6.C.jj\t2026-04-10 15:44:52.229788936 +0200\n>+++ gcc/testsuite/g++.dg/reflect/define_static_array6.C\t2026-04-10 15:52:38.099857297 +0200\n>@@ -0,0 +1,27 @@\n>+// LWG4483 - Multidimensional arrays are not supported by\n>+// meta::reflect_constant_array and related functions.\n>+// { dg-do compile { target c++26 } }\n>+// { dg-additional-options \"-freflection\" }\n>+\n>+#include <meta>\n>+\n>+consteval auto\n>+foo ()\n>+{\n>+  int a[3][3][3];\n>+  for (int i = 0; i < 3; ++i)\n>+    for (int j = 0; j < 3; ++j)\n>+      for (int k = 0; k < 3; ++k)\n>+\ta[i][j][k] = i + j + k;\n>+  return std::define_static_array (a);\n>+}\n>+\n>+static_assert (foo ().size () == 3);\n>+constexpr auto *m = foo ().data ();\n>+consteval {\n>+  for (int i = 0; i < 3; ++i)\n>+    for (int j = 0; j < 3; ++j)\n>+      for (int k = 0; k < 3; ++k)\n>+\tif (m[i][j][k] != i + j + k)\n>+\t  throw 1;\n>+}\n>--- gcc/testsuite/g++.dg/reflect/define_static_object2.C.jj\t2026-03-27 10:17:16.120298331 +0100\n>+++ gcc/testsuite/g++.dg/reflect/define_static_object2.C\t2026-04-10 16:09:20.261858550 +0200\n>@@ -1,3 +1,5 @@\n>+// LWG4483 - Multidimensional arrays are not supported by\n>+// meta::reflect_constant_array and related functions.\n> // { dg-do compile { target c++26 } }\n> // { dg-additional-options \"-freflection\" }\n> // Test std::define_static_object.\n>@@ -5,14 +7,19 @@\n> #include <meta>\n>\n> constexpr int arr[]{1, 2, 3};\n>-// LWG4483 use extract(reflect_constant_array())\n>-// constexpr const int(*ptr)[3] = std::define_static_object(arr);\n>-// static_assert( *ptr == std::define_static_array(arr).data() );\n>-// static_assert( ptr = &std::meta::constant_of(arr) );\n>+constexpr const int (*ptr)[3] = std::define_static_object (arr);\n>+static_assert (*ptr == std::define_static_array (arr).data ());\n>+static_assert (ptr == &[: std::meta::constant_of (^^arr) :]);\n>\n> constexpr int marr[3][3]{1, 2, 3};\n>-// LWG4483 array are not structural so this fail\n>-// constexpr const int(*mptr)[3][3] = std::define_static_object(marr);\n>-// static_assert( *mptr == std::define_static_array(marr).data() );\n>-// static_assert( mptr = &std::meta::constant_of(marr) );\n>+constexpr const int (*mptr)[3][3] = std::define_static_object (marr);\n>+static_assert (*mptr == std::define_static_array (marr).data ());\n>+static_assert (mptr == &[: std::meta::constant_of (^^marr) :]);\n>\n>+union U { int a; long long b; };\n>+constexpr U u = { .a = 42 };\n>+constexpr const U *up = std::define_static_object (u);\n>+static_assert (up->a == 42);\n>+constexpr U v = { .b = 43LL };\n>+constexpr const U *vp = std::define_static_object (v);\n>+static_assert (vp->b == 43LL);\n>--- libstdc++-v3/include/std/meta.jj\t2026-04-08 07:49:13.477647992 +0200\n>+++ libstdc++-v3/include/std/meta\t2026-04-10 15:57:25.423013150 +0200\n>@@ -682,11 +682,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n>     define_static_object(_Tp&& __t)\n>     {\n>       using _Up = remove_cvref_t<_Tp>;\n>-      if constexpr (meta::is_class_type(^^_Up))\n>+      if constexpr (meta::is_class_type(^^_Up) || meta::is_union_type(^^_Up))\n> \t{\n> \t  auto __cst = meta::reflect_constant(std::forward<_Tp>(__t));\n> \t  return std::addressof(meta::extract<const _Up&>(__cst));\n> \t}\n>+      else if constexpr (meta::is_array_type(^^_Up))\n>+\t{\n>+\t  auto __cst = meta::reflect_constant_array(std::forward<_Tp>(__t));\n>+\t  return std::addressof(meta::extract<const _Up&>(__cst));\n>+\t}\n>       else\n> \treturn std::define_static_array(span(std::addressof(__t), 1)).data();\n>     }\n>\n>\n>\tJakub\n>\n>","headers":{"Return-Path":"<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>","X-Original-To":["incoming@patchwork.ozlabs.org","gcc-patches@gcc.gnu.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","gcc-patches@gcc.gnu.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=DEConuYj;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=DEConuYj","sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com","sourceware.org; spf=pass smtp.mailfrom=redhat.com","server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.129.124"],"Received":["from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fvztK0sWnz1yDF\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 14 Apr 2026 19:45:39 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 88C264BA2E08\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 14 Apr 2026 09:45:37 +0000 (GMT)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by sourceware.org (Postfix) with ESMTP id D651C4BA2E07\n for <gcc-patches@gcc.gnu.org>; Tue, 14 Apr 2026 09:45:01 +0000 (GMT)","from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-611-0gpf1sjgM5umdPi_c_IdHw-1; Tue,\n 14 Apr 2026 05:44:58 -0400","from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id 43AB0195609D; Tue, 14 Apr 2026 09:44:56 +0000 (UTC)","from localhost (unknown [10.44.34.88])\n by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id B89673000C2F; Tue, 14 Apr 2026 09:44:54 +0000 (UTC)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 88C264BA2E08","OpenDKIM Filter v2.11.0 sourceware.org D651C4BA2E07"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org D651C4BA2E07","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org D651C4BA2E07","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776159902; cv=none;\n b=WyxJxb0dstXf5G4U03SZ329YpypKQryZ1XmkOtKQntnZkzenoy+om/+QegKg1Cz1u5pf/h9raujIxeCpRmOvVcxu+4JiI3L05e5L+JA1a3b3IhtOlvPN3Xb1EYcc9CKFGgfVKdrdAiWswKV6dtrCOOz2aB+CEEPKSDqc3U27mIQ=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776159902; c=relaxed/simple;\n bh=l/qMAKEzfEF2fAVm1O7hnE8CRHYyg2Q7JYcATa2TDqk=;\n h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version;\n b=vz7q7iGFb8vJTV97nrtlsEOBu3r0e3G8ThQPpdlqv1sJMowSQ1GdT537GFdJdTtQ4962pvgjWG2h9KuJmoZPXUv6ALI/F5g49BpSj0FPRt5raBxMmqwtcELnhtm7rFrCWcorDCiDxr0UIpKeaBWgLbu5+N03WPNgZxhaie9E9ms=","ARC-Authentication-Results":"i=1; server2.sourceware.org","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1776159901;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n in-reply-to:in-reply-to:references:references;\n bh=c+0u/XumQP+zF8vLVnmCL0s6mvz8LyTUROMwwdp83Sw=;\n b=DEConuYj9Q102V7MZ8Q4EgPLRkrQpZoKHoco84q6Jf0R1YnjWazzn9bTuWdtoiefs+B0hG\n m1N1N3m2/NCc+v40xR6u0WCFDysg6JyVfDgULyz0OVhHHGYvktz8Xs2VO4NwakfMH+437P\n iQOWZRueTXWroWNLivQ32fgPcsaZjxc=","X-MC-Unique":"0gpf1sjgM5umdPi_c_IdHw-1","X-Mimecast-MFC-AGG-ID":"0gpf1sjgM5umdPi_c_IdHw_1776159896","Date":"Tue, 14 Apr 2026 10:44:52 +0100","From":"Jonathan Wakely <jwakely@redhat.com>","To":"Jakub Jelinek <jakub@redhat.com>","Cc":"Jason Merrill <jason@redhat.com>, Marek Polacek <polacek@redhat.com>,\n Tomasz Kaminski <tkaminsk@redhat.com>, gcc-patches@gcc.gnu.org,\n libstdc++@gcc.gnu.org","Subject":"Re: [PATCH] c++, libstdc++, v2: Implement LWG4483 - Multidimensional\n arrays are not supported by meta::reflect_constant_array and related\n functions","Message-ID":"<ad4MlBSpP64Hdw73@zen.kayari.org>","References":"<adkUGggIiITbC-cp@tucnak>\n <CAKvuMXBJMd=813ixZmS-_+MuP8_EJf8SrtnbvEfueM2spptYZA@mail.gmail.com>\n <adkbHhg3-pyumdxH@tucnak>","MIME-Version":"1.0","In-Reply-To":"<adkbHhg3-pyumdxH@tucnak>","X-Clacks-Overhead":"GNU Terry Pratchett","X-Scanned-By":"MIMEDefang 3.4.1 on 10.30.177.4","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"hBvw_RWX65exc5GC_XoTbP6bONaWaBn9d_yH9u-LiKA_1776159896","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain; charset=utf-8; format=flowed","Content-Disposition":"inline","X-BeenThere":"gcc-patches@gcc.gnu.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Gcc-patches mailing list <gcc-patches.gcc.gnu.org>","List-Unsubscribe":"<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>","List-Archive":"<https://gcc.gnu.org/pipermail/gcc-patches/>","List-Post":"<mailto:gcc-patches@gcc.gnu.org>","List-Help":"<mailto:gcc-patches-request@gcc.gnu.org?subject=help>","List-Subscribe":"<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"}},{"id":3677362,"web_url":"http://patchwork.ozlabs.org/comment/3677362/","msgid":"<1ab72c7c-be1a-4539-9fb5-b0d11071752b@redhat.com>","list_archive_url":null,"date":"2026-04-14T19:02:51","subject":"Re: [PATCH] c++, libstdc++, v2: Implement LWG4483 - Multidimensional\n arrays are not supported by meta::reflect_constant_array and related\n functions","submitter":{"id":4337,"url":"http://patchwork.ozlabs.org/api/people/4337/","name":"Jason Merrill","email":"jason@redhat.com"},"content":"On 4/10/26 11:45 AM, Jakub Jelinek wrote:\n> On Fri, Apr 10, 2026 at 05:29:13PM +0200, Tomasz Kaminski wrote:\n>> Could you add a line:\n>>       static_assert(foo() ==  std::meta::reflect_constant_array(std::span\n>> <int[3][3]>(m)));\n>> I.e. we check that only content matters, and not type of the range.\n> \n> Here is an updated patch.\n> \n> Interdiff is just\n> +static_assert (foo () == std::meta::reflect_constant_array (m));\n> +static_assert (foo () == std::meta::reflect_constant_array (std::span <const int[3][3]> (m)));\n> ...\n> +static_assert (bar () == std::meta::reflect_constant_array (n));\n> +static_assert (bar () == std::meta::reflect_constant_array (std::span <const int[3][3]> (n)));\n> in reflect_constant_array10.C test.\n> \n> 2026-04-10  Jakub Jelinek  <jakub@redhat.com>\n> \n> \t* reflect.cc (adjust_array_elt): New function.\n> \t(get_range_elts): Implement LWG4483 - Multidimensional arrays are not\n> \tsupported by meta::reflect_constant_array and related functions.\n> \tHandle ARRAY_TYPE valuet.  Don't unshare_expr in the class valuet case,\n> \tget_template_param_object will unshare.\n> \n> \t* g++.dg/reflect/reflect_constant_array9.C: New test.\n> \t* g++.dg/reflect/reflect_constant_array10.C: New test.\n> \t* g++.dg/reflect/reflect_constant_array11.C: New test.\n> \t* g++.dg/reflect/define_static_array6.C: New test.\n> \t* g++.dg/reflect/define_static_object2.C: Uncomment older tests and\n> \tfix them, add tests for unions.\n> \n> \t* include/std/meta (define_static_object): Adjust for LWG4483 changes\n> \t- handle unions and arrays differently.\n> \n> --- gcc/cp/reflect.cc.jj\t2026-04-10 08:45:20.716811803 +0200\n> +++ gcc/cp/reflect.cc\t2026-04-10 15:32:30.747654790 +0200\n> @@ -394,6 +394,47 @@ replace_parm_r (tree *tp, int *walk_subt\n>   static tree throw_exception (location_t, const constexpr_ctx *, const char *,\n>   \t\t\t     tree, bool *, tree *);\n>   \n> +/* Helper function for get_range_elts, handle adjustment of ARRAY_TYPE elts\n> +   of a retvec.  */\n> +\n> +static tree\n> +adjust_array_elt (location_t loc, const constexpr_ctx *ctx, tree valuet,\n> +\t\t  tree expr, tree fun, bool *non_constant_p, tree *jump_target)\n> +{\n> +  if (TREE_CODE (valuet) == ARRAY_TYPE)\n> +    {\n> +      if (TREE_CODE (expr) != CONSTRUCTOR\n> +\t  || TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)\n> +\treturn throw_exception (loc, ctx, \"reflect_constant_array failed\",\n> +\t\t\t\tfun, non_constant_p, jump_target);\n> +      unsigned int i;\n> +      tree val;\n> +      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, val)\n> +\t{\n> +\t  CONSTRUCTOR_ELT (expr, i)->value\n> +\t    = adjust_array_elt (loc, ctx, TREE_TYPE (valuet), val, fun,\n> +\t\t\t\tnon_constant_p, jump_target);\n> +\t  if (*jump_target || *non_constant_p)\n> +\t    return NULL_TREE;\n> +\t}\n> +      return expr;\n> +    }\n> +  else if (INTEGRAL_TYPE_P (valuet))\n\nWhy this special case instead of using convert_reflect_constant_arg for \nintegers as well?\n\n> +    {\n> +      if (TREE_CODE (expr) == INTEGER_CST)\n> +\treturn expr;\n> +      return throw_exception (loc, ctx, \"array element not a constant integer\",\n> +\t\t\t      fun, non_constant_p, jump_target);\n> +    }\n> +  expr = convert_reflect_constant_arg (valuet, expr);\n> +  if (expr == error_mark_node)\n> +    return throw_exception (loc, ctx, \"reflect_constant failed\",\n> +\t\t\t    fun, non_constant_p, jump_target);\n> +  if (VAR_P (expr))\n> +    expr = DECL_INITIAL (expr);\n> +  return expr;\n> +}\n> +\n>   /* Kinds for get_range_elts.  */\n>   \n>   enum get_range_elts_kind {\n> @@ -551,7 +593,23 @@ get_range_elts (location_t loc, const co\n>   \t    }\n>   \t  tree referencet = TYPE_MAIN_VARIANT (instr);\n>   \t  TREE_VEC_ELT (args, 0) = referencet;\n> -\t  if (!is_xible (INIT_EXPR, valuet, args))\n> +\t  if (valuete != valuet)\n> +\t    {\n> +\t      tree rt = referencet;\n> +\t      if (TYPE_REF_P (rt))\n> +\t\trt = TREE_TYPE (rt);\n> +\t      if (!same_type_ignoring_top_level_qualifiers_p (valuet, rt))\n\nYou could use non_reference (referencet) here.\n\nJason","headers":{"Return-Path":"<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>","X-Original-To":["incoming@patchwork.ozlabs.org","gcc-patches@gcc.gnu.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","gcc-patches@gcc.gnu.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=YtyxSAXt;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=YtyxSAXt","sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com","sourceware.org; spf=pass smtp.mailfrom=redhat.com","server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.129.124"],"Received":["from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fwDFm2xVLz1y2d\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 15 Apr 2026 05:03:40 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 9B4844BA23E2\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 14 Apr 2026 19:03:38 +0000 (GMT)","from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.129.124])\n by sourceware.org (Postfix) with ESMTP id 82C3F4BA2E08\n for <gcc-patches@gcc.gnu.org>; Tue, 14 Apr 2026 19:02:56 +0000 (GMT)","from mail-oo1-f71.google.com (mail-oo1-f71.google.com\n [209.85.161.71]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-515-69uuaQMNP4mov6Avt7BKHw-1; Tue, 14 Apr 2026 15:02:54 -0400","by mail-oo1-f71.google.com with SMTP id\n 006d021491bc7-68e7e213adfso6477029eaf.0\n for <gcc-patches@gcc.gnu.org>; Tue, 14 Apr 2026 12:02:54 -0700 (PDT)","from [192.168.50.130]\n (130-44-146-247.s12789.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com.\n [130.44.146.247]) by smtp.gmail.com with ESMTPSA id\n 6a1803df08f44-8aca0054054sm79583886d6.24.2026.04.14.12.02.51\n (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n Tue, 14 Apr 2026 12:02:52 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 9B4844BA23E2","OpenDKIM Filter v2.11.0 sourceware.org 82C3F4BA2E08"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org 82C3F4BA2E08","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org 82C3F4BA2E08","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776193376; cv=none;\n b=T71HNim0ISwPIuTzLiTYSg+Dp4J9UN++tacIr28dO1J796jjVU7QoVu+eHgMS3/5J71H7w8EfZN2ekm8tC4bLYN8Yz2Elo8CAeh8rZ0YgqFuzZizIYJeYYGH11XMo81MlH7PPGTYs0DT+C/5RHp4j5PQ5R6WjWgRxIKZ2ZHqs9E=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776193376; c=relaxed/simple;\n bh=n+4w5qy2p0oJ8R0l3/SmH7H7WURZ56Wcc+IM20FJ3F8=;\n h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From;\n b=F9AWcehWWKVfadZDnCJ7/r2Wo/DIhH1nbxymcfWijHA3dzx7CB27aTK26pj516Y2cqNcPwNcl5TqcjuZY6aBcow7sHm/kNfPC1cm1lV+rM8mCY72QVAZzEsBLWjVPthNIF3kMFj+rXIzJIfzb5EQ8NTHNWASxqmRls+Uqpki6pk=","ARC-Authentication-Results":"i=1; server2.sourceware.org","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1776193376;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=8G/WXySqqKpg8fevLRUDDNbBTs1oaO3T4RjzqI3oflc=;\n b=YtyxSAXtSRgqEQhNMFUecurFLOpqXCYIsCWUCxgvptph7TtNpuGgKwqF6N1pr1MzXZBBD4\n SQZSULDIXSb4q71osOwYCJCexjJsEpMymVU/gjCPtO8SVRJbhm73qTasNMuHYy1bBvlaZb\n IS9uEXZUK7mftThfZpMZpZh/uH6r1yM=","X-MC-Unique":"69uuaQMNP4mov6Avt7BKHw-1","X-Mimecast-MFC-AGG-ID":"69uuaQMNP4mov6Avt7BKHw_1776193374","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776193374; x=1776798174;\n h=content-transfer-encoding:in-reply-to:from:content-language\n :references:cc:to:subject:user-agent:mime-version:date:message-id\n :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id\n :reply-to;\n bh=8G/WXySqqKpg8fevLRUDDNbBTs1oaO3T4RjzqI3oflc=;\n b=UxOJ0tWo8H8x9v0pwKQ1iqawqdlapxBSaUenZMhi0MalqTEcpTgZwbe5Wx/J3KfzbC\n meYYDBpFND2LH5Q2qlVfUtfugYSatTSGOJTnqhL6x6PI/RZXTHD0IWijWtZOZbfWO7hI\n dEW5zmokMlbWSsviPl7An1fSSmkFqCklxKVxahFH0GZxdT7Sixj3PhM4F4IwOZ9pAwPN\n U1I8olv0Tkc6nUpsIJYZL3HlRmNHhmrH+aROYvlgeuarlMZaolTYLqqpNFc5AhqorEIB\n PhQsNDaNQ+rm9xz7VFacUOtYzSitVzBFNLVzxm8Vu+C/UUMiixlB6zRmJcraeNd34bId\n uc1A==","X-Gm-Message-State":"AOJu0YzwfUge6Sg1dgWc7hiqrDvTIQhXJ3xRdUXZEVmnHE6ZCGydIHVp\n 6bT6FyUNSHORe0vg4NMiGiYSxlU63UHN5/I8TlRCteZsXkc3oNEMXQvpQnUYBl0yywIXWiv9iVr\n IunETuXgfzM++fnxFR34zf3vM7qA6rfJhhXtrgWPflFi/Md2uMYMeLyrOk5E=","X-Gm-Gg":"AeBDieuHYF75Vmx6OeU7sByOc0u21WnmVaKXzVSyCImRT3NhhzOfqqKPa3izKIQDwyl\n ZZgb0EK0dt7cptX7x6nwl1/S7gROYL3e9pWEybd7VHD+Y2zhBqspLofCZfisn7hBxkPKF0rrGTQ\n 5pHUyzKsteL3uMWE22a8/C7tKZ+Nt4E/Dfdu7pumt69ygwVOc+DN0UJnvICHVIAa1hy2CQs1yoa\n vgQooFgTn+bjEey38mF5v5+4gWQ6uq74u/OVr6YNx9qTuJW/e/w2P3HdtreLyFUKkdwicXpm37i\n omH77kHFsWffAxhj3El8TDYW308W7iEBqcVGQH2dfdNQ6hnT6PklVnFCnePzoMwo4gzcPTBkJKr\n MEFXBn+p97qNU/KqpRftXQ1MKEQTLnHukqw7m34x2XlcR7XgLilnCkNeidNNQQu+PjG7cBBfu0o\n W6fMyqs2rlO+Uu6XIcBPNKl/QQ1gx9wEZbOxhFts3mkA==","X-Received":["by 2002:a05:6820:985:b0:67b:c7a0:e4fa with SMTP id\n 006d021491bc7-68be5b5edd1mr9229043eaf.4.1776193373974;\n Tue, 14 Apr 2026 12:02:53 -0700 (PDT)","by 2002:a05:6820:985:b0:67b:c7a0:e4fa with SMTP id\n 006d021491bc7-68be5b5edd1mr9228969eaf.4.1776193372982;\n Tue, 14 Apr 2026 12:02:52 -0700 (PDT)"],"Message-ID":"<1ab72c7c-be1a-4539-9fb5-b0d11071752b@redhat.com>","Date":"Tue, 14 Apr 2026 15:02:51 -0400","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH] c++, libstdc++, v2: Implement LWG4483 - Multidimensional\n arrays are not supported by meta::reflect_constant_array and related\n functions","To":"Jakub Jelinek <jakub@redhat.com>, Marek Polacek <polacek@redhat.com>,\n Jonathan Wakely <jwakely@redhat.com>, Tomasz Kaminski <tkaminsk@redhat.com>","Cc":"gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org","References":"<adkUGggIiITbC-cp@tucnak>\n <CAKvuMXBJMd=813ixZmS-_+MuP8_EJf8SrtnbvEfueM2spptYZA@mail.gmail.com>\n <adkbHhg3-pyumdxH@tucnak>","From":"Jason Merrill <jason@redhat.com>","In-Reply-To":"<adkbHhg3-pyumdxH@tucnak>","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"eNSrIhdORcQUHPy8BsLcod6UgAOG_97blmBYfwzf7Pw_1776193374","X-Mimecast-Originator":"redhat.com","Content-Language":"en-US","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","X-BeenThere":"gcc-patches@gcc.gnu.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Gcc-patches mailing list <gcc-patches.gcc.gnu.org>","List-Unsubscribe":"<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>","List-Archive":"<https://gcc.gnu.org/pipermail/gcc-patches/>","List-Post":"<mailto:gcc-patches@gcc.gnu.org>","List-Help":"<mailto:gcc-patches-request@gcc.gnu.org?subject=help>","List-Subscribe":"<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"}}]