aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@gcc.gnu.org>2005-10-18 12:30:32 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2005-10-18 12:30:32 +0000
commitb77fe7b45f5a162d5d0f3cc64044281220076c04 (patch)
tree8c6ffe176818c794b78be35002d3b48a05a4cf5d /gcc
parent6d7e9a3582b6ce807b1d380c757cf50e5f41ec65 (diff)
downloadgcc-b77fe7b45f5a162d5d0f3cc64044281220076c04.zip
gcc-b77fe7b45f5a162d5d0f3cc64044281220076c04.tar.gz
gcc-b77fe7b45f5a162d5d0f3cc64044281220076c04.tar.bz2
re PR c++/22604 (ICE after invalid covariant return)
cp: PR c++/22604 * class.c (update_vtable_entry_for_fn): Don't process invalid covariant overriders. PR c++/23118 * cp-tree.h (add_method): Add return value. * class.c (add_method): Return success indicator. * semantics.c (finish_member_declaration): Don't add an invalid method to the method list. testsuite: PR c++/23118 * g++.dg/overload/error2.C: New. PR c++/22604 * g++.dg/inherit/covariant14.C: New. From-SVN: r105549
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/class.c16
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/semantics.c13
-rw-r--r--gcc/testsuite/ChangeLog18
-rw-r--r--gcc/testsuite/g++.dg/inherit/covariant14.C20
-rw-r--r--gcc/testsuite/g++.dg/overload/error2.C11
7 files changed, 74 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e000b55..cd3cded 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2005-10-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/22604
+ * class.c (update_vtable_entry_for_fn): Don't process invalid
+ covariant overriders.
+
+ PR c++/23118
+ * cp-tree.h (add_method): Add return value.
+ * class.c (add_method): Return success indicator.
+ * semantics.c (finish_member_declaration): Don't add an invalid
+ method to the method list.
+
2005-10-17 Mark Mitchell <mark@codesourcery.com>
PR c++/21908
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index b8254fe..ff5190a 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -879,9 +879,10 @@ modify_vtable_entry (tree t,
/* Add method METHOD to class TYPE. If USING_DECL is non-null, it is
- the USING_DECL naming METHOD. */
+ the USING_DECL naming METHOD. Returns true if the method could be
+ added to the method vec. */
-void
+bool
add_method (tree type, tree method, tree using_decl)
{
unsigned slot;
@@ -894,7 +895,7 @@ add_method (tree type, tree method, tree using_decl)
tree current_fns;
if (method == error_mark_node)
- return;
+ return false;
complete_p = COMPLETE_TYPE_P (type);
conv_p = DECL_CONV_FN_P (method);
@@ -1027,7 +1028,7 @@ add_method (tree type, tree method, tree using_decl)
{
if (DECL_CONTEXT (fn) == type)
/* Defer to the local function. */
- return;
+ return false;
if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
error ("repeated using declaration %q+D", using_decl);
else
@@ -1044,7 +1045,7 @@ add_method (tree type, tree method, tree using_decl)
declarations because that will confuse things if the
methods have inline definitions. In particular, we
will crash while processing the definitions. */
- return;
+ return false;
}
}
}
@@ -1069,6 +1070,7 @@ add_method (tree type, tree method, tree using_decl)
else
/* Replace the current slot. */
VEC_replace (tree, method_vec, slot, overload);
+ return true;
}
/* Subroutines of finish_struct. */
@@ -1980,7 +1982,9 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
if (POINTER_TYPE_P (over_return)
&& TREE_CODE (over_return) == TREE_CODE (base_return)
&& CLASS_TYPE_P (TREE_TYPE (over_return))
- && CLASS_TYPE_P (TREE_TYPE (base_return)))
+ && CLASS_TYPE_P (TREE_TYPE (base_return))
+ /* If the overrider is invalid, don't even try. */
+ && !DECL_INVALID_OVERRIDER_P (overrider_target))
{
/* If FN is a covariant thunk, we must figure out the adjustment
to the final base FN was converting to. As OVERRIDER_TARGET might
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b63d08e..97cc064 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3709,7 +3709,7 @@ extern tree build_vfn_ref (tree, tree);
extern tree get_vtable_decl (tree, int);
extern void resort_type_method_vec (void *, void *,
gt_pointer_operator, void *);
-extern void add_method (tree, tree, tree);
+extern bool add_method (tree, tree, tree);
extern int currently_open_class (tree);
extern tree currently_open_derived_class (tree);
extern tree finish_struct (tree, tree);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 5ccc7c7..95387e1 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2232,13 +2232,14 @@ finish_member_declaration (tree decl)
{
/* We also need to add this function to the
CLASSTYPE_METHOD_VEC. */
- add_method (current_class_type, decl, NULL_TREE);
-
- TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
- TYPE_METHODS (current_class_type) = decl;
+ if (add_method (current_class_type, decl, NULL_TREE))
+ {
+ TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
+ TYPE_METHODS (current_class_type) = decl;
- maybe_add_class_template_decl_list (current_class_type, decl,
- /*friend_p=*/0);
+ maybe_add_class_template_decl_list (current_class_type, decl,
+ /*friend_p=*/0);
+ }
}
/* Enter the DECL into the scope of the class. */
else if ((TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0815420..ce6dd03 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2005-10-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/23118
+ * g++.dg/overload/error2.C: New.
+
+ PR c++/22604
+ * g++.dg/inherit/covariant14.C: New.
+
2005-10-17 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/23440
@@ -9,19 +17,19 @@
* gfortran.dg/host_dummy_index_1.f90: New test.
PR fortran/21459
- gfortran.dg/automatic_char_len_2.f90: New test.
+ * gfortran.dg/automatic_char_len_2.f90: New test.
PR fortran/20866
- gfortran.dg/recursive_statement_functions.f90: New test.
+ * gfortran.dg/recursive_statement_functions.f90: New test.
PR fortran/20853
- gfortran.dg/assumed_size_dt_dummy.f90: New test.
+ * gfortran.dg/assumed_size_dt_dummy.f90: New test.
PR fortran/20849
- gfortran.dg/external_initializer.f90: New test.
+ * gfortran.dg/external_initializer.f90: New test.
PR fortran/20837
- non_module_public.f90: New test.
+ * non_module_public.f90: New test.
2005-10-17 Nathan Sidwell <nathan@codesourcery.com>
diff --git a/gcc/testsuite/g++.dg/inherit/covariant14.C b/gcc/testsuite/g++.dg/inherit/covariant14.C
new file mode 100644
index 0000000..13ca877
--- /dev/null
+++ b/gcc/testsuite/g++.dg/inherit/covariant14.C
@@ -0,0 +1,20 @@
+// Copyright (C) 2005 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 18 Oct 2005 <nathan@codesourcery.com>
+
+// PR 22604
+// Origin: Volker Reichelt <reichelt@gcc.gnu.org>
+
+struct A;
+
+struct B
+{
+ virtual A* foo(); // { dg-error "overriding" "" }
+};
+
+namespace N
+{
+ struct A : B
+ {
+ virtual A* foo(); // { dg-error "invalid covariant" "" }
+ };
+}
diff --git a/gcc/testsuite/g++.dg/overload/error2.C b/gcc/testsuite/g++.dg/overload/error2.C
new file mode 100644
index 0000000..3270621
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/error2.C
@@ -0,0 +1,11 @@
+// Copyright (C) 2005 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 18 Oct 2005 <nathan@codesourcery.com>
+
+// PR 22604
+// Origin: Volker Reichelt <reichelt@gcc.gnu.org>
+
+struct A
+{
+ void foo(); // { dg-error "with" "" }
+ virtual void foo(); // { dg-error "cannot be overloaded" "" }
+};