aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-07-06 18:13:51 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-07-06 18:13:51 -0400
commit62c99ce47506cfa0d451e96722614cc786497cda (patch)
tree432036f472304641038076640d60f211c0be7e45 /gcc
parente90e6bd7377e37334a4bc1ce17278025e760ec09 (diff)
downloadgcc-62c99ce47506cfa0d451e96722614cc786497cda.zip
gcc-62c99ce47506cfa0d451e96722614cc786497cda.tar.gz
gcc-62c99ce47506cfa0d451e96722614cc786497cda.tar.bz2
vmi_class_type_info.cc (__do_dyncast): Use src2dst hint to defer searching bases that don't overlap the desired address.
* libsupc++/vmi_class_type_info.cc (__do_dyncast): Use src2dst hint to defer searching bases that don't overlap the desired address. From-SVN: r149297
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/rtti/dyncast3.C81
-rw-r--r--gcc/testsuite/g++.dg/rtti/dyncast4.C26
3 files changed, 111 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 81ed85c..3a97503 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2009-07-06 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/rtti/dyncast[34].C: New.
+
2009-07-06 Nathan Froyd <froydnj@codesourcery.com>
* lib/target-supports.exp
diff --git a/gcc/testsuite/g++.dg/rtti/dyncast3.C b/gcc/testsuite/g++.dg/rtti/dyncast3.C
new file mode 100644
index 0000000..0835259
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/dyncast3.C
@@ -0,0 +1,81 @@
+// This testcase used to crash while looking in A for my_module. I'm still
+// not sure it's well-formed, but it works now because of the optimization
+// to look at the expected address first.
+
+// { dg-do run }
+
+extern "C" int puts (const char *);
+extern "C" void abort ();
+
+struct my_object
+{
+ my_object() { puts ("in my_object ctor");}
+ virtual ~my_object() { puts ("in my_object dtor"); }
+};
+
+my_object* my_module_ptr = 0;
+
+struct my_module : my_object
+{
+ my_module()
+ {
+ puts ("in my_module ctor, setting up ptr");
+ my_module_ptr = this;
+ }
+ ~my_module() { puts ("in my_module dtor");}
+};
+
+struct D
+{
+ D() { puts ("in D ctor"); }
+ virtual ~D();
+};
+
+D::~D()
+{
+ puts ("in D dtor");
+ puts ("before DCASTing to my_module*");
+ my_module* m = dynamic_cast<my_module*>(my_module_ptr);
+ if (m != my_module_ptr)
+ abort ();
+ puts ("after DCASTing to my_module*");
+}
+
+struct my_interface
+{
+ my_interface() { puts ("in my_interface ctor");}
+ ~my_interface() { puts ("in my_interface dtor");}
+};
+
+struct myif : virtual my_interface
+{
+ myif() { puts ("in myif ctor");}
+ ~myif() { puts ("in myif dtor");}
+};
+
+struct A: virtual myif
+{
+ A() { puts ("in A ctor"); }
+ ~A() { puts ("in A dtor"); }
+
+ D d;
+};
+
+struct B: virtual myif
+{
+ B() { puts ("in B ctor"); }
+ ~B() { puts ("in B dtor"); }
+
+ D d;
+};
+
+struct C : my_module, A, B
+{
+ C() { puts ("in C ctor");}
+ ~C() { puts ("in C dtor"); }
+};
+
+int main(int, char**)
+{
+ C t;
+}
diff --git a/gcc/testsuite/g++.dg/rtti/dyncast4.C b/gcc/testsuite/g++.dg/rtti/dyncast4.C
new file mode 100644
index 0000000..2a5fd2b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/dyncast4.C
@@ -0,0 +1,26 @@
+// Test to make sure that we keep searching if we don't find the type we
+// want at the expected address.
+
+// { dg-do run }
+
+struct A
+{
+ virtual void f() {};
+};
+
+struct B: A { };
+
+struct C: A { };
+
+struct D: B, C { };
+
+int main()
+{
+ D d;
+ A* ap = static_cast<B*>(&d);
+ C* cp = dynamic_cast<C*>(ap);
+ if (cp == 0)
+ return 1;
+ else
+ return 0;
+}