diff options
Diffstat (limited to 'contrib/gcc/cp/search.c')
-rw-r--r-- | contrib/gcc/cp/search.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/contrib/gcc/cp/search.c b/contrib/gcc/cp/search.c index 65ed660..0dfdb92 100644 --- a/contrib/gcc/cp/search.c +++ b/contrib/gcc/cp/search.c @@ -78,6 +78,7 @@ struct vbase_info tree inits; }; +static int is_subobject_of_p (tree, tree); static tree dfs_check_overlap (tree, void *); static tree dfs_no_overlap_yet (tree, int, void *); static base_kind lookup_base_r (tree, tree, base_access, bool, tree *); @@ -97,7 +98,6 @@ static struct search_level *pop_search_level (struct stack_level *); static tree bfs_walk (tree, tree (*) (tree, void *), tree (*) (tree, int, void *), void *); static tree lookup_field_queue_p (tree, int, void *); -static int shared_member_p (tree); static tree lookup_field_r (tree, void *); static tree dfs_accessible_queue_p (tree, int, void *); static tree dfs_accessible_p (tree, void *); @@ -891,10 +891,26 @@ friend_accessible_p (tree scope, tree decl, tree binfo) /* Or an instantiation of something which is a friend. */ if (DECL_TEMPLATE_INFO (scope)) - return friend_accessible_p (DECL_TI_TEMPLATE (scope), decl, binfo); + { + int ret; + /* Increment processing_template_decl to make sure that + dependent_type_p works correctly. */ + ++processing_template_decl; + ret = friend_accessible_p (DECL_TI_TEMPLATE (scope), decl, binfo); + --processing_template_decl; + return ret; + } } else if (CLASSTYPE_TEMPLATE_INFO (scope)) - return friend_accessible_p (CLASSTYPE_TI_TEMPLATE (scope), decl, binfo); + { + int ret; + /* Increment processing_template_decl to make sure that + dependent_type_p works correctly. */ + ++processing_template_decl; + ret = friend_accessible_p (CLASSTYPE_TI_TEMPLATE (scope), decl, binfo); + --processing_template_decl; + return ret; + } return 0; } @@ -1058,7 +1074,6 @@ template_self_reference_p (tree type, tree decl) && DECL_NAME (decl) == constructor_name (type)); } - /* Nonzero for a class member means that it is shared between all objects of that class. @@ -1069,7 +1084,7 @@ template_self_reference_p (tree type, tree decl) This function checks that T contains no nonstatic members. */ -static int +int shared_member_p (tree t) { if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == TYPE_DECL \ @@ -1088,6 +1103,27 @@ shared_member_p (tree t) return 0; } +/* Routine to see if the sub-object denoted by the binfo PARENT can be + found as a base class and sub-object of the object denoted by + BINFO. */ + +static int +is_subobject_of_p (tree parent, tree binfo) +{ + tree probe; + + for (probe = parent; probe; probe = BINFO_INHERITANCE_CHAIN (probe)) + { + if (probe == binfo) + return 1; + if (TREE_VIA_VIRTUAL (probe)) + return (purpose_member (BINFO_TYPE (probe), + CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo))) + != NULL_TREE); + } + return 0; +} + /* DATA is really a struct lookup_field_info. Look for a field with the name indicated there in BINFO. If this function returns a non-NULL value it is the result of the lookup. Called from @@ -1155,12 +1191,14 @@ lookup_field_r (tree binfo, void *data) /* If the lookup already found a match, and the new value doesn't hide the old one, we might have an ambiguity. */ - if (lfi->rval_binfo && !original_binfo (lfi->rval_binfo, binfo)) + if (lfi->rval_binfo + && !is_subobject_of_p (lfi->rval_binfo, binfo)) + { if (nval == lfi->rval && shared_member_p (nval)) /* The two things are really the same. */ ; - else if (original_binfo (binfo, lfi->rval_binfo)) + else if (is_subobject_of_p (binfo, lfi->rval_binfo)) /* The previous value hides the new one. */ ; else |