diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2019-03-21 23:04:29 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-03-21 23:04:29 +0100 |
commit | 774856e3fbc2b1b6ab67470a7d6fc7cb7b4be546 (patch) | |
tree | 7061da68fd12dcff4b6b50141a6b8cff428ef595 | |
parent | 8c8b42cf72f677e004909b2ab3b3f12353fb94d5 (diff) | |
download | gcc-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/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/pr89692.C | 20 | ||||
-rw-r--r-- | gcc/tree.c | 30 |
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]; +} @@ -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)) { |