aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2019-03-21 23:04:29 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2019-03-21 23:04:29 +0100
commit774856e3fbc2b1b6ab67470a7d6fc7cb7b4be546 (patch)
tree7061da68fd12dcff4b6b50141a6b8cff428ef595
parent8c8b42cf72f677e004909b2ab3b3f12353fb94d5 (diff)
downloadgcc-774856e3fbc2b1b6ab67470a7d6fc7cb7b4be546.zip
gcc-774856e3fbc2b1b6ab67470a7d6fc7cb7b4be546.tar.gz
gcc-774856e3fbc2b1b6ab67470a7d6fc7cb7b4be546.tar.bz2
re PR lto/89692 (ICE in streamer_write_chain, at tree-streamer-out.c:506)
PR lto/89692 * tree.c (fld_type_variant, fld_incomplete_type_of, fld_process_array_type): Call fld->pset.add and don't call add_tree_to_fld_list if it returns true. (free_lang_data_in_type): Similarly with self-recursive call. Purge non-marked types from TYPE_NEXT_VARIANT list. (find_decls_types_r): Call fld_worklist_push for TYPE_CANONICAL (t). * g++.dg/other/pr89692.C: New test. From-SVN: r269862
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/other/pr89692.C20
-rw-r--r--gcc/tree.c30
4 files changed, 57 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2f1bf46..2f0c540 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2019-03-21 Jan Hubicka <hubicka@ucw.cz>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR lto/89692
+ * tree.c (fld_type_variant, fld_incomplete_type_of,
+ fld_process_array_type): Call fld->pset.add and don't call
+ add_tree_to_fld_list if it returns true.
+ (free_lang_data_in_type): Similarly with self-recursive call. Purge
+ non-marked types from TYPE_NEXT_VARIANT list.
+ (find_decls_types_r): Call fld_worklist_push for TYPE_CANONICAL (t).
+
2019-03-21 Jakub Jelinek <jakub@redhat.com>
* hash-table.h (hash_table): Add Lazy template parameter defaulted
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2334e97..4edc0ef 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2019-03-21 Jakub Jelinek <jakub@redhat.com>
+ PR lto/89692
+ * g++.dg/other/pr89692.C: New test.
+
PR c++/89767
* g++.dg/cpp1y/lambda-init18.C: New test.
* g++.dg/cpp1y/lambda-init19.C: New test.
diff --git a/gcc/testsuite/g++.dg/other/pr89692.C b/gcc/testsuite/g++.dg/other/pr89692.C
new file mode 100644
index 0000000..36adeb5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/pr89692.C
@@ -0,0 +1,20 @@
+// PR lto/89692
+// { dg-do compile }
+// { dg-require-effective-target lto }
+// { dg-options "-flto -O2" }
+
+struct S {
+ short int a, b;
+ unsigned char c : 1;
+};
+
+bool
+foo (void)
+{
+ unsigned char d[sizeof (S)] = { 0 };
+ S e;
+
+ __builtin_memcpy (&e, d, sizeof (d));
+
+ return e.c == d[0];
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index ae8ff08..65f8cd3 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -5215,7 +5215,8 @@ fld_type_variant (tree first, tree t, struct free_lang_data_d *fld,
if (inner_type)
TREE_TYPE (v) = inner_type;
gcc_checking_assert (fld_type_variant_equal_p (t,v, inner_type));
- add_tree_to_fld_list (v, fld);
+ if (!fld->pset.add (v))
+ add_tree_to_fld_list (v, fld);
return v;
}
@@ -5253,7 +5254,8 @@ fld_process_array_type (tree t, tree t2, hash_map<tree, tree> *map,
array = build_array_type_1 (t2, TYPE_DOMAIN (t),
TYPE_TYPELESS_STORAGE (t), false);
TYPE_CANONICAL (array) = TYPE_CANONICAL (t);
- add_tree_to_fld_list (array, fld);
+ if (!fld->pset.add (array))
+ add_tree_to_fld_list (array, fld);
}
return array;
}
@@ -5298,7 +5300,8 @@ fld_incomplete_type_of (tree t, struct free_lang_data_d *fld)
TYPE_REF_CAN_ALIAS_ALL (t));
gcc_assert (TYPE_CANONICAL (t2) != t2
&& TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE (t)));
- add_tree_to_fld_list (first, fld);
+ if (!fld->pset.add (first))
+ add_tree_to_fld_list (first, fld);
return fld_type_variant (first, t, fld);
}
return t;
@@ -5321,7 +5324,8 @@ fld_incomplete_type_of (tree t, struct free_lang_data_d *fld)
copy = build_distinct_type_copy (t);
/* It is possible that type was not seen by free_lang_data yet. */
- add_tree_to_fld_list (copy, fld);
+ if (!fld->pset.add (copy))
+ add_tree_to_fld_list (copy, fld);
TYPE_SIZE (copy) = NULL;
TYPE_USER_ALIGN (copy) = 0;
TYPE_SIZE_UNIT (copy) = NULL;
@@ -5445,6 +5449,18 @@ free_lang_data_in_type (tree type, struct free_lang_data_d *fld)
TYPE_NEEDS_CONSTRUCTING (type) = 0;
+ /* Purge non-marked variants from the variants chain, so that they
+ don't reappear in the IL after free_lang_data. */
+ while (TYPE_NEXT_VARIANT (type)
+ && !fld->pset.contains (TYPE_NEXT_VARIANT (type)))
+ {
+ tree t = TYPE_NEXT_VARIANT (type);
+ TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (t);
+ /* Turn the removed types into distinct types. */
+ TYPE_MAIN_VARIANT (t) = t;
+ TYPE_NEXT_VARIANT (t) = NULL_TREE;
+ }
+
if (TREE_CODE (type) == FUNCTION_TYPE)
{
TREE_TYPE (type) = fld_simplified_type (TREE_TYPE (type), fld);
@@ -5464,7 +5480,8 @@ free_lang_data_in_type (tree type, struct free_lang_data_d *fld)
& ~TYPE_QUAL_CONST
& ~TYPE_QUAL_VOLATILE;
TREE_VALUE (p) = build_qualified_type (arg_type, quals);
- free_lang_data_in_type (TREE_VALUE (p), fld);
+ if (!fld->pset.add (TREE_VALUE (p)))
+ free_lang_data_in_type (TREE_VALUE (p), fld);
}
/* C++ FE uses TREE_PURPOSE to store initial values. */
TREE_PURPOSE (p) = NULL;
@@ -5886,8 +5903,7 @@ find_decls_types_r (tree *tp, int *ws, void *data)
ctx = BLOCK_SUPERCONTEXT (ctx);
fld_worklist_push (ctx, fld);
}
- /* Do not walk TYPE_CANONICAL. We do not stream it and thus do not
- and want not to reach unused types this way. */
+ fld_worklist_push (TYPE_CANONICAL (t), fld);
if (RECORD_OR_UNION_TYPE_P (t) && TYPE_BINFO (t))
{