From: Mark Mitchell Date: Tue, 6 Apr 1999 14:38:08 +0000 (+0000) Subject: cp-tree.h (BASELINK_P): New macro. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4bb0968f4e3eb6af9a9a1ba5758ebea168a4b2e2;p=gcc.git cp-tree.h (BASELINK_P): New macro. * cp-tree.h (BASELINK_P): New macro. (SET_BASELINK_P): Likewise. * init.c (build_member_call): Remove needless assignment in if statement. * search.c (lookup_field_r): Fix handling when we are looking specifically for a type; these are not hidden by functions and variables. (lookup_member): Use SET_BASELINK_P. * tree.c (is_overloaded_fn): Use BASELINK_P. (really_overloaed_fn): Likewise. (get_first_fn): Likewise. From-SVN: r26219 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e5d86a99f05..5dd92144328 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +1999-04-06 Mark Mitchell + + * cp-tree.h (BASELINK_P): New macro. + (SET_BASELINK_P): Likewise. + * init.c (build_member_call): Remove needless assignment in if + statement. + * search.c (lookup_field_r): Fix handling when we are looking + specifically for a type; these are not hidden by functions and + variables. + (lookup_member): Use SET_BASELINK_P. + * tree.c (is_overloaded_fn): Use BASELINK_P. + (really_overloaed_fn): Likewise. + (get_first_fn): Likewise. + 1999-04-05 Mark Mitchell * decl.c (lookup_name_current_level): Tweak, and improve diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6d0b2735bd2..0ed7d750232 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -33,7 +33,7 @@ Boston, MA 02111-1307, USA. */ TREE_INDIRECT_USING (in NAMESPACE_DECL). IDENTIFIER_MARKED (used by search routines). LOCAL_BINDING_P (in CPLUS_BINDING) - 1: IDENTIFIER_VIRTUAL_P. + 1: IDENTIFIER_VIRTUAL_P. TI_PENDING_TEMPLATE_FLAG. TEMPLATE_PARMS_FOR_INLINE. DELETE_EXPR_USE_VEC (in DELETE_EXPR). @@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA. */ TYPE_USES_COMPLEX_INHERITANCE (in _TYPE). C_DECLARED_LABEL_FLAG. INHERITED_VALUE_BINDING_P (in CPLUS_BINDING) + BASELINK_P (in TREE_LIST) 2: IDENTIFIER_OPNAME_P. BINFO_VBASE_MARKED. BINFO_FIELDS_MARKED. @@ -191,6 +192,14 @@ struct tree_overload tree function; }; +/* A `baselink' is a TREE_LIST whose TREE_PURPOSE is a BINFO + indicating a particular base class, and whose TREE_VALUE is a + (possibly overloaded) function from that base class. */ +#define BASELINK_P(NODE) \ + (TREE_CODE ((NODE)) == TREE_LIST && TREE_LANG_FLAG_1 ((NODE))) +#define SET_BASELINK_P(NODE) \ + (TREE_LANG_FLAG_1 ((NODE)) = 1) + #define WRAPPER_PTR(NODE) (((struct tree_wrapper*)NODE)->u.ptr) #define WRAPPER_INT(NODE) (((struct tree_wrapper*)NODE)->u.i) diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 06262036715..2769765ef63 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1443,7 +1443,7 @@ build_member_call (type, name, parmlist) if (method_name == constructor_name (type) || method_name == constructor_name_full (type)) return build_functional_cast (type, parmlist); - if ((t = lookup_fnfields (basetype_path, method_name, 0))) + if (lookup_fnfields (basetype_path, method_name, 0)) return build_method_call (decl, TREE_CODE (name) == TEMPLATE_ID_EXPR ? name : method_name, diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 99e25a84a15..7a13a9f1e0d 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1207,17 +1207,20 @@ lookup_field_r (binfo, data) { struct lookup_field_info *lfi = (struct lookup_field_info *) data; tree type = BINFO_TYPE (binfo); - tree nval; - int idx; + tree nval = NULL_TREE; int from_dep_base_p; /* First, look for a function. There can't be a function and a data member with the same name, and if there's a function and a type with the same name, the type is hidden by the function. */ - idx = lookup_fnfields_here (type, lfi->name); - if (idx >= 0) - nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx); - else + if (!lfi->want_type) + { + int idx = lookup_fnfields_here (type, lfi->name); + if (idx >= 0) + nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx); + } + + if (!nval) /* Look for a data member or type. */ nval = lookup_field_1 (type, lfi->name); @@ -1226,6 +1229,17 @@ lookup_field_r (binfo, data) if (!nval) return NULL_TREE; + /* If we're looking up a type (as with an elaborated type specifier) + we ignore all non-types we find. */ + if (lfi->want_type && TREE_CODE (nval) != TYPE_DECL) + { + nval = purpose_member (lfi->name, CLASSTYPE_TAGS (type)); + if (nval) + nval = TYPE_MAIN_DECL (TREE_VALUE (nval)); + else + return NULL_TREE; + } + /* You must name a template base class with a template-id. */ if (!same_type_p (type, lfi->type) && template_self_reference_p (type, nval)) @@ -1285,41 +1299,24 @@ lookup_field_r (binfo, data) } else { - /* The new lookup is the best we've got so far. Verify that - it's the kind of thing we're looking for. */ - if (lfi->want_type && TREE_CODE (nval) != TYPE_DECL) + /* If the thing we're looking for is a virtual base class, then + we know we've got what we want at this point; there's no way + to get an ambiguity. */ + if (VBASE_NAME_P (lfi->name)) { - nval = purpose_member (lfi->name, CLASSTYPE_TAGS (type)); - if (nval) - { - nval = TYPE_MAIN_DECL (TREE_VALUE (nval)); - if (!same_type_p (type, lfi->type) - && template_self_reference_p (type, nval)) - nval = NULL_TREE; - } + lfi->rval = nval; + return nval; } - if (nval) - { - /* If the thing we're looking for is a virtual base class, - then we know we've got what we want at this point; - there's no way to get an ambiguity. */ - if (VBASE_NAME_P (lfi->name)) - { - lfi->rval = nval; - return nval; - } - - if (from_dep_base_p && TREE_CODE (nval) != TYPE_DECL - /* We need to return a member template class so we can - define partial specializations. Is there a better - way? */ - && !DECL_CLASS_TEMPLATE_P (nval)) - /* The thing we're looking for isn't a type, so the implicit - typename extension doesn't apply, so we just pretend we - didn't find anything. */ - return NULL_TREE; - } + if (from_dep_base_p && TREE_CODE (nval) != TYPE_DECL + /* We need to return a member template class so we can + define partial specializations. Is there a better + way? */ + && !DECL_CLASS_TEMPLATE_P (nval)) + /* The thing we're looking for isn't a type, so the implicit + typename extension doesn't apply, so we just pretend we + didn't find anything. */ + return NULL_TREE; lfi->rval = nval; lfi->from_dep_base_p = from_dep_base_p; @@ -1444,8 +1441,11 @@ lookup_member (xbasetype, name, protect, want_type) name, name, TREE_TYPE (rval))); - if (rval && is_overloaded_fn (rval)) - rval = scratch_tree_cons (basetype_path, rval, NULL_TREE); + if (rval && is_overloaded_fn (rval)) + { + rval = scratch_tree_cons (basetype_path, rval, NULL_TREE); + SET_BASELINK_P (rval); + } return rval; } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 96d9cbd72bd..44e958f064d 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1223,21 +1223,9 @@ int is_overloaded_fn (x) tree x; { - /* XXX A baselink is also considered an overloaded function. - As is a placeholder from push_class_decls. - As is an expression like X::f. */ - if (TREE_CODE (x) == TREE_LIST) - { - if (TREE_PURPOSE (x) == error_mark_node) - { - x = TREE_VALUE (x); - my_friendly_assert (TREE_CODE (x) == TREE_LIST, 981121); - } - my_friendly_assert (TREE_CODE (TREE_PURPOSE (x)) == TREE_VEC - || TREE_CODE (TREE_PURPOSE (x)) == IDENTIFIER_NODE, - 388); - x = TREE_VALUE (x); - } + /* A baselink is also considered an overloaded function. */ + if (BASELINK_P (x)) + x = TREE_VALUE (x); return (TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == TEMPLATE_ID_EXPR || DECL_FUNCTION_TEMPLATE_P (x) @@ -1248,9 +1236,8 @@ int really_overloaded_fn (x) tree x; { - /* A baselink is also considered an overloaded function. - This might also be an ambiguous class member. */ - if (TREE_CODE (x) == TREE_LIST) + /* A baselink is also considered an overloaded function. */ + if (BASELINK_P (x)) x = TREE_VALUE (x); return (TREE_CODE (x) == OVERLOAD && (TREE_CHAIN (x) != NULL_TREE @@ -1263,7 +1250,7 @@ get_first_fn (from) { my_friendly_assert (is_overloaded_fn (from), 9); /* A baselink is also considered an overloaded function. */ - if (TREE_CODE (from) == TREE_LIST) + if (BASELINK_P (from)) from = TREE_VALUE (from); return OVL_CURRENT (from); } diff --git a/gcc/testsuite/g++.old-deja/g++.other/crash9.C b/gcc/testsuite/g++.old-deja/g++.other/crash9.C new file mode 100644 index 00000000000..d3c23977abf --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/crash9.C @@ -0,0 +1,9 @@ +// Build don't link: +// Origin: Jason Merrill + +struct A { }; +struct B : public A +{ + int A; +}; +struct C : public B { }; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash33.C b/gcc/testsuite/g++.old-deja/g++.pt/crash33.C new file mode 100644 index 00000000000..bc7dcf5c4c7 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash33.C @@ -0,0 +1,17 @@ +// Build don't link: +// Origin: Theodore Papadopoulo + +class A { +public: + template T& f(T& t) const; +}; + +class B { +public: + template T& f(T& t) const; +}; + +class C: public A,B { +public: + template T& f(T& t) const; +};