PATCH for crashes on ambiguity

Mark Mitchell mmitchell@usa.net
Wed Mar 25 13:51:00 GMT 1998


Jason -- 

  Here's a patch for code like this:

    struct A {
      int operator ++();
      void operator ()();
      void operator delete(void*);
    };
    
    struct B {
      int operator ++(int);
      void operator ()();
      void operator delete(void*);
      void f();
    };
    
    struct C : public A, public B {
    };
    
    void f()
    {
      C c;
      C* cp;
      
      delete cp; // ERROR - ambiguous
      c(); // ERROR - ambiguous
      c++; // ERROR - ambiguous
    }

  We used to crash on every line marked with ERROR.

-- 
Mark Mitchell <mmitchell@usa.net>
http://home.earthlink.net/~mbmitchell
Consulting Services Available

Wed Mar 25 12:10:05 1998  Mark Mitchell  <mmitchell@usa.net>

	* call.c (build_object_call): Complain about ambiguous operator(),
	rather that crashing.
	(build_new_op): Likewise.
	(build_op_delete_call): Likewise.
	
Index: gcc/cp/call.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/call.c,v
retrieving revision 1.52
diff -c -p -r1.52 call.c
*** call.c	1998/03/19 21:37:25	1.52
--- call.c	1998/03/25 20:08:08
*************** build_object_call (obj, args)
*** 2289,2295 ****
        return error_mark_node;
      }
  
!   fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 0);
  
    args = resolve_args (args);
  
--- 2289,2297 ----
        return error_mark_node;
      }
  
!   fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 1);
!   if (fns == error_mark_node)
!     return error_mark_node;
  
    args = resolve_args (args);
  
*************** build_new_op (code, flags, arg1, arg2, a
*** 2569,2575 ****
      }
  
    if (IS_AGGR_TYPE (TREE_TYPE (arg1)))
!     fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 0);
    else
      fns = NULL_TREE;
  
--- 2571,2581 ----
      }
  
    if (IS_AGGR_TYPE (TREE_TYPE (arg1)))
!     {
!       fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 1);
!       if (fns == error_mark_node)
! 	return fns;
!     }
    else
      fns = NULL_TREE;
  
*************** build_op_delete_call (code, addr, size, 
*** 2863,2869 ****
    fnname = ansi_opname[code];
  
    if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL))
!     fns = lookup_fnfields (TYPE_BINFO (type), fnname, 0);
    else
      fns = NULL_TREE;
  
--- 2869,2886 ----
    fnname = ansi_opname[code];
  
    if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL))
!     /* In [class.free]
! 
!        If the result of the lookup is ambiguous or inaccessible, or if
!        the lookup selects a placement deallocation function, the
!        program is ill-formed.
!   
!        Therefore, we ask lookup_fnfields to complain ambout ambiguity.  */
!     {
!       fns = lookup_fnfields (TYPE_BINFO (type), fnname, 1);
!       if (fns == error_mark_node)
! 	return error_mark_node;
!     }
    else
      fns = NULL_TREE;
  
Index: gcc/testsuite/g++.old-deja/g++.other/ambig1.C
===================================================================
RCS file: ambig1.C
diff -N ambig1.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- ambig1.C	Wed Mar 25 12:07:56 1998
***************
*** 0 ****
--- 1,28 ----
+ // Build don't link:
+ 
+ struct A {
+   int operator ++();
+   void operator ()();
+   void operator delete(void*);
+ };
+ 
+ struct B {
+   int operator ++(int);
+   void operator ()();
+   void operator delete(void*);
+   void f();
+ };
+ 
+ struct C : public A, public B {
+ };
+ 
+ void f()
+ {
+   C c;
+   C* cp;
+   
+   delete cp; // ERROR - ambiguous
+   c(); // ERROR - ambiguous
+   c++; // ERROR - ambiguous
+ }
+   



More information about the Gcc-bugs mailing list