Commit b77fe7b4 by Nathan Sidwell

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
parent 6d7e9a35
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> 2005-10-17 Mark Mitchell <mark@codesourcery.com>
PR c++/21908 PR c++/21908
......
...@@ -879,9 +879,10 @@ modify_vtable_entry (tree t, ...@@ -879,9 +879,10 @@ modify_vtable_entry (tree t,
/* Add method METHOD to class TYPE. If USING_DECL is non-null, it is /* 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) add_method (tree type, tree method, tree using_decl)
{ {
unsigned slot; unsigned slot;
...@@ -894,7 +895,7 @@ add_method (tree type, tree method, tree using_decl) ...@@ -894,7 +895,7 @@ add_method (tree type, tree method, tree using_decl)
tree current_fns; tree current_fns;
if (method == error_mark_node) if (method == error_mark_node)
return; return false;
complete_p = COMPLETE_TYPE_P (type); complete_p = COMPLETE_TYPE_P (type);
conv_p = DECL_CONV_FN_P (method); conv_p = DECL_CONV_FN_P (method);
...@@ -1027,7 +1028,7 @@ add_method (tree type, tree method, tree using_decl) ...@@ -1027,7 +1028,7 @@ add_method (tree type, tree method, tree using_decl)
{ {
if (DECL_CONTEXT (fn) == type) if (DECL_CONTEXT (fn) == type)
/* Defer to the local function. */ /* Defer to the local function. */
return; return false;
if (DECL_CONTEXT (fn) == DECL_CONTEXT (method)) if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
error ("repeated using declaration %q+D", using_decl); error ("repeated using declaration %q+D", using_decl);
else else
...@@ -1044,7 +1045,7 @@ add_method (tree type, tree method, tree using_decl) ...@@ -1044,7 +1045,7 @@ add_method (tree type, tree method, tree using_decl)
declarations because that will confuse things if the declarations because that will confuse things if the
methods have inline definitions. In particular, we methods have inline definitions. In particular, we
will crash while processing the definitions. */ will crash while processing the definitions. */
return; return false;
} }
} }
} }
...@@ -1069,6 +1070,7 @@ add_method (tree type, tree method, tree using_decl) ...@@ -1069,6 +1070,7 @@ add_method (tree type, tree method, tree using_decl)
else else
/* Replace the current slot. */ /* Replace the current slot. */
VEC_replace (tree, method_vec, slot, overload); VEC_replace (tree, method_vec, slot, overload);
return true;
} }
/* Subroutines of finish_struct. */ /* Subroutines of finish_struct. */
...@@ -1980,7 +1982,9 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, ...@@ -1980,7 +1982,9 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
if (POINTER_TYPE_P (over_return) if (POINTER_TYPE_P (over_return)
&& TREE_CODE (over_return) == TREE_CODE (base_return) && TREE_CODE (over_return) == TREE_CODE (base_return)
&& CLASS_TYPE_P (TREE_TYPE (over_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 /* If FN is a covariant thunk, we must figure out the adjustment
to the final base FN was converting to. As OVERRIDER_TARGET might to the final base FN was converting to. As OVERRIDER_TARGET might
......
...@@ -3709,7 +3709,7 @@ extern tree build_vfn_ref (tree, tree); ...@@ -3709,7 +3709,7 @@ extern tree build_vfn_ref (tree, tree);
extern tree get_vtable_decl (tree, int); extern tree get_vtable_decl (tree, int);
extern void resort_type_method_vec (void *, void *, extern void resort_type_method_vec (void *, void *,
gt_pointer_operator, 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 int currently_open_class (tree);
extern tree currently_open_derived_class (tree); extern tree currently_open_derived_class (tree);
extern tree finish_struct (tree, tree); extern tree finish_struct (tree, tree);
......
...@@ -2232,13 +2232,14 @@ finish_member_declaration (tree decl) ...@@ -2232,13 +2232,14 @@ finish_member_declaration (tree decl)
{ {
/* We also need to add this function to the /* We also need to add this function to the
CLASSTYPE_METHOD_VEC. */ 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); TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
TYPE_METHODS (current_class_type) = decl; TYPE_METHODS (current_class_type) = decl;
maybe_add_class_template_decl_list (current_class_type, decl, maybe_add_class_template_decl_list (current_class_type, decl,
/*friend_p=*/0); /*friend_p=*/0);
}
} }
/* Enter the DECL into the scope of the class. */ /* Enter the DECL into the scope of the class. */
else if ((TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl)) else if ((TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
......
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> 2005-10-17 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/23440 PR c++/23440
...@@ -9,19 +17,19 @@ ...@@ -9,19 +17,19 @@
* gfortran.dg/host_dummy_index_1.f90: New test. * gfortran.dg/host_dummy_index_1.f90: New test.
PR fortran/21459 PR fortran/21459
gfortran.dg/automatic_char_len_2.f90: New test. * gfortran.dg/automatic_char_len_2.f90: New test.
PR fortran/20866 PR fortran/20866
gfortran.dg/recursive_statement_functions.f90: New test. * gfortran.dg/recursive_statement_functions.f90: New test.
PR fortran/20853 PR fortran/20853
gfortran.dg/assumed_size_dt_dummy.f90: New test. * gfortran.dg/assumed_size_dt_dummy.f90: New test.
PR fortran/20849 PR fortran/20849
gfortran.dg/external_initializer.f90: New test. * gfortran.dg/external_initializer.f90: New test.
PR fortran/20837 PR fortran/20837
non_module_public.f90: New test. * non_module_public.f90: New test.
2005-10-17 Nathan Sidwell <nathan@codesourcery.com> 2005-10-17 Nathan Sidwell <nathan@codesourcery.com>
// 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" "" }
};
}
// 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" "" }
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment