]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR c++/90108 (ICE: Segmentation fault (in c_tree_chain_next))
authorJakub Jelinek <jakub@redhat.com>
Fri, 30 Aug 2019 12:38:31 +0000 (14:38 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 30 Aug 2019 12:38:31 +0000 (14:38 +0200)
Backported from mainline
2019-04-19  Jakub Jelinek  <jakub@redhat.com>

PR c++/90108
* c-decl.c (merge_decls): If remove is main variant and
DECL_ORIGINAL_TYPE is some other type, remove a DECL_ORIGINAL_TYPE
variant that has newdecl as TYPE_NAME if any.

* decl.c (duplicate_decls): If remove is main variant and
DECL_ORIGINAL_TYPE is some other type, remove a DECL_ORIGINAL_TYPE
variant that has newdecl as TYPE_NAME if any.

* c-c++-common/pr90108.c: New test.

From-SVN: r275150

gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr90108.c [new file with mode: 0644]

index a861feeac2ee20f0431f6500f4580225bfdc6543..394457213f78651f0afb21098ceced2682fd7984 100644 (file)
@@ -1,6 +1,13 @@
 2019-08-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2019-04-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/90108
+       * c-decl.c (merge_decls): If remove is main variant and
+       DECL_ORIGINAL_TYPE is some other type, remove a DECL_ORIGINAL_TYPE
+       variant that has newdecl as TYPE_NAME if any.
+
        2019-04-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/89933
index 11c63af89ed7ae941fbbc680e70e826d2dd403ac..964d5f1a2d2243784c9e6f72e118c47a1001a170 100644 (file)
@@ -2349,7 +2349,24 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
        {
          tree remove = TREE_TYPE (newdecl);
          if (TYPE_MAIN_VARIANT (remove) == remove)
-           gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE);
+           {
+             gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE);
+             /* If remove is the main variant, no need to remove that
+                from the list.  One of the DECL_ORIGINAL_TYPE
+                variants, e.g. created for aligned attribute, might still
+                refer to the newdecl TYPE_DECL though, so remove that one
+                in that case.  */
+             if (DECL_ORIGINAL_TYPE (newdecl)
+                 && DECL_ORIGINAL_TYPE (newdecl) != remove)
+               for (tree t = TYPE_MAIN_VARIANT (DECL_ORIGINAL_TYPE (newdecl));
+                    t; t = TYPE_MAIN_VARIANT (t))
+                 if (TYPE_NAME (TYPE_NEXT_VARIANT (t)) == newdecl)
+                   {
+                     TYPE_NEXT_VARIANT (t)
+                       = TYPE_NEXT_VARIANT (TYPE_NEXT_VARIANT (t));
+                     break;
+                   }
+           }       
          else
            for (tree t = TYPE_MAIN_VARIANT (remove); ;
                 t = TYPE_NEXT_VARIANT (t))
index 742b0e428440994e6fe9bfaa6e72682a474518dd..9712503fe9e4e2574c929aaadce060ee48812e1b 100644 (file)
@@ -1,6 +1,13 @@
 2019-08-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2019-04-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/90108
+       * decl.c (duplicate_decls): If remove is main variant and
+       DECL_ORIGINAL_TYPE is some other type, remove a DECL_ORIGINAL_TYPE
+       variant that has newdecl as TYPE_NAME if any.
+
        2019-04-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/89933
index 1ad6ad8fae4815579dbd5800eea38cb180939c76..56e4c31e242ee1472291dcf99d45e682d9716103 100644 (file)
@@ -2131,7 +2131,24 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
            {
              tree remove = TREE_TYPE (newdecl);
              if (TYPE_MAIN_VARIANT (remove) == remove)
-               gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE);
+               {
+                 gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE);
+                 /* If remove is the main variant, no need to remove that
+                    from the list.  One of the DECL_ORIGINAL_TYPE
+                    variants, e.g. created for aligned attribute, might still
+                    refer to the newdecl TYPE_DECL though, so remove that one
+                    in that case.  */
+                 if (tree orig = DECL_ORIGINAL_TYPE (newdecl))
+                   if (orig != remove)
+                     for (tree t = TYPE_MAIN_VARIANT (orig); t;
+                          t = TYPE_MAIN_VARIANT (t))
+                       if (TYPE_NAME (TYPE_NEXT_VARIANT (t)) == newdecl)
+                         {
+                           TYPE_NEXT_VARIANT (t)
+                             = TYPE_NEXT_VARIANT (TYPE_NEXT_VARIANT (t));
+                           break;
+                         }
+               }           
              else
                for (tree t = TYPE_MAIN_VARIANT (remove); ;
                     t = TYPE_NEXT_VARIANT (t))
index 978d725437ec2c8b4b3659caff88b2be9fb2987f..9b51773a0d31ab45e8d60b4ec4ff2358f906f2cd 100644 (file)
@@ -1,6 +1,11 @@
 2019-08-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2019-04-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/90108
+       * c-c++-common/pr90108.c: New test.
+
        2019-04-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/90082
diff --git a/gcc/testsuite/c-c++-common/pr90108.c b/gcc/testsuite/c-c++-common/pr90108.c
new file mode 100644 (file)
index 0000000..fa5b846
--- /dev/null
@@ -0,0 +1,6 @@
+/* PR c++/90108 */
+/* { dg-do compile } */
+/* { dg-options "--param ggc-min-heapsize=0" } */
+
+typedef unsigned int a __attribute__ ((__aligned__(8), __may_alias__));
+typedef unsigned int a __attribute__ ((__aligned__(8), __may_alias__));