aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/class.c16
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/method.c4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/inherit/covariant12.C18
6 files changed, 49 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 36e29ce..51cc4f1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2005-03-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20232
+ * class.c (update_vtable_entry_for_fn): Don't crash on invalid
+ covariancy.
+
+ * cp-tree.g (THUNK_TARGET): Expand comment.
+ * method.c (use_thunk): Make sure we also use the target, if that
+ is a thunk.
+
2005-02-27 Jakub Jelinek <jakub@redhat.com>
PR c++/20206
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index f6ba914..ba89ea1 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2048,14 +2048,17 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
tree thunk_binfo, base_binfo;
/* Find the base binfo within the overriding function's
- return type. */
+ 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);
- !SAME_BINFO_TYPE_P (BINFO_TYPE (thunk_binfo),
- BINFO_TYPE (base_binfo));
+ thunk_binfo;
thunk_binfo = TREE_CHAIN (thunk_binfo))
- continue;
-
+ if (SAME_BINFO_TYPE_P (BINFO_TYPE (thunk_binfo),
+ BINFO_TYPE (base_binfo)))
+ break;
+
/* See if virtual inheritance is involved. */
for (virtual_offset = thunk_binfo;
virtual_offset;
@@ -2063,7 +2066,8 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
if (BINFO_VIRTUAL_P (virtual_offset))
break;
- if (virtual_offset || !BINFO_OFFSET_ZEROP (thunk_binfo))
+ if (virtual_offset
+ || (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo)))
{
tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo));
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index caac8b2..d714424 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2913,7 +2913,8 @@ struct lang_decl GTY(())
#define THUNK_ALIAS(DECL) \
(DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.u.template_info)
-/* For thunk NODE, this is the FUNCTION_DECL thunked to. */
+/* 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)
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 85e2b3f..7a99c26 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -328,6 +328,10 @@ use_thunk (tree thunk_fndecl, bool emit_p)
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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 26fa08c..5e3ceaa 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-03-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20232
+ * g++.dg/inherit/covariant12.C: New.
+
2005-02-28 Tobias Schl"uter <tobias.schlueter@physik.uni-muenchen.de>
PR fortran/19479
diff --git a/gcc/testsuite/g++.dg/inherit/covariant12.C b/gcc/testsuite/g++.dg/inherit/covariant12.C
new file mode 100644
index 0000000..434082a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/inherit/covariant12.C
@@ -0,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" "" }
+};