Patchwork C++ PATCH for c++/47873 (bad code with covariant virtuals)

login
register
mail settings
Submitter Jason Merrill
Date Feb. 28, 2011, 9:40 p.m.
Message ID <4D6C165B.3070508@redhat.com>
Download mbox | patch
Permalink /patch/84868/
State New
Headers show

Comments

Jason Merrill - Feb. 28, 2011, 9:40 p.m.
When I rewrote our covariant thunk handling to fix 43120, I was confused 
about what BINFO_LOST_PRIMARY_P meant; I thought it meant that the binfo 
was itself a lost primary, rather than that the binfo lost its primary. 
  So I put the tests in the wrong order: a binfo with 
BINFO_LOST_PRIMARY_P is still interesting, it's its primary that we 
aren't interested in.  So we need to check for a non-thunk before we 
check BINFO_LOST_PRIMARY_P.

Tested x86_64-pc-linux-gnu, applied to trunk.
commit 421e8d4642b0639dc3fca4478d661a76ee5aa022
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Feb 28 13:13:03 2011 -0500

    	PR c++/47873
    	* class.c (update_vtable_entry_for_fn): Check BINFO_LOST_PRIMARY_P
    	after checking for a non-thunk.

Patch

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 0d485fc..1325260 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2250,10 +2250,10 @@  update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
 	{
 	  tree main_binfo = TYPE_BINFO (BINFO_TYPE (b));
 	  tree bv = chain_index (ix, BINFO_VIRTUALS (main_binfo));
+	  if (!DECL_THUNK_P (TREE_VALUE (bv)))
+	    break;
 	  if (BINFO_LOST_PRIMARY_P (b))
 	    lost = true;
-	  if (!DECL_THUNK_P (TREE_VALUE (bv)))
-	    break;
 	}
       first_defn = b;
     }
diff --git a/gcc/testsuite/g++.dg/inherit/covariant18.C b/gcc/testsuite/g++.dg/inherit/covariant18.C
new file mode 100644
index 0000000..31e6216
--- /dev/null
+++ b/gcc/testsuite/g++.dg/inherit/covariant18.C
@@ -0,0 +1,41 @@ 
+// PR c++/47873
+// { dg-do run }
+
+struct Base
+{
+    virtual ~Base(){}
+
+    virtual Base& This() { return *this; }
+};
+
+
+struct Ent : virtual Base
+{
+    void *m_Body;
+
+    Ent& This() { return *this; }
+
+    virtual Ent& body()
+    {
+        return This();
+    }
+
+};
+
+
+struct Msg : virtual Ent
+{
+    Msg()
+    {
+        body();
+    }
+
+    Msg& This() { return *this; }
+};
+
+int main()
+{
+    Msg m;
+
+    return 0;
+}