PATCH: better diagnostic on ambiguous member access

Nathan Sidwell nathan@acm.org
Mon Feb 8 06:17:00 GMT 1999


Hi,
here's a patch which improves the diagnostics when you attempt to access an
ambiguous member (due to multiple inheritance). The current behaviour simply
states that there is an ambiguity. The new behaviour lists the declarations of
the ambiguous members.

I have changed the format specifier in print_z_candidates, to bring it into
line with that in print_candidates.

In hack_identifier, the list of ambiguous member decls are listed. When a bas
class declares member functions by that name, only one of them is listed as
ambiguous -- that should be sufficient to track things down.

In lookup_field I cons up a list of ambiguities, once I discover there are
some. this list is then shown when diagnosing the problem. Again, only one
function out of an overload list is shown per base class.

I also patch two test cases, as they would otherwise now fail with excess
errors. I also attach a test case which checks the new behaviour.

Enjoy.

nathan
-- 
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
      You can up the bandwidth, but you can't up the speed of light      
nathan@acm.org  http://www.cs.bris.ac.uk/~nathan/  nathan@cs.bris.ac.uk
egcs/gcc/cp/ChangeLog:
Mon Feb  8 11:17:41 GMT 1999  Nathan Sidwell  <nathan@acm.org>

	* call.c (print_z_candidates): Use alternate print format, to be
	consistant with (pt.c) print_candidates.
	method.c (hack_identifier): List candidate members.
	search.c (lookup_field): Build ambiguous list, and show it, if
	ambiguous.

Index: egcs/gcc/cp/call.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/call.c,v
retrieving revision 1.130
diff -c -3 -p -r1.130 call.c
*** call.c	1999/01/25 20:43:13	1.130
--- call.c	1999/02/08 13:57:16
*************** print_z_candidates (candidates)
*** 2078,2084 ****
        else if (TYPE_P (candidates->fn))
  	cp_error ("%s %T <conversion>", str, candidates->fn);
        else
! 	cp_error_at ("%s %+D%s", str, candidates->fn,
  		     candidates->viable == -1 ? " <near match>" : "");
        str = "               "; 
      }
--- 2078,2084 ----
        else if (TYPE_P (candidates->fn))
  	cp_error ("%s %T <conversion>", str, candidates->fn);
        else
! 	cp_error_at ("%s %+#D%s", str, candidates->fn,
  		     candidates->viable == -1 ? " <near match>" : "");
        str = "               "; 
      }
Index: egcs/gcc/cp/method.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/method.c,v
retrieving revision 1.87
diff -c -3 -p -r1.87 method.c
*** method.c	1998/12/22 12:18:16	1.87
--- method.c	1999/02/08 13:57:22
*************** hack_identifier (value, name)
*** 2019,2024 ****
--- 2019,2025 ----
      {
        error ("request for member `%s' is ambiguous in multiple inheritance lattice",
  	     IDENTIFIER_POINTER (name));
+       print_candidates (value);
        return error_mark_node;
      }
  
Index: egcs/gcc/cp/search.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/search.c,v
retrieving revision 1.76
diff -c -3 -p -r1.76 search.c
*** search.c	1998/12/16 21:16:08	1.76
--- search.c	1999/02/08 13:57:31
*************** lookup_field (xbasetype, name, protect, 
*** 876,881 ****
--- 876,882 ----
    tree entry, binfo, binfo_h;
    tree own_access = access_default_node;
    int vbase_name_p = VBASE_NAME_P (name);
+   tree ambiguous = NULL_TREE;
  
    /* rval_binfo is the binfo associated with the found member, note,
       this can be set with useful information, even when rval is not
*************** lookup_field (xbasetype, name, protect, 
*** 992,997 ****
--- 993,999 ----
        tree binfos = BINFO_BASETYPES (binfo);
        int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
        tree nval;
+       int idx = -1;
  
        /* Process and/or queue base types.  */
        for (i = 0; i < n_baselinks; i++)
*************** lookup_field (xbasetype, name, protect, 
*** 1046,1052 ****
  
        nval = lookup_field_1 (type, name);
  
!       if (nval || lookup_fnfields_here (type, name)>=0)
  	{
  	  if (nval && nval == rval && SHARED_MEMBER_P (nval))
  	    {
--- 1048,1054 ----
  
        nval = lookup_field_1 (type, name);
  
!       if (nval || (idx = lookup_fnfields_here (type, name)) >= 0)
  	{
  	  if (nval && nval == rval && SHARED_MEMBER_P (nval))
  	    {
*************** lookup_field (xbasetype, name, protect, 
*** 1080,1089 ****
  	    }
  	  else
  	    {
! 	      /* This is ambiguous.  */
! 	      errstr = "request for member `%D' is ambiguous";
! 	      protect += 2;
! 	      break;
  	    }
  	}
      }
--- 1082,1101 ----
  	    }
  	  else
  	    {
! 	      /* This is ambiguous. Remember it. */
! 	      if (! ambiguous)
! 	        {
! 	          errstr = "request for member `%D' is ambiguous";
! 	          protect += 2;
! 	          if (rval)
! 	            ambiguous = scratch_tree_cons (NULL_TREE, rval, ambiguous);
! 	        }
! 	      if (! nval)
! 	        {
! 	          nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
! 	          nval = OVL_CURRENT (nval);
! 	        }
!               ambiguous = scratch_tree_cons (NULL_TREE, nval, ambiguous);
  	    }
  	}
      }
*************** lookup_field (xbasetype, name, protect, 
*** 1182,1187 ****
--- 1194,1201 ----
    if (errstr && protect)
      {
        cp_error (errstr, name, type);
+       if (ambiguous)
+         print_candidates (ambiguous);
        rval = error_mark_node;
      }
  
Index: egcs/gcc/testsuite/g++.old-deja/g++.bugs/900519_13.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.bugs/900519_13.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 900519_13.C
*** 900519_13.C	1998/12/16 21:29:51	1.2
--- 900519_13.C	1999/02/08 13:57:38
***************
*** 11,25 ****
  // keywords: inheritance, ambiguity resolution, members
  
  struct base_0 {
!   enum { base_member };
  };
  
  struct base_1 {
!   int base_member;
  };
  
  struct base_2 {
!   int base_member ();
  };
  
  struct derived_0 : public base_0, public base_1 {
--- 11,25 ----
  // keywords: inheritance, ambiguity resolution, members
  
  struct base_0 {
!   enum { base_member }; // ERROR - candidate (26, 30)
  };
  
  struct base_1 {
!   int base_member;      // ERROR - candidate (26, 34)
  };
  
  struct base_2 {
!   int base_member ();   // ERROR - candidate (30, 34)
  };
  
  struct derived_0 : public base_0, public base_1 {
Index: egcs/gcc/testsuite/g++.old-deja/g++.martin/ambig1.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.martin/ambig1.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 ambig1.C
*** ambig1.C	1998/12/16 21:43:19	1.2
--- ambig1.C	1999/02/08 13:57:50
***************
*** 2,13 ****
  //Based on a report by Bill Currie <bcurrie@tssc.co.nz>
  struct foo {
    protected:
!     int x;
  };
  
  struct bar {
    public:
!     int x();
  };
  
  struct foobar: public foo, public bar {
--- 2,13 ----
  //Based on a report by Bill Currie <bcurrie@tssc.co.nz>
  struct foo {
    protected:
!     int x;        // ERROR - candidate
  };
  
  struct bar {
    public:
!     int x();      // ERROR - candidate
  };
  
  struct foobar: public foo, public bar {


More information about the Gcc-patches mailing list