This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix 21427
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 09 May 2005 12:47:42 +0100
- Subject: Fix 21427
This patch fixes 21427, a 3.4 ICE. Although the patch comes from
mainline, the test case is slightly different to that which caused the
mainline ICE. I'll therefore place the testcase on mainline too.
built & tested on i686-pc-linux-gnu
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2005-05-08 Nathan Sidwell <nathan@codesourcery.com>
PR c++/21427
Backport 2005-03-01 Nathan Sidwell <nathan@codesourcery.com>
* class.c (update_vtable_entry_for_fn): Don't crash on invalid
covariancy.
* cp-tree.h (THUNK_TARGET): Expand comment.
* method.c (use_thunk): Make sure we also use the target, if that
is a thunk.
Backport 2005-02-11 Nathan Sidwell <nathan@codesourcery.com>
* class.c (update_vtable_entry_for_fn): Walk the covariant's binfo
chain rather than using lookup_base.
2005-05-08 Nathan Sidwell <nathan@codesourcery.com>
PR c++/21427
* g++.dg/inherit/covariant13.C: New.
Backport 2005-03-01 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/inherit/covariant12.C: New.
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.595.4.10
diff -c -3 -p -r1.595.4.10 class.c
*** cp/class.c 21 Feb 2005 21:11:46 -0000 1.595.4.10
--- cp/class.c 8 May 2005 19:45:47 -0000
*************** update_vtable_entry_for_fn (tree t, tree
*** 2116,2121 ****
--- 2116,2124 ----
also be converting to the return type of FN, we have to
combine the two conversions here. */
tree fixed_offset, virtual_offset;
+
+ over_return = TREE_TYPE (over_return);
+ base_return = TREE_TYPE (base_return);
if (DECL_THUNK_P (fn))
{
*************** update_vtable_entry_for_fn (tree t, tree
*** 2133,2164 ****
virtual_offset =
TREE_VALUE (purpose_member
(BINFO_TYPE (virtual_offset),
! CLASSTYPE_VBASECLASSES (TREE_TYPE (over_return))));
! else if (!same_type_p (TREE_TYPE (over_return),
! TREE_TYPE (base_return)))
! {
! /* There was no existing virtual thunk (which takes
! precedence). */
! tree thunk_binfo;
! base_kind kind;
! thunk_binfo = lookup_base (TREE_TYPE (over_return),
! TREE_TYPE (base_return),
! ba_check | ba_quiet, &kind);
!
! if (thunk_binfo && (kind == bk_via_virtual
! || !BINFO_OFFSET_ZEROP (thunk_binfo)))
{
tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo));
! if (kind == bk_via_virtual)
{
! /* We convert via virtual base. Find the virtual
! base and adjust the fixed offset to be from there. */
! while (!TREE_VIA_VIRTUAL (thunk_binfo))
! thunk_binfo = BINFO_INHERITANCE_CHAIN (thunk_binfo);
!
! virtual_offset = thunk_binfo;
offset = size_diffop
(offset, convert
(ssizetype, BINFO_OFFSET (virtual_offset)));
--- 2136,2186 ----
virtual_offset =
TREE_VALUE (purpose_member
(BINFO_TYPE (virtual_offset),
! CLASSTYPE_VBASECLASSES (over_return)));
! else if (!same_type_ignoring_top_level_qualifiers_p
! (over_return, base_return))
! {
! /* There was no existing virtual thunk (which takes
! precedence). So find the binfo of the base function's
! return type within the overriding function's return type.
! We cannot call lookup base here, because we're inside a
! dfs_walk, and will therefore clobber the BINFO_MARKED
! flags. Fortunately we know the covariancy is valid (it
! has already been checked), so we can just iterate along
! the binfos, which have been chained in inheritance graph
! order. Of course it is lame that we have to repeat the
! search here anyway -- we should really be caching pieces
! of the vtable and avoiding this repeated work. */
! tree thunk_binfo, base_binfo;
!
! /* Find the base binfo within the overriding function's
! return type. We will always find a thunk_binfo, except
! when the covariancy is invalid (which we will have
! already diagnosed). */
! for (base_binfo = TYPE_BINFO (base_return),
! thunk_binfo = TYPE_BINFO (over_return);
! thunk_binfo;
! thunk_binfo = TREE_CHAIN (thunk_binfo))
! if (same_type_p (BINFO_TYPE (thunk_binfo),
! BINFO_TYPE (base_binfo)))
! break;
! /* See if virtual inheritance is involved. */
! for (virtual_offset = thunk_binfo;
! virtual_offset;
! virtual_offset = BINFO_INHERITANCE_CHAIN (virtual_offset))
! if (TREE_VIA_VIRTUAL (virtual_offset))
! break;
!
! if (virtual_offset
! || (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo)))
{
tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo));
! if (virtual_offset)
{
! /* We convert via virtual base. Adjust the fixed
! offset to be from there. */
offset = size_diffop
(offset, convert
(ssizetype, BINFO_OFFSET (virtual_offset)));
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.946.4.19
diff -c -3 -p -r1.946.4.19 cp-tree.h
*** cp/cp-tree.h 25 Apr 2005 19:58:28 -0000 1.946.4.19
--- cp/cp-tree.h 8 May 2005 19:45:59 -0000
*************** struct lang_decl GTY(())
*** 2917,2923 ****
#define THUNK_ALIAS(DECL) \
(DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.u.thunk_alias)
! /* For thunk NODE, this is the FUNCTION_DECL thunked to. */
#define THUNK_TARGET(NODE) \
(DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
--- 2917,2924 ----
#define THUNK_ALIAS(DECL) \
(DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.u.thunk_alias)
! /* For thunk NODE, this is the FUNCTION_DECL thunked to. It is
! possible for the target to be a thunk too. */
#define THUNK_TARGET(NODE) \
(DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.275.4.5
diff -c -3 -p -r1.275.4.5 method.c
*** cp/method.c 17 Dec 2004 16:19:19 -0000 1.275.4.5
--- cp/method.c 8 May 2005 19:46:23 -0000
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 357,362 ****
--- 357,366 ----
There's no need to process this thunk again. */
return;
+ if (DECL_THUNK_P (function))
+ /* The target is itself a thunk, process it now. */
+ use_thunk (function, emit_p);
+
/* Thunks are always addressable; they only appear in vtables. */
TREE_ADDRESSABLE (thunk_fndecl) = 1;
Index: testsuite/g++.dg/inherit/covariant12.C
===================================================================
RCS file: testsuite/g++.dg/inherit/covariant12.C
diff -N testsuite/g++.dg/inherit/covariant12.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/covariant12.C 8 May 2005 19:47:39 -0000
***************
*** 0 ****
--- 1,18 ----
+ // Copyright (C) 2004 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 27 Feb 2005<nathan@codesourcery.com>
+
+ // PR 20232: ICE on invalid
+
+ struct T { };
+
+ struct S;
+
+ struct B
+ {
+ virtual T *Foo (); // { dg-error "overriding" "" }
+ };
+
+ struct D : B
+ {
+ virtual S *Foo (); // { dg-error "invalid covariant" "" }
+ };
Index: testsuite/g++.dg/inherit/covariant13.C
===================================================================
RCS file: testsuite/g++.dg/inherit/covariant13.C
diff -N testsuite/g++.dg/inherit/covariant13.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/covariant13.C 8 May 2005 19:47:39 -0000
***************
*** 0 ****
--- 1,25 ----
+ // Copyright (C) 2004 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 8 May 2005<nathan@codesourcery.com>
+
+ // Origin:Andrew Pinski: pinskia@gcc.gnu.org
+ // PR 21427: ICE on valid
+
+ struct B1 {
+ public:
+ virtual void foo();
+ };
+
+ struct B2 {
+ public:
+ virtual B2 & bar() = 0;
+ };
+
+ struct I : public B1, B2 {
+ public:
+ virtual ~I();
+ virtual I & bar();
+ };
+
+ struct D : public I {
+ virtual ~D();
+ };