commit:     d9ec8d21d27b98b1ae8a0fe33c8917868a14ba63
Author:     Sergei Trofimovich <slyfox <AT> gentoo <DOT> org>
AuthorDate: Thu May 20 22:14:05 2021 +0000
Commit:     Sergei Trofimovich <slyfox <AT> gentoo <DOT> org>
CommitDate: Thu May 20 22:14:05 2021 +0000
URL:        https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=d9ec8d21

11.1.0: backport PR100489: union constructor fix

Reported-by: Martin Kolleck
Bug: https://bugs.gentoo.org/788829
Bug: https://gcc.gnu.org/PR100489
Signed-off-by: Sergei Trofimovich <slyfox <AT> gentoo.org>

 11.1.0/gentoo/28_all_ctor-union-PR100489.patch | 156 +++++++++++++++++++++++++
 11.1.0/gentoo/README.history                   |   1 +
 2 files changed, 157 insertions(+)

diff --git a/11.1.0/gentoo/28_all_ctor-union-PR100489.patch 
b/11.1.0/gentoo/28_all_ctor-union-PR100489.patch
new file mode 100644
index 0000000..1ee1277
--- /dev/null
+++ b/11.1.0/gentoo/28_all_ctor-union-PR100489.patch
@@ -0,0 +1,156 @@
+https://bugs.gentoo.org/788829
+https://gcc.gnu.org/PR100489
+
+From 0a1010428b3861464eb319c629c68cb13b9ca01e Mon Sep 17 00:00:00 2001
+From: Jason Merrill <[email protected]>
+Date: Wed, 19 May 2021 21:12:45 -0400
+Subject: [PATCH] c++: designated init with anonymous union [PR100489]
+
+My patch for PR98463 added an assert that tripped on this testcase, because
+we ended up with a U CONSTRUCTOR with an initializer for a, which is not a
+member of U.  We need to wrap the a initializer in another CONSTRUCTOR for
+the anonymous union.
+
+There was already support for this in process_init_constructor_record, but
+not in process_init_constructor_union.  But since this is about brace
+elision, it really belongs under reshape_init rather than digest_init, so
+this patch moves the handling to reshape_init_class, which also handles
+unions.
+
+       PR c++/100489
+
+gcc/cp/ChangeLog:
+
+       * decl.c (reshape_init_class): Handle designator for
+       member of anonymous aggregate here.
+       * typeck2.c (process_init_constructor_record): Not here.
+
+gcc/testsuite/ChangeLog:
+
+       * g++.dg/cpp2a/desig18.C: New test.
+---
+ gcc/cp/decl.c                        | 33 ++++++++++++++++++++++++----
+ gcc/cp/typeck2.c                     | 26 ----------------------
+ gcc/testsuite/g++.dg/cpp2a/desig18.C | 17 ++++++++++++++
+ 3 files changed, 46 insertions(+), 30 deletions(-)
+ create mode 100644 gcc/testsuite/g++.dg/cpp2a/desig18.C
+
+--- a/gcc/cp/decl.c
++++ b/gcc/cp/decl.c
+@@ -6388,10 +6388,9 @@ reshape_init_class (tree type, reshape_iter *d, bool 
first_initializer_p,
+             /* We already reshaped this.  */
+             if (field != d->cur->index)
+               {
+-                tree id = DECL_NAME (d->cur->index);
+-                gcc_assert (id);
+-                gcc_checking_assert (d->cur->index
+-                                     == get_class_binding (type, id));
++                if (tree id = DECL_NAME (d->cur->index))
++                  gcc_checking_assert (d->cur->index
++                                       == get_class_binding (type, id));
+                 field = d->cur->index;
+               }
+           }
+@@ -6412,6 +6411,32 @@ reshape_init_class (tree type, reshape_iter *d, bool 
first_initializer_p,
+                      d->cur->index);
+             return error_mark_node;
+           }
++
++        /* If the element is an anonymous union object and the initializer
++           list is a designated-initializer-list, the anonymous union object
++           is initialized by the designated-initializer-list { D }, where D
++           is the designated-initializer-clause naming a member of the
++           anonymous union object.  */
++        tree ictx = DECL_CONTEXT (field);
++        if (!same_type_ignoring_top_level_qualifiers_p (ictx, type))
++          {
++            gcc_assert (ANON_AGGR_TYPE_P (ictx));
++            /* Find the anon aggr that is a direct member of TYPE.  */
++            while (true)
++              {
++                tree cctx = TYPE_CONTEXT (ictx);
++                if (same_type_ignoring_top_level_qualifiers_p (cctx, type))
++                  break;
++                ictx = cctx;
++              }
++            /* And then the TYPE member with that anon aggr type.  */
++            tree aafield = TYPE_FIELDS (type);
++            for (; aafield; aafield = TREE_CHAIN (aafield))
++              if (TREE_TYPE (aafield) == ictx)
++                break;
++            gcc_assert (aafield);
++            field = aafield;
++          }
+       }
+ 
+       /* If we processed all the member of the class, we are done.  */
+diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
+index 4e9632f6a7d..142c6fd8e75 100644
+--- a/gcc/cp/typeck2.c
++++ b/gcc/cp/typeck2.c
+@@ -1511,19 +1511,6 @@ process_init_constructor_record (tree type, tree init, 
int nested, int flags,
+                         || identifier_p (ce->index));
+             if (ce->index == field || ce->index == DECL_NAME (field))
+               next = ce->value;
+-            else if (ANON_AGGR_TYPE_P (fldtype)
+-                     && search_anon_aggr (fldtype,
+-                                          TREE_CODE (ce->index) == FIELD_DECL
+-                                          ? DECL_NAME (ce->index)
+-                                          : ce->index))
+-              /* If the element is an anonymous union object and the
+-                 initializer list is a designated-initializer-list, the
+-                 anonymous union object is initialized by the
+-                 designated-initializer-list { D }, where D is the
+-                 designated-initializer-clause naming a member of the
+-                 anonymous union object.  */
+-              next = build_constructor_single (init_list_type_node,
+-                                               ce->index, ce->value);
+             else
+               {
+                 ce = NULL;
+@@ -1669,19 +1656,6 @@ process_init_constructor_record (tree type, tree init, 
int nested, int flags,
+ 
+                 if (ce->index == field || ce->index == DECL_NAME (field))
+                   break;
+-                if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
+-                  {
+-                    tree t
+-                      = search_anon_aggr (TREE_TYPE (field),
+-                                          TREE_CODE (ce->index) == FIELD_DECL
+-                                          ? DECL_NAME (ce->index)
+-                                          : ce->index);
+-                    if (t)
+-                      {
+-                        field = t;
+-                        break;
+-                      }
+-                  }
+               }
+           }
+         if (field)
+diff --git a/gcc/testsuite/g++.dg/cpp2a/desig18.C 
b/gcc/testsuite/g++.dg/cpp2a/desig18.C
+new file mode 100644
+index 00000000000..4851579b7c7
+--- /dev/null
++++ b/gcc/testsuite/g++.dg/cpp2a/desig18.C
+@@ -0,0 +1,17 @@
++// PR c++/100489
++// { dg-options "" }
++
++union U
++{
++  union
++  {
++    unsigned char a;
++  };
++
++  unsigned char b[1];
++};
++
++void f(unsigned char a)
++{
++  union U u = { .a = a };
++}
+-- 
+2.31.1
+

diff --git a/11.1.0/gentoo/README.history b/11.1.0/gentoo/README.history
index 9c9ad5e..27dd8ff 100644
--- a/11.1.0/gentoo/README.history
+++ b/11.1.0/gentoo/README.history
@@ -1,5 +1,6 @@
 2              TODO
        + 27_all_msp430-f2c.patch
+       + 28_all_ctor-union-PR100489.patch
 
 1              27 Apr 2021
        + 01_all_default-fortify-source.patch

Reply via email to