summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/search.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/search.c')
-rw-r--r--contrib/gcc/cp/search.c52
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
OpenPOWER on IntegriCloud