This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH]: fix bug 143
- To: gcc-patches at gcc dot gnu dot org
- Subject: [C++ PATCH]: fix bug 143
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Tue, 20 Jun 2000 17:17:53 +0100
- Organization: Codesourcery LLC
Hi,
I've installed the attached patch and testcase which fixes bug 143.
When fishing out the FIELD_DECL of a vbase pointer, we'd forget that it
might be in a base at non-zero offset. Hence out type_info structures
could be hosed.
Approved by Mark, built & tested on i686-pc-linux-gnu
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2000-06-20 Nathan Sidwell <nathan@codesourcery.com>
* rtti.c (get_base_offset): Cope when vbase field is in a base.
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/rtti.c,v
retrieving revision 1.95
diff -c -3 -p -r1.95 rtti.c
*** rtti.c 2000/06/14 05:30:05 1.95
--- rtti.c 2000/06/20 12:18:05
*************** get_base_offset (binfo, parent)
*** 549,558 ****
else if (! vbase_offsets_in_vtable_p ())
{
const char *name;
FORMAT_VBASE_NAME (name, BINFO_TYPE (binfo));
! return byte_position (lookup_field (parent, get_identifier (name),
! 0, 0));
}
else
/* Under the new ABI, we store the vtable offset at which
--- 549,573 ----
else if (! vbase_offsets_in_vtable_p ())
{
const char *name;
+ tree result;
+ tree field;
FORMAT_VBASE_NAME (name, BINFO_TYPE (binfo));
! field = lookup_field (parent, get_identifier (name), 0, 0);
! result = byte_position (field);
!
! if (DECL_CONTEXT (field) != parent)
! {
! /* The vbase pointer might be in a non-virtual base of PARENT.
! * Adjust for the offset of that base in PARENT. */
! tree path;
!
! get_base_distance (DECL_CONTEXT (field), parent, -1, &path);
! result = build (PLUS_EXPR, TREE_TYPE (result),
! result, BINFO_OFFSET (path));
! result = fold (result);
! }
! return result;
}
else
/* Under the new ABI, we store the vtable offset at which
2000-06-20 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.other/dyncast6.C: New test.
Index: testsuite/g++.old-deja/g++.other/dyncast6.C
===================================================================
RCS file: dyncast6.C
diff -N dyncast6.C
*** /dev/null Tue May 5 13:32:27 1998
--- dyncast6.C Tue Jun 20 09:14:04 2000
***************
*** 0 ****
--- 1,72 ----
+ // Special g++ Options: -w -ansi -pedantic-errors
+
+ // Copyright (C) 2000 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 20 June 2000 <nathan@codesourcery.com>
+
+ // Origin GNATS bug report 143 from Carlo Wood <carlo@runaway.xs4all.nl>
+ // We were generating incorrect type_info structures, and hence breaking
+ // dynamic_cast.
+
+ #include <stdio.h>
+
+ class OBASE { public: virtual void bz () {}};
+ class IBASE { public: virtual void by () {}};
+
+ class V {public:int m; };
+
+ class A : public virtual V { };
+ class AA : public A {};
+
+ class B : public OBASE, public A { public: virtual void foo(void) { } };
+ class B1 : public OBASE, public AA { public: virtual void foo(void) { } };
+
+ class C : public IBASE, public virtual V { };
+
+ class D : public B, public C { };
+
+ class E : public B, public virtual V { };
+
+ class E1 : public B1, public virtual V {};
+
+ class E2 : public B1, public A, public virtual V {};
+
+ int main(void)
+ {
+ D d;
+ E e;
+ E1 e1;
+ E2 e2;
+ int code = 0;
+
+ OBASE* osd = &d;
+ OBASE* ose = &e;
+ OBASE* ose1 = &e1;
+ OBASE* ose2 = &e2;
+
+
+ if (!dynamic_cast<V*>(osd))
+ {
+ printf ("fail osd\n");
+ code++;
+ }
+
+ if (!dynamic_cast<V*>(ose))
+ {
+ printf ("fail ose\n");
+ code++;
+ }
+
+ if (!dynamic_cast<V*>(ose1))
+ {
+ printf ("fail ose1\n");
+ code++;
+ }
+
+ if (!dynamic_cast<V*>(ose2))
+ {
+ printf ("fail ose2\n");
+ code++;
+ }
+
+ return code;
+ }