2004-08-24 Nathan Sidwell PR c++/16889 * (is_subobject_of_p): Resurrect & optimize. (lookup_field_r): Use it. Index: cp/search.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v retrieving revision 1.308 diff -c -3 -p -r1.308 search.c *** cp/search.c 15 Aug 2004 15:45:25 -0000 1.308 --- cp/search.c 24 Aug 2004 14:38:01 -0000 *************** struct vbase_info *** 45,50 **** --- 45,51 ---- 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 *); *************** template_self_reference_p (tree type, tr *** 1002,1008 **** && DECL_NAME (decl) == constructor_name (type)); } - /* Nonzero for a class member means that it is shared between all objects of that class. --- 1003,1008 ---- *************** shared_member_p (tree t) *** 1032,1037 **** --- 1032,1057 ---- 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 (BINFO_VIRTUAL_P (probe)) + return (binfo_for_vbase (BINFO_TYPE (probe), 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 *************** lookup_field_r (tree binfo, void *data) *** 1099,1110 **** /* 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 (nval == lfi->rval && shared_member_p (nval)) /* The two things are really the same. */ ; ! else if (original_binfo (binfo, lfi->rval_binfo)) /* The previous value hides the new one. */ ; else --- 1119,1132 ---- /* 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 ! && !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 (is_subobject_of_p (binfo, lfi->rval_binfo)) /* The previous value hides the new one. */ ; else