This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[C++ PATCH] Fix bug 69 - non-ambiguous lookup


hi,
I've installed the attached patch and testcase for bug 69.
The implementation of the hiding algorithm was broken for
non-virtual bases of a virtual base.

Approved by Mark, built & tested on i686-pc-linux-gnu

nathan
-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2000-06-24  Nathan Sidwell  <nathan@codesourcery.com>

	* search.c (hides): Remove.
	(is_subobject_of_p): Add most_derived parameter. Use
	CANONICAL_BINFO.
	(lookup_field_queue_p): Adjust.
	(lookup_field_r): Adjust.

Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/search.c,v
retrieving revision 1.183
diff -c -3 -p -r1.183 search.c
*** search.c	2000/06/23 01:14:40	1.183
--- search.c	2000/06/24 08:44:36
*************** static tree next_baselink PARAMS ((tree)
*** 89,96 ****
  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));
! static int is_subobject_of_p PARAMS ((tree, tree));
! static int hides PARAMS ((tree, tree));
  static tree virtual_context PARAMS ((tree, tree, tree));
  static tree dfs_check_overlap PARAMS ((tree, void *));
  static tree dfs_no_overlap_yet PARAMS ((tree, void *));
--- 89,95 ----
  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));
! static int is_subobject_of_p PARAMS ((tree, tree, tree));
  static tree virtual_context PARAMS ((tree, tree, tree));
  static tree dfs_check_overlap PARAMS ((tree, void *));
  static tree dfs_no_overlap_yet PARAMS ((tree, void *));
*************** accessible_p (type, decl)
*** 1223,1252 ****
  
  /* 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.  This routine relies upon binfos not being shared, except
!    for binfos for virtual bases.  */
  
  static int
! is_subobject_of_p (parent, binfo)
!      tree parent, binfo;
  {
    tree binfos;
    int i, n_baselinks;
  
-   /* We want to canonicalize for comparison purposes.  But, when we
-      iterate through basetypes later, we want the binfos from the
-      original hierarchy.  That's why we have to calculate BINFOS
-      first, and then canonicalize.  */
-   binfos = BINFO_BASETYPES (binfo);
-   parent = canonical_binfo (parent);
-   binfo = canonical_binfo (binfo);
- 
    if (parent == binfo)
      return 1;
  
    n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  
!   /* Process and/or queue base types.  */
    for (i = 0; i < n_baselinks; i++)
      {
        tree base_binfo = TREE_VEC_ELT (binfos, i);
--- 1222,1244 ----
  
  /* 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.  MOST_DERIVED is the most derived type of the hierarchy being
!    searched.  */
  
  static int
! is_subobject_of_p (parent, binfo, most_derived)
!      tree parent, binfo, most_derived;
  {
    tree binfos;
    int i, n_baselinks;
  
    if (parent == binfo)
      return 1;
  
+   binfos = BINFO_BASETYPES (binfo);
    n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  
!   /* Iterate the base types.  */
    for (i = 0; i < n_baselinks; i++)
      {
        tree base_binfo = TREE_VEC_ELT (binfos, i);
*************** is_subobject_of_p (parent, binfo)
*** 1255,1285 ****
  	   class there's no way to descend into it.  */
  	continue;
  
!       if (is_subobject_of_p (parent, base_binfo))
  	return 1;
      }
    return 0;
  }
  
- /* See if a one FIELD_DECL hides another.  This routine is meant to
-    correspond to ANSI working paper Sept 17, 1992 10p4.  The two
-    binfos given are the binfos corresponding to the particular places
-    the FIELD_DECLs are found.  This routine relies upon binfos not
-    being shared, except for virtual bases.  */
- 
- static int
- hides (hider_binfo, hidee_binfo)
-      tree hider_binfo, hidee_binfo;
- {
-   /* hider hides hidee, if hider has hidee as a base class and
-      the instance of hidee is a sub-object of hider.  The first
-      part is always true is the second part is true.
- 
-      When hider and hidee are the same (two ways to get to the exact
-      same member) we consider either one as hiding the other.  */
-   return is_subobject_of_p (hidee_binfo, hider_binfo);
- }
- 
  /* Very similar to lookup_fnfields_1 but it ensures that at least one
     function was declared inside the class given by TYPE.  It really should
     only return functions that match the given TYPE.  */
--- 1247,1260 ----
  	   class there's no way to descend into it.  */
  	continue;
  
!       if (is_subobject_of_p (parent, 
!                              CANONICAL_BINFO (base_binfo, most_derived),
!                              most_derived))
  	return 1;
      }
    return 0;
  }
  
  /* Very similar to lookup_fnfields_1 but it ensures that at least one
     function was declared inside the class given by TYPE.  It really should
     only return functions that match the given TYPE.  */
