On 8/15/25 11:49 AM, Patrick Palka wrote:
Hi, thanks for the patch!

On Fri, 15 Aug 2025, seha-bot wrote:

From: Nedim Šehić <nedimsehi...@gmail.com>

Regtested on x86_64-pc-linux-gnu.

This patch fixes deduction for member array types from parenthesized
initializers which use braces and string literals.

         PR c++/121518

gcc/cp/ChangeLog:

         * pt.cc (maybe_aggr_guide): Add deduction for brace and string
           literal initializer cases.

gcc/testsuite/ChangeLog:

         * g++.dg/cpp2a/class-deduction-aggr17.C: New test.

Co-Authored-By: Nathaniel Shead <nathanielosh...@gmail.com>
Signed-off-by: Nedim Šehić <nedimsehi...@gmail.com>
---
  gcc/cp/pt.cc                                  | 22 +++--
  .../g++.dg/cpp2a/class-deduction-aggr17.C     | 88 +++++++++++++++++++
  2 files changed, 105 insertions(+), 5 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr17.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index b6b13edd03f..35c3ce517e8 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -31116,22 +31116,34 @@ maybe_aggr_guide (tree tmpl, tree init, 
vec<tree,va_gc> *args)
      }
    else if (TREE_CODE (init) == TREE_LIST)
      {
-      int len = list_length (init);
+      tree elt = init;
        for (tree binfo : BINFO_BASE_BINFOS (TYPE_BINFO (template_type)))
        {
-         if (!len)
+         if (!elt)
            break;
          parms = tree_cons (NULL_TREE, BINFO_TYPE (binfo), parms);
-         --len;
+         elt = TREE_CHAIN (elt);
        }
        for (tree field = TYPE_FIELDS (template_type);
-          len;
-          --len, field = DECL_CHAIN (field))
+     elt;
+     elt = TREE_CHAIN (elt), field = DECL_CHAIN (field))

The identation seems off in this hunk.

        {
          field = next_aggregate_field (field);
          if (!field)
            return NULL_TREE;
          tree ftype = finish_decltype_type (field, true, complain);
+    tree arg = tree_strip_any_location_wrapper (TREE_VALUE (elt));
+    if (TREE_CODE (ftype) == ARRAY_TYPE)
+      {
+        if (BRACE_ENCLOSED_INITIALIZER_P (arg))
+          ftype = cp_build_reference_type (ftype, true);
+        else if (TREE_CODE (arg) == STRING_CST)
+          {
+            ftype = cp_build_qualified_type
+              (ftype, cp_type_quals (ftype) | TYPE_QUAL_CONST);
+            ftype = cp_build_reference_type (ftype, false);
+          }
+      }

Indentation seems off here too.  And I think we could sink the variable
'arg' into the if.

Besides that, LGTM, we have similar logic in collect_ctor_idx_types
(for aggregate CTAD from {} rather than ()).  I guess duplicating it
isn't ideal but I don't mind too much.  Jason, what do you think?

I generally prefer to share code that should have the same effect, to avoid mismatches like this.

In this case, I think split off the array type adjustment from both functions into e.g. adjust_aggr_ctad_field_type.

Probably collect_ctor_idx_types should use finish_decltype_type like this function, rather than TREE_TYPE (idx) as it does now. But it seems we can't put that and the adjustment in the same function because of the array brace elision handling that needs to come between them.

Jason

Reply via email to