commit:     a824358f19e4fe8445a7bdbbe6c3020b9fd32bee
Author:     Sergei Trofimovich <slyfox <AT> gentoo <DOT> org>
AuthorDate: Mon Oct  8 22:04:04 2018 +0000
Commit:     Sergei Trofimovich <slyfox <AT> gentoo <DOT> org>
CommitDate: Mon Oct  8 22:04:04 2018 +0000
URL:        https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=a824358f

8.2.0: fix initialization of empty structs

Single new patch: 111_all_ubd-hog-PR85704.patch

Fix indefinite memory consumption.

Bug: https://gcc.gnu.org/PR85704
Signed-off-by: Sergei Trofimovich <slyfox <AT> gentoo.org>

 8.2.0/gentoo/111_all_ubd-hog-PR85704.patch | 146 +++++++++++++++++++++++++++++
 8.2.0/gentoo/README.history                |   3 +
 2 files changed, 149 insertions(+)

diff --git a/8.2.0/gentoo/111_all_ubd-hog-PR85704.patch 
b/8.2.0/gentoo/111_all_ubd-hog-PR85704.patch
new file mode 100644
index 0000000..de1c6e6
--- /dev/null
+++ b/8.2.0/gentoo/111_all_ubd-hog-PR85704.patch
@@ -0,0 +1,146 @@
+From e15966a15764277e180fdae7a606166c702ec3ca Mon Sep 17 00:00:00 2001
+From: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Wed, 1 Aug 2018 09:35:34 +0000
+Subject: [PATCH]       PR c/85704      * c-typeck.c (init_field_decl_cmp):
+ New function.         (output_pending_init_elements): Use it for field 
comparisons 
+ instead of pure bit_position comparisons.
+
+       * gcc.c-torture/compile/pr85704.c: New test.
+
+
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-8-branch@263199 
138bc75d-0d04-0410-961f-82ee72b054a4
+---
+ gcc/c/c-typeck.c                              | 86 +++++++++++++++----
+ gcc/testsuite/gcc.c-torture/compile/pr85704.c | 10 +++
+ 4 files changed, 91 insertions(+), 17 deletions(-)
+ create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr85704.c
+
+--- a/gcc/c/c-typeck.c
++++ b/gcc/c/c-typeck.c
+@@ -9316,6 +9316,65 @@ output_init_element (location_t loc, tree value, tree 
origtype,
+     output_pending_init_elements (0, braced_init_obstack);
+ }
+ 
++/* For two FIELD_DECLs in the same chain, return -1 if field1
++   comes before field2, 1 if field1 comes after field2 and
++   0 if field1 == field2.  */
++
++static int
++init_field_decl_cmp (tree field1, tree field2)
++{
++  if (field1 == field2)
++    return 0;
++
++  tree bitpos1 = bit_position (field1);
++  tree bitpos2 = bit_position (field2);
++  if (tree_int_cst_equal (bitpos1, bitpos2))
++    {
++      /* If one of the fields has non-zero bitsize, then that
++       field must be the last one in a sequence of zero
++       sized fields, fields after it will have bigger
++       bit_position.  */
++      if (TREE_TYPE (field1) != error_mark_node
++        && COMPLETE_TYPE_P (TREE_TYPE (field1))
++        && integer_nonzerop (TREE_TYPE (field1)))
++      return 1;
++      if (TREE_TYPE (field2) != error_mark_node
++        && COMPLETE_TYPE_P (TREE_TYPE (field2))
++        && integer_nonzerop (TREE_TYPE (field2)))
++      return -1;
++      /* Otherwise, fallback to DECL_CHAIN walk to find out
++       which field comes earlier.  Walk chains of both
++       fields, so that if field1 and field2 are close to each
++       other in either order, it is found soon even for large
++       sequences of zero sized fields.  */
++      tree f1 = field1, f2 = field2;
++      while (1)
++      {
++        f1 = DECL_CHAIN (f1);
++        f2 = DECL_CHAIN (f2);
++        if (f1 == NULL_TREE)
++          {
++            gcc_assert (f2);
++            return 1;
++          }
++        if (f2 == NULL_TREE)
++          return -1;
++        if (f1 == field2)
++          return -1;
++        if (f2 == field1)
++          return 1;
++        if (!tree_int_cst_equal (bit_position (f1), bitpos1))
++          return 1;
++        if (!tree_int_cst_equal (bit_position (f2), bitpos1))
++          return -1;
++      }
++    }
++  else if (tree_int_cst_lt (bitpos1, bitpos2))
++    return -1;
++  else
++    return 1;
++}
++
+ /* Output any pending elements which have become next.
+    As we output elements, constructor_unfilled_{fields,index}
+    advances, which may cause other elements to become next;
+@@ -9387,25 +9446,18 @@ output_pending_init_elements (int all, struct obstack 
* braced_init_obstack)
+       }
+       else if (RECORD_OR_UNION_TYPE_P (constructor_type))
+       {
+-        tree ctor_unfilled_bitpos, elt_bitpos;
+-
+         /* If the current record is complete we are done.  */
+         if (constructor_unfilled_fields == NULL_TREE)
+           break;
+ 
+-        ctor_unfilled_bitpos = bit_position (constructor_unfilled_fields);
+-        elt_bitpos = bit_position (elt->purpose);
+-        /* We can't compare fields here because there might be empty
+-           fields in between.  */
+-        if (tree_int_cst_equal (elt_bitpos, ctor_unfilled_bitpos))
+-          {
+-            constructor_unfilled_fields = elt->purpose;
+-            output_init_element (input_location, elt->value, elt->origtype,
+-                                 true, TREE_TYPE (elt->purpose),
+-                                 elt->purpose, false, false,
+-                                 braced_init_obstack);
+-          }
+-        else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos))
++        int cmp = init_field_decl_cmp (constructor_unfilled_fields,
++                                       elt->purpose);
++        if (cmp == 0)
++          output_init_element (input_location, elt->value, elt->origtype,
++                               true, TREE_TYPE (elt->purpose),
++                               elt->purpose, false, false,
++                               braced_init_obstack);
++        else if (cmp < 0)
+           {
+             /* Advance to the next smaller node.  */
+             if (elt->left)
+@@ -9431,8 +9483,8 @@ output_pending_init_elements (int all, struct obstack * 
braced_init_obstack)
+                   elt = elt->parent;
+                 elt = elt->parent;
+                 if (elt
+-                    && (tree_int_cst_lt (ctor_unfilled_bitpos,
+-                                         bit_position (elt->purpose))))
++                    && init_field_decl_cmp (constructor_unfilled_fields,
++                                            elt->purpose) < 0)
+                   {
+                     next = elt->purpose;
+                     break;
+--- /dev/null
++++ b/gcc/testsuite/gcc.c-torture/compile/pr85704.c
+@@ -0,0 +1,10 @@
++/* PR c/85704 */
++
++struct C { struct {} c; };
++struct D { int d; struct C e; int f; };
++
++void
++foo (struct D *x)
++{
++  *x = (struct D) { .e = (struct C) { .c = {} } };
++}
+-- 
+2.19.1
+

diff --git a/8.2.0/gentoo/README.history b/8.2.0/gentoo/README.history
index 776f49d..d85e258 100644
--- a/8.2.0/gentoo/README.history
+++ b/8.2.0/gentoo/README.history
@@ -1,3 +1,6 @@
+1.5            TODO
+       + 111_all_ubd-hog-PR85704.patch
+
 1.4            01 Oct 2018
        + 105_all_libgfortran-Werror.patch
        + 106_all_libgomp-Werror.patch

Reply via email to