diff options
author | Richard Guenther <rguenther@suse.de> | 2012-03-06 09:54:06 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-03-06 09:54:06 +0000 |
commit | 6bb485a36af85c406eed0136210fd25b97d9a01c (patch) | |
tree | 74b564fcecfa65fe616c1269328df3279547f6bb /gcc/lto | |
parent | b7b5540a8ae6d202ed0bc70b16c2d6170a8d9221 (diff) | |
download | gcc-6bb485a36af85c406eed0136210fd25b97d9a01c.tar.gz |
re PR middle-end/52097 (ICE: in get_bit_range, at expr.c:4535 with -O -flto -fexceptions -fnon-call-exceptions --param allow-store-data-races=0)
2012-03-06 Richard Guenther <rguenther@suse.de>
PR lto/52097
* lto.c (uniquify_nodes): Merge TYPE_FIELDS of variant types.
* gcc.dg/lto/pr52097_0.c: New testcase.
From-SVN: r184981
Diffstat (limited to 'gcc/lto')
-rw-r--r-- | gcc/lto/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/lto/lto.c | 35 |
2 files changed, 40 insertions, 0 deletions
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 6d074db096c..16624e61482 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,8 @@ +2012-03-06 Richard Guenther <rguenther@suse.de> + + PR lto/52097 + * lto.c (uniquify_nodes): Merge TYPE_FIELDS of variant types. + 2012-02-28 Richard Guenther <rguenther@suse.de> PR lto/52400 diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index f267d2a4ec4..83b53918f98 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -798,6 +798,41 @@ uniquify_nodes (struct data_in *data_in, unsigned from) TYPE_NEXT_VARIANT (mv) = t; if (RECORD_OR_UNION_TYPE_P (t)) TYPE_BINFO (t) = TYPE_BINFO (mv); + /* Preserve the invariant that type variants share their + TYPE_FIELDS. */ + if (RECORD_OR_UNION_TYPE_P (t) + && TYPE_FIELDS (mv) != TYPE_FIELDS (t)) + { + tree f1, f2; + for (f1 = TYPE_FIELDS (mv), f2 = TYPE_FIELDS (t); + f1 && f2; f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2)) + { + unsigned ix; + gcc_assert (f1 != f2 + && DECL_NAME (f1) == DECL_NAME (f2)); + if (!streamer_tree_cache_lookup (cache, f2, &ix)) + gcc_unreachable (); + /* If we're going to replace an element which we'd + still visit in the next iterations, we wouldn't + handle it, so do it here. We do have to handle it + even though the field_decl itself will be removed, + as it could refer to e.g. integer_cst which we + wouldn't reach via any other way, hence they + (and their type) would stay uncollected. */ + /* ??? We should rather make sure to replace all + references to f2 with f1. That means handling + COMPONENT_REFs and CONSTRUCTOR elements in + lto_fixup_types and special-case the field-decl + operand handling. */ + /* ??? Not sure the above is all relevant in this + path canonicalizing TYPE_FIELDS to that of the + main variant. */ + if (ix < i) + lto_fixup_types (f2); + streamer_tree_cache_insert_at (cache, f1, ix); + } + TYPE_FIELDS (t) = TYPE_FIELDS (mv); + } } /* Finally adjust our main variant and fix it up. */ |