This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix cgraph verification (PR middle-end/51929)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Guenther <rguenther at suse dot de>, Jan Hubicka <jh at suse dot cz>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 10 Feb 2012 15:25:07 +0100
- Subject: [PATCH] Fix cgraph verification (PR middle-end/51929)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
As discussed in the PR, this is a verification ICE if a call stmt
calls a same_body_alias (__comp_ctor) and IPA-CP decides to clone the
ctor, it clones the function with the body (__base_ctor), but
before the call stmts are updated, the checking fails because
the clone isn't clone or former clone of the called function,
but its alias.
Fixed by adjusting the verifier, bootstrapped/regtested on x86_64-linux
and i686-linux, ok for trunk?
2012-02-10 Jakub Jelinek <jakub@redhat.com>
PR middle-end/51929
* cgraphunit.c (verify_edge_corresponds_to_fndecl): If node is
a same_body_alias, also test whether e->callee isn't a former
or current clone of the decl this is a same body alias of.
(verify_cgraph_node): Fix a typo in error message.
* g++.dg/ipa/pr51929.C: New test.
--- gcc/cgraphunit.c.jj 2012-02-03 13:31:41.000000000 +0100
+++ gcc/cgraphunit.c 2012-02-10 12:35:44.682099203 +0100
@@ -471,11 +471,17 @@ verify_edge_corresponds_to_fndecl (struc
return false;
node = cgraph_function_or_thunk_node (node, NULL);
- if ((e->callee->former_clone_of != node->decl)
+ if ((e->callee->former_clone_of != node->decl
+ && (!node->same_body_alias
+ || e->callee->former_clone_of != node->thunk.alias))
/* IPA-CP sometimes redirect edge to clone and then back to the former
- function. This ping-pong has to go, eventaully. */
+ function. This ping-pong has to go, eventually. */
&& (node != cgraph_function_or_thunk_node (e->callee, NULL))
- && !clone_of_p (node, e->callee))
+ && !clone_of_p (node, e->callee)
+ /* If decl is a same body alias of some other decl, allow e->callee to be
+ a clone of a clone of that other decl too. */
+ && (!node->same_body_alias
+ || !clone_of_p (cgraph_get_node (node->thunk.alias), e->callee)))
return true;
else
return false;
@@ -667,7 +673,7 @@ verify_cgraph_node (struct cgraph_node *
for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
if (ref->use != IPA_REF_ALIAS)
{
- error ("Alias has non-alias refernece");
+ error ("Alias has non-alias reference");
error_found = true;
}
else if (ref_found)
--- gcc/testsuite/g++.dg/ipa/pr51929.C.jj 2012-02-10 12:36:55.792748549 +0100
+++ gcc/testsuite/g++.dg/ipa/pr51929.C 2012-02-09 19:42:10.000000000 +0100
@@ -0,0 +1,32 @@
+// PR middle-end/51929
+// { dg-do compile }
+// { dg-options "-O -fno-guess-branch-probability -fipa-cp -fipa-cp-clone --param=max-inline-insns-single=25" }
+
+struct A
+{
+ A (A, unsigned);
+ A (const char *);
+ ~A () { a1 (a4 ()); }
+ void a1 (int);
+ unsigned a2 ();
+ char *a3 ();
+ int a4 ();
+};
+
+template <typename T>
+struct B
+{
+ A b;
+ B (A x, int y = 1) : b (x.a3 (), x.a2 ()) { if (y & 1) b.a2 (); }
+};
+
+extern template struct B <char>;
+A a1 ("foo"), a2 ("bar");
+B<char> b1 (a1), b2 (a2, 8);
+
+void
+foo ()
+{
+ A a3 ("baz");
+ B<char> b3 (a1), b4 (a3);
+}
Jakub