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]

[C++ PATCH]: fix bug 143


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;
+ }

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