]> gcc.gnu.org Git - gcc.git/commitdiff
decl.c (finish_destructor_body): Convert to vbase pointer here.
authorNathan Sidwell <nathan@codesourcery.com>
Thu, 18 Jan 2001 09:39:13 +0000 (09:39 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 18 Jan 2001 09:39:13 +0000 (09:39 +0000)
cp:
* decl.c (finish_destructor_body): Convert to vbase pointer here.
testsuite:
* g++.old-deja/g++.abi/vbase1.C: New test.

From-SVN: r39114

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.abi/vbase1.C [new file with mode: 0644]

index c020cfaf3d0bca05b1d6a3bf50bedfb220ed10ad..56b84835a42ea8e578a590c62b337b0a1fd1762a 100644 (file)
@@ -1,3 +1,7 @@
+2001-01-18  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * decl.c (finish_destructor_body): Convert to vbase pointer here.
+
 2001-01-18  Nathan Sidwell  <nathan@codesourcery.com>
 
        * semantics.c (begin_class_definition): Check we're not inside a
index ff3084e8dfe38aa399620e1b5033f2e62a3ad82c..e5fd61e73dca2e3b72d57534fbdfa97ca221dc9d 100644 (file)
@@ -13862,16 +13862,26 @@ finish_destructor_body ()
               vbases = TREE_CHAIN (vbases))
            {
              tree vbase = TREE_VALUE (vbases);
+             tree base_type = BINFO_TYPE (vbase);
 
-             if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (vbase)))
+             if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (base_type))
                {
-                 tree vb = get_vbase
-                   (BINFO_TYPE (vbase),
-                    TYPE_BINFO (current_class_type));
-                 finish_expr_stmt
-                   (build_scoped_method_call
-                    (current_class_ref, vb, base_dtor_identifier,
-                     NULL_TREE));
+                  tree base_ptr_type = build_pointer_type (base_type);
+                 tree expr = current_class_ptr;
+                 
+                 /* Convert to the basetype here, as we know the layout is
+                     fixed. What is more, if we let build_method_call do it,
+                     it will use the vtable, which may have been clobbered
+                     by the deletion of our primary base.  */
+                  
+                  expr = build1 (NOP_EXPR, base_ptr_type, expr);
+                 expr = build (PLUS_EXPR, base_ptr_type, expr,
+                               BINFO_OFFSET (vbase));
+                 expr = build_indirect_ref (expr, NULL);
+                 expr = build_method_call (expr, base_dtor_identifier,
+                                           NULL_TREE, vbase,
+                                           LOOKUP_NORMAL);
+                 finish_expr_stmt (expr);
                }
            }
 
index 4b00c044efc05ada0969b03f21947e81f29ad06b..30643601bffd5a8370a0132fe7213705b62dafc2 100644 (file)
@@ -1,3 +1,7 @@
+2001-01-18  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.old-deja/g++.abi/vbase1.C: New test.
+
 2001-01-18  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.old-deja/g++.pt/crash65.C: New test.
diff --git a/gcc/testsuite/g++.old-deja/g++.abi/vbase1.C b/gcc/testsuite/g++.old-deja/g++.abi/vbase1.C
new file mode 100644 (file)
index 0000000..a85e00d
--- /dev/null
@@ -0,0 +1,114 @@
+// Copyright (C) 2000 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 16 Jan 2001 <nathan@codesourcery.com>
+
+// Bug 1611. Under the new ABI, the vtable can be clobered during dtoring our
+// primary vbase. We mustn't use the vtable after that to locate our vbases.
+
+#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
+#include <stdio.h>
+#include <stdlib.h>
+
+int *ctorVBase = 0;
+int *dtorVBase = 0;
+int *ctorVDerived = 0;
+int *dtorVDerived = 0;
+int *ctorB = 0;
+int *dtorB = 0;
+
+struct VBase
+{
+  int member;
+  VBase ()
+    {
+      if (ctorVBase) exit (1);
+      ctorVBase = &member;
+    }
+  virtual ~VBase ()
+    {
+      if (dtorVBase) exit (2);
+      dtorVBase = &member;
+      if (dtorVBase != ctorVBase) exit (3);
+    }
+  void Offset () const
+  {
+    printf ("VBase\n");
+    printf ("  VBase::member %d\n", &this->VBase::member - (int *)this);
+  }
+};
+
+struct VDerived : virtual VBase
+{
+  int member;
+  
+  VDerived ()
+    {
+      if (ctorVDerived) exit (4);
+      ctorVDerived = &member;
+    }
+  virtual ~VDerived ()
+    {
+      if (dtorVDerived) exit (5);
+      dtorVDerived = &member;
+      if (dtorVDerived != ctorVDerived) exit (6);
+    }
+  void Offset () const
+  {
+    printf ("VDerived\n");
+    printf ("  VBase::member %d\n", &this->VBase::member - (int *)this);
+    printf ("  VDerived::member %d\n", &this->VDerived::member - (int *)this);
+  }
+};
+struct B : virtual VBase
+{
+  int member;
+  void Offset () const
+  {
+    printf ("B\n");
+    printf ("  VBase::member %d\n", &this->VBase::member - (int *)this);
+    printf ("  B::member %d\n", &this->B::member - (int *)this);
+  }
+};
+struct MostDerived : B, virtual VDerived
+{
+  int member;
+  void Offset () const
+  {
+    printf ("MostDerived\n");
+    printf ("  VBase::member %d\n", &this->VBase::member - (int *)this);
+    printf ("  B::member %d\n", &this->B::member - (int *)this);
+    printf ("  VDerived::member %d\n", &this->VDerived::member - (int *)this);
+    printf ("  MostDerived::member %d\n", &this->MostDerived::member - (int *)this);
+  }
+};
+
+
+int main ()
+{
+  {
+    MostDerived dum;
+    
+    int *this_ = (int *)&dum;
+    
+    if (ctorVBase != &dum.VBase::member)
+      return 23;
+    if (ctorVDerived != &dum.VDerived::member)
+      return 24;
+    
+    printf ("  VBase::member %d\n", &dum.VBase::member - this_);
+    printf ("  B::member %d\n", &dum.B::member - this_);
+    printf ("  VDerived::member %d\n", &dum.VDerived::member - this_);
+    printf ("  MostDerived::member %d\n", &dum.MostDerived::member - this_);
+    dum.MostDerived::Offset ();
+    dum.B::Offset ();
+    dum.VDerived::Offset ();
+    dum.VBase::Offset ();
+  }
+  return 0;
+}
+#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
+
+int main () 
+{
+}
+
+#endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
This page took 0.215735 seconds and 5 git commands to generate.