diff options
author | Martin Jambor <mjambor@suse.cz> | 2010-04-27 12:07:47 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2010-04-27 12:07:47 +0200 |
commit | 78eaf7bf186397f1ea7ca581c1e76e543eaac9b6 (patch) | |
tree | 815344fd064a1ca431cddb228100fe10fdc26f05 /gcc/ipa.c | |
parent | 5b56d3bbcab015c4dabf4c1ef82237ac0a37c792 (diff) | |
download | gcc-78eaf7bf186397f1ea7ca581c1e76e543eaac9b6.zip gcc-78eaf7bf186397f1ea7ca581c1e76e543eaac9b6.tar.gz gcc-78eaf7bf186397f1ea7ca581c1e76e543eaac9b6.tar.bz2 |
re PR middle-end/43812 (compiling .cc file with -fwhole-program results in ICE, in ipcp_iterate_stage, at ipa-cp.c:760)
2010-04-27 Martin Jambor <mjambor@suse.cz>
PR middle-end/43812
* ipa.c (dissolve_same_comdat_group_list): New function.
(function_and_variable_visibility): Call
dissolve_same_comdat_group_list when comdat group contains external or
newly local nodes.
* cgraphunit.c (verify_cgraph_node): Verify that same_comdat_group
lists are circular and that they contain only DECL_ONE_ONLY nodes.
* testsuite/g++.dg/ipa/pr43812.C: New test.
From-SVN: r158777
Diffstat (limited to 'gcc/ipa.c')
-rw-r--r-- | gcc/ipa.c | 37 |
1 files changed, 29 insertions, 8 deletions
@@ -355,6 +355,21 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program) return false; } +/* Dissolve the same_comdat_group list in which NODE resides. */ + +static void +dissolve_same_comdat_group_list (struct cgraph_node *node) +{ + struct cgraph_node *n = node, *next; + do + { + next = n->same_comdat_group; + n->same_comdat_group = NULL; + n = next; + } + while (n != node); +} + /* Mark visibility of all functions. A local function is one whose calls can occur only in the current @@ -385,17 +400,17 @@ function_and_variable_visibility (bool whole_program) and simplifies later passes. */ if (node->same_comdat_group && DECL_EXTERNAL (node->decl)) { - struct cgraph_node *n = node, *next; - do - { +#ifdef ENABLE_CHECKING + struct cgraph_node *n; + + for (n = node->same_comdat_group; + n != node; + n = n->same_comdat_group) /* If at least one of same comdat group functions is external, all of them have to be, otherwise it is a front-end bug. */ gcc_assert (DECL_EXTERNAL (n->decl)); - next = n->same_comdat_group; - n->same_comdat_group = NULL; - n = next; - } - while (n != node); +#endif + dissolve_same_comdat_group_list (node); } gcc_assert ((!DECL_WEAK (node->decl) && !DECL_COMDAT (node->decl)) || TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl)); @@ -411,6 +426,12 @@ function_and_variable_visibility (bool whole_program) { gcc_assert (whole_program || !TREE_PUBLIC (node->decl)); cgraph_make_decl_local (node->decl); + if (node->same_comdat_group) + /* cgraph_externally_visible_p has already checked all other nodes + in the group and they will all be made local. We need to + dissolve the group at once so that the predicate does not + segfault though. */ + dissolve_same_comdat_group_list (node); } node->local.local = (cgraph_only_called_directly_p (node) && node->analyzed |