This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix cgraph verification (PR middle-end/51929)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]