From b77fe7b45f5a162d5d0f3cc64044281220076c04 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 18 Oct 2005 12:30:32 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 12 ++++++++++++ gcc/cp/class.c | 16 ++++++++++------ gcc/cp/cp-tree.h | 2 +- gcc/cp/semantics.c | 13 +++++++------ gcc/testsuite/ChangeLog | 18 +++++++++++++----- gcc/testsuite/g++.dg/inherit/covariant14.C | 20 ++++++++++++++++++++ gcc/testsuite/g++.dg/overload/error2.C | 11 +++++++++++ 7 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/g++.dg/inherit/covariant14.C create mode 100644 gcc/testsuite/g++.dg/overload/error2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e000b55716c..cd3cded707a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2005-10-18 Nathan Sidwell + + 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 PR c++/21908 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b8254fe4a09..ff5190ab7d6 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 b63d08e5fcc..97cc064110c 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 5ccc7c75709..95387e13bc3 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); + if (add_method (current_class_type, decl, NULL_TREE)) + { + TREE_CHAIN (decl) = TYPE_METHODS (current_class_type); + TYPE_METHODS (current_class_type) = decl; - 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 081542030a4..ce6dd03c082 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2005-10-18 Nathan Sidwell + + PR c++/23118 + * g++.dg/overload/error2.C: New. + + PR c++/22604 + * g++.dg/inherit/covariant14.C: New. + 2005-10-17 Volker Reichelt 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 diff --git a/gcc/testsuite/g++.dg/inherit/covariant14.C b/gcc/testsuite/g++.dg/inherit/covariant14.C new file mode 100644 index 00000000000..13ca877b4ab --- /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 + +// PR 22604 +// Origin: Volker Reichelt + +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 00000000000..3270621334d --- /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 + +// PR 22604 +// Origin: Volker Reichelt + +struct A +{ + void foo(); // { dg-error "with" "" } + virtual void foo(); // { dg-error "cannot be overloaded" "" } +};