diff options
author | Martin Jambor <mjambor@suse.cz> | 2014-03-21 13:59:35 +0100 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2014-03-21 13:59:35 +0100 |
commit | 3d8d00439b8507ebb9c89949d44133bbdcde333f (patch) | |
tree | 9a7d70708594301be7def95ae86b5e51f4577ef8 | |
parent | d833415cdac558ab5da28048154d119856b62ad6 (diff) | |
download | gcc-3d8d00439b8507ebb9c89949d44133bbdcde333f.zip gcc-3d8d00439b8507ebb9c89949d44133bbdcde333f.tar.gz gcc-3d8d00439b8507ebb9c89949d44133bbdcde333f.tar.bz2 |
re PR ipa/59176 (ICE edge points to wrong declaration / verify_cgraph_node failed)
2014-03-21 Martin Jambor <mjambor@suse.cz>
PR ipa/59176
* cgraph.h (symtab_node): New flag body_removed.
* ipa.c (symtab_remove_unreachable_nodes): Set body_removed flag
when removing bodies.
* symtab.c (dump_symtab_base): Dump body_removed flag.
* cgraph.c (verify_edge_corresponds_to_fndecl): Skip nodes which
had their bodies removed.
testsuite/
* g++.dg/torture/pr59176.C: New test.
From-SVN: r208748
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cgraph.c | 9 | ||||
-rw-r--r-- | gcc/cgraph.h | 4 | ||||
-rw-r--r-- | gcc/ipa.c | 2 | ||||
-rw-r--r-- | gcc/symtab.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/pr59176.C | 41 |
7 files changed, 70 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c56a5b7..57a7688 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2014-03-21 Martin Jambor <mjambor@suse.cz> + PR ipa/59176 + * cgraph.h (symtab_node): New flag body_removed. + * ipa.c (symtab_remove_unreachable_nodes): Set body_removed flag + when removing bodies. + * symtab.c (dump_symtab_base): Dump body_removed flag. + * cgraph.c (verify_edge_corresponds_to_fndecl): Skip nodes which + had their bodies removed. + +2014-03-21 Martin Jambor <mjambor@suse.cz> + PR ipa/60419 * ipa.c (symtab_remove_unreachable_nodes): Clear thunk flag of nodes in the border. diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 577352f..abfd63c 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -2604,8 +2604,13 @@ verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl) node = cgraph_get_node (decl); /* We do not know if a node from a different partition is an alias or what it - aliases and therefore cannot do the former_clone_of check reliably. */ - if (!node || node->in_other_partition || e->callee->in_other_partition) + aliases and therefore cannot do the former_clone_of check reliably. When + body_removed is set, we have lost all information about what was alias or + thunk of and also cannot proceed. */ + if (!node + || node->body_removed + || node->in_other_partition + || e->callee->in_other_partition) return false; node = cgraph_function_or_thunk_node (node, NULL); diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 32b1ee1..59d9ce6 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -91,7 +91,9 @@ public: unsigned forced_by_abi : 1; /* True when the name is known to be unique and thus it does not need mangling. */ unsigned unique_name : 1; - + /* True when body and other characteristics have been removed by + symtab_remove_unreachable_nodes. */ + unsigned body_removed : 1; /*** WHOPR Partitioning flags. These flags are used at ltrans stage when only part of the callgraph is @@ -484,6 +484,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) { if (file) fprintf (file, " %s", node->name ()); + node->body_removed = true; node->analyzed = false; node->definition = false; node->cpp_implicit_alias = false; @@ -543,6 +544,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) fprintf (file, " %s", vnode->name ()); changed = true; } + vnode->body_removed = true; vnode->definition = false; vnode->analyzed = false; vnode->aux = NULL; diff --git a/gcc/symtab.c b/gcc/symtab.c index 2d6f665..4db4870 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -601,6 +601,8 @@ dump_symtab_base (FILE *f, symtab_node *node) ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->alias_target)) : IDENTIFIER_POINTER (node->alias_target)); + if (node->body_removed) + fprintf (f, "\n Body removed by symtab_remove_unreachable_nodes"); fprintf (f, "\n Visibility:"); if (node->in_other_partition) fprintf (f, " in_other_partition"); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 581efab..9740621 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2014-03-21 Martin Jambor <mjambor@suse.cz> + PR ipa/59176 + * g++.dg/torture/pr59176.C: New test. + +2014-03-21 Martin Jambor <mjambor@suse.cz> + PR ipa/60419 * g++.dg/ipa/pr60419.C: New test. diff --git a/gcc/testsuite/g++.dg/ipa/pr59176.C b/gcc/testsuite/g++.dg/ipa/pr59176.C new file mode 100644 index 0000000..d576bc3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr59176.C @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +template <class> class A { +protected: + void m_fn2(); + ~A() { m_fn2(); } + virtual void m_fn1(); +}; + +class D : A<int> {}; +template <class Key> void A<Key>::m_fn2() { + m_fn1(); + m_fn1(); + m_fn1(); +} + +#pragma interface +class B { + D m_cellsAlreadyProcessed; + D m_cellsNotToProcess; + +public: + virtual ~B() {} + void m_fn1(); +}; + +class C { + unsigned long m_fn1(); + B m_fn2(); + unsigned long m_fn3(); +}; +unsigned long C::m_fn1() { +CellHierarchy: + m_fn2().m_fn1(); +} + +unsigned long C::m_fn3() { +CellHierarchy: + m_fn2().m_fn1(); +} |