*************** lookup_field_queue_p (binfo, data)
*** 1344,1350 ****
    /* If this base class is hidden by the best-known value so far, we
       don't need to look.  */
    if (!lfi->from_dep_base_p && lfi->rval_binfo
!       && hides (lfi->rval_binfo, binfo))
      return NULL_TREE;
  
    return CANONICAL_BINFO (binfo, lfi->type);
--- 1319,1325 ----
    /* If this base class is hidden by the best-known value so far, we
       don't need to look.  */
    if (!lfi->from_dep_base_p && lfi->rval_binfo
!       && is_subobject_of_p (binfo, lfi->rval_binfo, lfi->type))
      return NULL_TREE;
  
    return CANONICAL_BINFO (binfo, lfi->type);
*************** lookup_field_r (binfo, data)
*** 1448,1459 ****
  
    /* 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 && !hides (binfo, lfi->rval_binfo))
      {
        if (nval == lfi->rval && SHARED_MEMBER_P (nval))
  	/* The two things are really the same.  */
  	;
!       else if (hides (lfi->rval_binfo, binfo))
  	/* The previous value hides the new one.  */
  	;
        else
--- 1423,1434 ----
  
    /* 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, lfi->type))
      {
        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, lfi->type))
  	/* The previous value hides the new one.  */
  	;
        else
Index: testsuite/ChangeLog
===================================================================
RCS file: /cvs/gcc/egcs/gcc/testsuite/ChangeLog,v
retrieving revision 1.537
diff -c -3 -p -r1.537 ChangeLog
*** ChangeLog	2000/06/26 11:07:19	1.537
--- ChangeLog	2000/06/26 13:14:33
***************
*** 1,5 ****
--- 1,9 ----
  2000-06-26  Nathan Sidwell  <nathan@codesourcery.com>
  
+ 	* g++.old-deja/g++.other/ambig3.C: New test.
+ 
+ 2000-06-26  Nathan Sidwell  <nathan@codesourcery.com>
+ 
  	* g++.old-deja/g++.pt/syntax1.C: New test.
  	* g++.old-deja/g++.pt/syntax2.C: New test.
  	* g++.old-deja/g++.other/syntax3.C: New test.
Index: testsuite/g++.old-deja/g++.other/ambig3.C
===================================================================
RCS file: ambig3.C
diff -N ambig3.C
*** /dev/null	Tue May  5 13:32:27 1998
--- ambig3.C	Mon Jun 26 06:14:33 2000
***************
*** 0 ****
--- 1,34 ----
+ // Build don't link:
+ 
+ // Copyright (C) 2000 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 23 June 2000 <nathan@codesourcery.com>
+ 
+ // Origin GNATS bug report 69 from Glenn Ammons <ammons@cs.wisc.edu>
+ // 
+ // A base which derives a virtual base hides declarations in the virtual base,
+ // even if that virtual base is accessible via another path [10.2]/6. Make
+ // sure that non-virtual bases of the virtual base are also hidden, not matter
+ // what order bases are declared in.
+ 
+ struct A {int a;};
+ struct B : A {};
+ 
+ struct L1 : virtual B { int a; };
+ struct L2 : virtual A { int a; };
+ 
+ struct R1 : virtual B {};
+ struct R2 : virtual A {};
+ 
+ struct C1 : R1, L1 {};
+ struct C2 : R2, L2 {};
+ 
+ struct D1 : L1, R1 {};
+ struct D2 : L2, R2 {};
+ 
+ void fn (C1 *c1, D1 *d1, C2 *c2, D2 *d2)
+ {
+   c1->a = 1;
+   d1->a = 1;
+   c2->a = 1;
+   d2->a = 1;
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]