cp-tree.h (IDENTIFIER_VIRTUAL_P): Document.
cp: * cp-tree.h (IDENTIFIER_VIRTUAL_P): Document. (get_matching_virtual): Remove. (look_for_overrides): Declare new function. * decl.c (grokfndecl): Don't set IDENTIFIER_VIRTUAL_P or DECL_VINDEX here. * class.c (check_for_override): Move base class iteration code to look_for_overrides. * search.c (next_baselink): Remove. (get_virtuals_named_this): Remove. (get_virtual_destructor): Remove. (tree_has_any_destructors_p): Remove. (struct gvnt_info): Remove. (check_final_overrider): Remove `virtual' from error messages. (get_matching_virtuals): Remove. Move functionality to ... (look_for_overrides): ... here, and ... (look_for_overrides_r): ... here. Set DECL_VIRTUAL_P, if found to be overriding. testsuite: * g++.old-deja/g++.h/spec6.C: Remove some of the XFAILS. * g++.old-deja/g++.other/virtual10.C: New test. From-SVN: r38040
This commit is contained in:
parent
61402b802a
commit
cbb409451b
8 changed files with 155 additions and 246 deletions
|
@ -1,3 +1,23 @@
|
|||
2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* cp-tree.h (IDENTIFIER_VIRTUAL_P): Document.
|
||||
(get_matching_virtual): Remove.
|
||||
(look_for_overrides): Declare new function.
|
||||
* decl.c (grokfndecl): Don't set IDENTIFIER_VIRTUAL_P or
|
||||
DECL_VINDEX here.
|
||||
* class.c (check_for_override): Move base class iteration code
|
||||
to look_for_overrides.
|
||||
* search.c (next_baselink): Remove.
|
||||
(get_virtuals_named_this): Remove.
|
||||
(get_virtual_destructor): Remove.
|
||||
(tree_has_any_destructors_p): Remove.
|
||||
(struct gvnt_info): Remove.
|
||||
(check_final_overrider): Remove `virtual' from error messages.
|
||||
(get_matching_virtuals): Remove. Move functionality to ...
|
||||
(look_for_overrides): ... here, and ...
|
||||
(look_for_overrides_r): ... here. Set DECL_VIRTUAL_P, if found
|
||||
to be overriding.
|
||||
|
||||
2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* typeck.c (get_delta_difference): If via a virtual base,
|
||||
|
|
|
@ -2910,56 +2910,24 @@ static void
|
|||
check_for_override (decl, ctype)
|
||||
tree decl, ctype;
|
||||
{
|
||||
tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
|
||||
int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
|
||||
int virtualp = DECL_VIRTUAL_P (decl);
|
||||
int found_overriden_fn = 0;
|
||||
if (TREE_CODE (decl) == TEMPLATE_DECL)
|
||||
/* In [temp.mem] we have:
|
||||
|
||||
for (i = 0; i < n_baselinks; i++)
|
||||
A specialization of a member function template does not
|
||||
override a virtual function from a base class. */
|
||||
return;
|
||||
if ((DECL_DESTRUCTOR_P (decl)
|
||||
|| IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)))
|
||||
&& look_for_overrides (ctype, decl)
|
||||
&& !DECL_STATIC_FUNCTION_P (decl))
|
||||
{
|
||||
tree base_binfo = TREE_VEC_ELT (binfos, i);
|
||||
if (TYPE_POLYMORPHIC_P (BINFO_TYPE (base_binfo)))
|
||||
{
|
||||
tree tmp = get_matching_virtual
|
||||
(base_binfo, decl, DECL_DESTRUCTOR_P (decl));
|
||||
|
||||
if (tmp && !found_overriden_fn)
|
||||
{
|
||||
/* If this function overrides some virtual in some base
|
||||
class, then the function itself is also necessarily
|
||||
virtual, even if the user didn't explicitly say so. */
|
||||
DECL_VIRTUAL_P (decl) = 1;
|
||||
|
||||
/* The TMP we really want is the one from the deepest
|
||||
baseclass on this path, taking care not to
|
||||
duplicate if we have already found it (via another
|
||||
path to its virtual baseclass. */
|
||||
if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
|
||||
{
|
||||
cp_error_at ("`static %#D' cannot be declared", decl);
|
||||
cp_error_at (" since `virtual %#D' declared in base class",
|
||||
tmp);
|
||||
break;
|
||||
}
|
||||
virtualp = 1;
|
||||
|
||||
/* Set DECL_VINDEX to a value that is neither an
|
||||
INTEGER_CST nor the error_mark_node so that
|
||||
add_virtual_function will realize this is an
|
||||
overridden function. */
|
||||
DECL_VINDEX (decl)
|
||||
= tree_cons (tmp, NULL_TREE, DECL_VINDEX (decl));
|
||||
|
||||
/* We now know that DECL overrides something,
|
||||
which is all that is important. But, we must
|
||||
continue to iterate through all the base-classes
|
||||
in order to allow get_matching_virtual to check for
|
||||
various illegal overrides. */
|
||||
found_overriden_fn = 1;
|
||||
}
|
||||
}
|
||||
/* Set DECL_VINDEX to a value that is neither an
|
||||
INTEGER_CST nor the error_mark_node so that
|
||||
add_virtual_function will realize this is an
|
||||
overriding function. */
|
||||
DECL_VINDEX (decl) = decl;
|
||||
}
|
||||
if (virtualp)
|
||||
if (DECL_VIRTUAL_P (decl))
|
||||
{
|
||||
if (DECL_VINDEX (decl) == NULL_TREE)
|
||||
DECL_VINDEX (decl) = error_mark_node;
|
||||
|
|
|
@ -514,7 +514,8 @@ struct tree_srcloc
|
|||
#define SET_IDENTIFIER_ERROR_LOCUS(NODE,VALUE) \
|
||||
SET_LANG_ID(NODE, VALUE, error_locus)
|
||||
|
||||
|
||||
/* Nonzero if this identifier is used as a virtual function name somewhere
|
||||
(optimizes searches). */
|
||||
#define IDENTIFIER_VIRTUAL_P(NODE) TREE_LANG_FLAG_1(NODE)
|
||||
|
||||
/* Nonzero if this identifier is the prefix for a mangled C++ operator
|
||||
|
@ -4250,7 +4251,7 @@ extern tree lookup_field PARAMS ((tree, tree, int, int));
|
|||
extern int lookup_fnfields_1 PARAMS ((tree, tree));
|
||||
extern tree lookup_fnfields PARAMS ((tree, tree, int));
|
||||
extern tree lookup_member PARAMS ((tree, tree, int, int));
|
||||
extern tree get_matching_virtual PARAMS ((tree, tree, int));
|
||||
extern int look_for_overrides PARAMS ((tree, tree));
|
||||
extern void get_pure_virtuals PARAMS ((tree));
|
||||
extern tree init_vbase_pointers PARAMS ((tree, tree));
|
||||
extern void get_vbase_types PARAMS ((tree));
|
||||
|
|
|
@ -9038,12 +9038,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
|
|||
return decl;
|
||||
|
||||
if (virtualp)
|
||||
{
|
||||
DECL_VIRTUAL_P (decl) = 1;
|
||||
if (DECL_VINDEX (decl) == NULL_TREE)
|
||||
DECL_VINDEX (decl) = error_mark_node;
|
||||
IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
|
||||
}
|
||||
DECL_VIRTUAL_P (decl) = 1;
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
|
276
gcc/cp/search.c
276
gcc/cp/search.c
|
@ -83,7 +83,6 @@ struct vbase_info
|
|||
tree inits;
|
||||
};
|
||||
|
||||
static tree next_baselink PARAMS ((tree));
|
||||
static tree get_vbase_1 PARAMS ((tree, tree, unsigned int *));
|
||||
static tree lookup_field_1 PARAMS ((tree, tree));
|
||||
static int lookup_fnfields_here PARAMS ((tree, tree));
|
||||
|
@ -110,11 +109,9 @@ static tree dfs_push_type_decls PARAMS ((tree, void *));
|
|||
static tree dfs_push_decls PARAMS ((tree, void *));
|
||||
static tree dfs_unuse_fields PARAMS ((tree, void *));
|
||||
static tree add_conversions PARAMS ((tree, void *));
|
||||
static tree get_virtuals_named_this PARAMS ((tree, tree));
|
||||
static tree get_virtual_destructor PARAMS ((tree, void *));
|
||||
static tree tree_has_any_destructor_p PARAMS ((tree, void *));
|
||||
static int covariant_return_p PARAMS ((tree, tree));
|
||||
static int check_final_overrider PARAMS ((tree, tree));
|
||||
static int look_for_overrides_r PARAMS ((tree, tree));
|
||||
static struct search_level *push_search_level
|
||||
PARAMS ((struct stack_level *, struct obstack *));
|
||||
static struct search_level *pop_search_level
|
||||
|
@ -124,7 +121,6 @@ static tree bfs_walk
|
|||
void *));
|
||||
static tree lookup_field_queue_p PARAMS ((tree, void *));
|
||||
static tree lookup_field_r PARAMS ((tree, void *));
|
||||
static tree get_virtuals_named_this_r PARAMS ((tree, void *));
|
||||
static tree context_for_name_lookup PARAMS ((tree));
|
||||
static tree canonical_binfo PARAMS ((tree));
|
||||
static tree shared_marked_p PARAMS ((tree, void *));
|
||||
|
@ -1867,87 +1863,6 @@ dfs_walk (binfo, fn, qfn, data)
|
|||
return dfs_walk_real (binfo, 0, fn, qfn, data);
|
||||
}
|
||||
|
||||
struct gvnt_info
|
||||
{
|
||||
/* The name of the function we are looking for. */
|
||||
tree name;
|
||||
/* The overloaded functions we have found. */
|
||||
tree fields;
|
||||
};
|
||||
|
||||
/* Called from get_virtuals_named_this via bfs_walk. */
|
||||
|
||||
static tree
|
||||
get_virtuals_named_this_r (binfo, data)
|
||||
tree binfo;
|
||||
void *data;
|
||||
{
|
||||
struct gvnt_info *gvnti = (struct gvnt_info *) data;
|
||||
tree type = BINFO_TYPE (binfo);
|
||||
int idx;
|
||||
|
||||
idx = lookup_fnfields_here (BINFO_TYPE (binfo), gvnti->name);
|
||||
if (idx >= 0)
|
||||
gvnti->fields
|
||||
= tree_cons (binfo,
|
||||
TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx),
|
||||
gvnti->fields);
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Return the virtual functions with the indicated NAME in the type
|
||||
indicated by BINFO. The result is a TREE_LIST whose TREE_PURPOSE
|
||||
indicates the base class from which the TREE_VALUE (an OVERLOAD or
|
||||
just a FUNCTION_DECL) originated. */
|
||||
|
||||
static tree
|
||||
get_virtuals_named_this (binfo, name)
|
||||
tree binfo;
|
||||
tree name;
|
||||
{
|
||||
struct gvnt_info gvnti;
|
||||
tree fields;
|
||||
|
||||
gvnti.name = name;
|
||||
gvnti.fields = NULL_TREE;
|
||||
|
||||
bfs_walk (binfo, get_virtuals_named_this_r, 0, &gvnti);
|
||||
|
||||
/* Get to the function decls, and return the first virtual function
|
||||
with this name, if there is one. */
|
||||
for (fields = gvnti.fields; fields; fields = next_baselink (fields))
|
||||
{
|
||||
tree fndecl;
|
||||
|
||||
for (fndecl = TREE_VALUE (fields); fndecl; fndecl = OVL_NEXT (fndecl))
|
||||
if (DECL_VINDEX (OVL_CURRENT (fndecl)))
|
||||
return fields;
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
static tree
|
||||
get_virtual_destructor (binfo, data)
|
||||
tree binfo;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
tree type = BINFO_TYPE (binfo);
|
||||
if (TYPE_HAS_DESTRUCTOR (type)
|
||||
&& DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1)))
|
||||
return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static tree
|
||||
tree_has_any_destructor_p (binfo, data)
|
||||
tree binfo;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
tree type = BINFO_TYPE (binfo);
|
||||
return TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) ? binfo : NULL_TREE;
|
||||
}
|
||||
|
||||
/* Returns > 0 if a function with type DRETTYPE overriding a function
|
||||
with type BRETTYPE is covariant, as defined in [class.virtual].
|
||||
|
||||
|
@ -2026,124 +1941,128 @@ check_final_overrider (overrider, basefn)
|
|||
|
||||
if (pedantic && i == -1)
|
||||
{
|
||||
cp_pedwarn_at ("invalid covariant return type for `virtual %#D'", overrider);
|
||||
cp_pedwarn_at (" overriding `virtual %#D' (must be pointer or reference to class)", basefn);
|
||||
cp_pedwarn_at ("invalid covariant return type for `%#D'", overrider);
|
||||
cp_pedwarn_at (" overriding `%#D' (must be pointer or reference to class)", basefn);
|
||||
}
|
||||
}
|
||||
else if (IS_AGGR_TYPE_2 (base_return, over_return)
|
||||
&& same_or_base_type_p (base_return, over_return))
|
||||
{
|
||||
cp_error_at ("invalid covariant return type for `virtual %#D'", overrider);
|
||||
cp_error_at (" overriding `virtual %#D' (must use pointer or reference)", basefn);
|
||||
cp_error_at ("invalid covariant return type for `%#D'", overrider);
|
||||
cp_error_at (" overriding `%#D' (must use pointer or reference)", basefn);
|
||||
return 0;
|
||||
}
|
||||
else if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider)) == NULL_TREE)
|
||||
{
|
||||
cp_error_at ("conflicting return type specified for `virtual %#D'", overrider);
|
||||
cp_error_at (" overriding `virtual %#D'", basefn);
|
||||
cp_error_at ("conflicting return type specified for `%#D'", overrider);
|
||||
cp_error_at (" overriding `%#D'", basefn);
|
||||
SET_IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider),
|
||||
DECL_CONTEXT (overrider));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check throw specifier is subset. */
|
||||
/* XXX At the moment, punt on an overriding artificial function. We
|
||||
don't generate its exception specifier, so can't check it properly. */
|
||||
/* XXX At the moment, punt with artificial functions. We
|
||||
don't generate their exception specifiers, so can't check properly. */
|
||||
if (! DECL_ARTIFICIAL (overrider)
|
||||
&& !comp_except_specs (base_throw, over_throw, 0))
|
||||
{
|
||||
cp_error_at ("looser throw specifier for `virtual %#F'", overrider);
|
||||
cp_error_at (" overriding `virtual %#F'", basefn);
|
||||
cp_error_at ("looser throw specifier for `%#F'", overrider);
|
||||
cp_error_at (" overriding `%#F'", basefn);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Given a class type TYPE, and a function decl FNDECL, look for a
|
||||
virtual function in TYPE's hierarchy which FNDECL could match as a
|
||||
virtual function. It doesn't matter which one we find.
|
||||
/* Given a class TYPE, and a function decl FNDECL, look for
|
||||
virtual functions in TYPE's hierarchy which FNDECL overrides.
|
||||
We do not look in TYPE itself, only its bases.
|
||||
|
||||
Returns non-zero, if we find any. Set FNDECL's DECL_VIRTUAL_P, if we
|
||||
find that it overrides anything.
|
||||
|
||||
We check that every function which is overridden, is correctly
|
||||
overridden. */
|
||||
|
||||
DTORP is nonzero if we are looking for a destructor. Destructors
|
||||
need special treatment because they do not match by name. */
|
||||
|
||||
tree
|
||||
get_matching_virtual (binfo, fndecl, dtorp)
|
||||
tree binfo, fndecl;
|
||||
int dtorp;
|
||||
int
|
||||
look_for_overrides (type, fndecl)
|
||||
tree type, fndecl;
|
||||
{
|
||||
tree tmp = NULL_TREE;
|
||||
tree binfo = TYPE_BINFO (type);
|
||||
tree basebinfos = BINFO_BASETYPES (binfo);
|
||||
int nbasebinfos = basebinfos ? TREE_VEC_LENGTH (basebinfos) : 0;
|
||||
int ix;
|
||||
int found = 0;
|
||||
|
||||
if (TREE_CODE (fndecl) == TEMPLATE_DECL)
|
||||
/* In [temp.mem] we have:
|
||||
|
||||
A specialization of a member function template does not
|
||||
override a virtual function from a base class. */
|
||||
return NULL_TREE;
|
||||
|
||||
/* Breadth first search routines start searching basetypes
|
||||
of TYPE, so we must perform first ply of search here. */
|
||||
if (dtorp)
|
||||
return bfs_walk (binfo, get_virtual_destructor,
|
||||
tree_has_any_destructor_p, 0);
|
||||
else
|
||||
for (ix = 0; ix != nbasebinfos; ix++)
|
||||
{
|
||||
tree drettype, dtypes, btypes, instptr_type;
|
||||
tree baselink, best = NULL_TREE;
|
||||
tree declarator = DECL_NAME (fndecl);
|
||||
if (IDENTIFIER_VIRTUAL_P (declarator) == 0)
|
||||
return NULL_TREE;
|
||||
tree basetype = BINFO_TYPE (TREE_VEC_ELT (basebinfos, ix));
|
||||
|
||||
if (TYPE_POLYMORPHIC_P (basetype))
|
||||
found += look_for_overrides_r (basetype, fndecl);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
baselink = get_virtuals_named_this (binfo, declarator);
|
||||
if (baselink == NULL_TREE)
|
||||
return NULL_TREE;
|
||||
/* Look in TYPE for virtual functions overridden by FNDECL. Check both
|
||||
TYPE itself and its bases. */
|
||||
|
||||
drettype = TREE_TYPE (TREE_TYPE (fndecl));
|
||||
dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||
if (DECL_STATIC_FUNCTION_P (fndecl))
|
||||
instptr_type = NULL_TREE;
|
||||
else
|
||||
instptr_type = TREE_TYPE (TREE_VALUE (dtypes));
|
||||
|
||||
for (; baselink; baselink = next_baselink (baselink))
|
||||
{
|
||||
tree tmps;
|
||||
for (tmps = TREE_VALUE (baselink); tmps; tmps = OVL_NEXT (tmps))
|
||||
static int
|
||||
look_for_overrides_r (type, fndecl)
|
||||
tree type, fndecl;
|
||||
{
|
||||
int ix;
|
||||
|
||||
if (DECL_DESTRUCTOR_P (fndecl))
|
||||
ix = CLASSTYPE_DESTRUCTOR_SLOT;
|
||||
else
|
||||
ix = lookup_fnfields_here (type, DECL_NAME (fndecl));
|
||||
if (ix >= 0)
|
||||
{
|
||||
tree fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), ix);
|
||||
tree dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||
tree thistype = DECL_STATIC_FUNCTION_P (fndecl)
|
||||
? NULL_TREE : TREE_TYPE (TREE_VALUE (dtypes));
|
||||
|
||||
for (; fns; fns = OVL_NEXT (fns))
|
||||
{
|
||||
tree fn = OVL_CURRENT (fns);
|
||||
tree btypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
||||
|
||||
if (!DECL_VIRTUAL_P (fn))
|
||||
;
|
||||
else if (thistype == NULL_TREE)
|
||||
{
|
||||
tmp = OVL_CURRENT (tmps);
|
||||
if (! DECL_VINDEX (tmp))
|
||||
continue;
|
||||
|
||||
btypes = TYPE_ARG_TYPES (TREE_TYPE (tmp));
|
||||
if (instptr_type == NULL_TREE)
|
||||
{
|
||||
if (compparms (TREE_CHAIN (btypes), dtypes))
|
||||
/* Caller knows to give error in this case. */
|
||||
return tmp;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
if (/* The first parameter is the `this' parameter,
|
||||
which has POINTER_TYPE, and we can therefore
|
||||
safely use TYPE_QUALS, rather than
|
||||
if (compparms (TREE_CHAIN (btypes), dtypes))
|
||||
{
|
||||
/* A static member function cannot match an inherited
|
||||
virtual member function. */
|
||||
cp_error_at ("`%#D' cannot be declared", fndecl);
|
||||
cp_error_at (" since `%#D' declared in base class", fn);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (/* The first parameter is the `this' parameter,
|
||||
which has POINTER_TYPE, and we can therefore
|
||||
safely use TYPE_QUALS, rather than
|
||||
CP_TYPE_QUALS. */
|
||||
(TYPE_QUALS (TREE_TYPE (TREE_VALUE (btypes)))
|
||||
== TYPE_QUALS (instptr_type))
|
||||
&& compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes)))
|
||||
{
|
||||
check_final_overrider (fndecl, tmp);
|
||||
|
||||
/* FNDECL overrides this function. We continue to
|
||||
check all the other functions in order to catch
|
||||
errors; it might be that in some other baseclass
|
||||
a virtual function was declared with the same
|
||||
parameter types, but a different return type. */
|
||||
best = tmp;
|
||||
}
|
||||
(TYPE_QUALS (TREE_TYPE (TREE_VALUE (btypes)))
|
||||
== TYPE_QUALS (thistype))
|
||||
&& compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes)))
|
||||
{
|
||||
/* It's definitely virtual, even if not explicitly set. */
|
||||
DECL_VIRTUAL_P (fndecl) = 1;
|
||||
check_final_overrider (fndecl, fn);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
/* We failed to find one declared in this class. Look in its bases. */
|
||||
return look_for_overrides (type, fndecl);
|
||||
}
|
||||
|
||||
/* A queue function for dfs_walk that skips any nonprimary virtual
|
||||
|
@ -2320,23 +2239,6 @@ get_pure_virtuals (type)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static tree
|
||||
next_baselink (baselink)
|
||||
tree baselink;
|
||||
{
|
||||
tree tmp = TREE_TYPE (baselink);
|
||||
baselink = TREE_CHAIN (baselink);
|
||||
while (tmp)
|
||||
{
|
||||
/* @@ does not yet add previous base types. */
|
||||
baselink = tree_cons (TREE_PURPOSE (tmp), TREE_VALUE (tmp),
|
||||
baselink);
|
||||
TREE_TYPE (baselink) = TREE_TYPE (tmp);
|
||||
tmp = TREE_CHAIN (tmp);
|
||||
}
|
||||
return baselink;
|
||||
}
|
||||
|
||||
/* DEPTH-FIRST SEARCH ROUTINES. */
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* g++.old-deja/g++.h/spec6.C: Remove some of the XFAILS.
|
||||
* g++.old-deja/g++.other/virtual10.C: New test.
|
||||
|
||||
2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* g++.old-deja/g++.mike/pmf5.C: Remove test.
|
||||
|
|
|
@ -92,7 +92,7 @@ struct A
|
|||
virtual void wobble(int) throw(E *); // ERROR - overriding
|
||||
virtual void wabble(int) throw(E *);
|
||||
virtual void wubble(int) throw(E *, H *);
|
||||
virtual ~A() throw(); // ERROR - overriding XFAIL
|
||||
virtual ~A() throw(); // ERROR - overriding
|
||||
};
|
||||
|
||||
struct B : A
|
||||
|
@ -133,9 +133,7 @@ struct C : A, A1
|
|||
|
||||
struct D : A, A1
|
||||
{
|
||||
// The xfail here is because we don't have the check in the right place to
|
||||
// catch dtor failings.
|
||||
virtual ~D() throw(int); // ERROR - looser throw - A::~A() - XFAIL
|
||||
virtual ~D() throw(int); // ERROR - looser throw - A::~A()
|
||||
};
|
||||
|
||||
// [except.spec] 5, types shall not be defined in exception specifiers
|
||||
|
|
20
gcc/testsuite/g++.old-deja/g++.other/virtual10.C
Normal file
20
gcc/testsuite/g++.old-deja/g++.other/virtual10.C
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Build don't link:
|
||||
|
||||
// Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
// Contributed by Nathan Sidwell 14 Nov 2000 <nathan@codesourcery.com>
|
||||
|
||||
// We failed to spot a static member which overrode a virtual
|
||||
|
||||
struct A
|
||||
{
|
||||
virtual int foo (char);
|
||||
static int foo ();
|
||||
virtual int foo (int); // ERROR - this function
|
||||
static int foo (float);
|
||||
virtual int foo (double);
|
||||
};
|
||||
|
||||
struct B : A
|
||||
{
|
||||
static int foo (int); // ERROR - cannot override
|
||||
};
|
Loading…
Add table
Reference in a new issue