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
