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 for &a.f


We were failing to give any diagnostic for converting &a.f to void (where f
is a unique non-static member function), because it didn't look like a
really_overloaded_fn.  I've restored the diagnostic in build_unary_op that
Nathan removed in August, because it's more friendly than the generic
overload resolution failure error.

g++.other/pmf7.C:
// Test for proper diagnostics on trying to take the address of a non-static
// member function.

struct A {
  void f ();
  void f (int);
  void g ();
};

int main ()
{
  A a;
  &a.f;				// ERROR - overloaded
  &a.g;				// ERROR - can't write a pmf like this
}

2001-01-02  Jason Merrill  <jason@redhat.com>

	* typeck.c (build_unary_op): Restore old &a.f diagnostic code.
	* cvt.c (convert_to_void): Use type_unknown_p.

*** typeck.c.~1~	Tue Jan  2 15:22:32 2001
--- typeck.c	Tue Jan  2 19:25:09 2001
*************** build_unary_op (code, xarg, noconvert)
*** 4682,4696 ****
  	  return build1 (ADDR_EXPR, unknown_type_node, arg);
  	}
  
!       if (TREE_CODE (arg) == COMPONENT_REF && flag_ms_extensions
!           && type_unknown_p (arg)
            && OVL_NEXT (TREE_OPERAND (arg, 1)) == NULL_TREE)
          {
  	  /* They're trying to take the address of a unique non-static
! 	     member function.  This is ill-formed, except in microsoft-land.  */
  
  	  tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
  	  tree name = DECL_NAME (OVL_CURRENT (TREE_OPERAND (arg, 1)));
  	  arg = build_offset_ref (base, name);
          }
          
--- 4696,4726 ----
  	  return build1 (ADDR_EXPR, unknown_type_node, arg);
  	}
  
!       if (TREE_CODE (arg) == COMPONENT_REF && type_unknown_p (arg)
            && OVL_NEXT (TREE_OPERAND (arg, 1)) == NULL_TREE)
          {
  	  /* They're trying to take the address of a unique non-static
! 	     member function.  This is ill-formed (except in MS-land),
! 	     but let's try to DTRT.
! 	     Note: We only handle unique functions here because we don't
! 	     want to complain if there's a static overload; non-unique
! 	     cases will be handled by instantiate_type.  But we need to
! 	     handle this case here to allow casts on the resulting PMF.
! 	     We could defer this in non-MS mode, but it's easier to give
! 	     a useful error here.  */
  
  	  tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
  	  tree name = DECL_NAME (OVL_CURRENT (TREE_OPERAND (arg, 1)));
+ 
+ 	  if (! flag_ms_extensions)
+ 	    {
+ 	      if (current_class_type
+ 		  && TREE_OPERAND (arg, 0) == current_class_ref)
+ 		/* An expression like &memfn.  */
+ 		cp_pedwarn ("ISO C++ forbids taking the address of a non-static member function to form a pointer to member function.  Say `&%T::%D'", base, name);
+ 	      else
+ 		cp_pedwarn ("ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say `&%T::%D'", base, name);
+ 	    }
  	  arg = build_offset_ref (base, name);
          }
          
*** cvt.c.~1~	Thu Dec 14 13:39:09 2000
--- cvt.c	Tue Jan  2 18:23:35 2001
*************** convert_to_void (expr, implicit)
*** 976,994 ****
    
      if (TREE_CODE (probe) == ADDR_EXPR)
        probe = TREE_OPERAND (expr, 0);
!     if (!is_overloaded_fn (probe))
!       ;/* OK */
!     else if (really_overloaded_fn (probe))
!         {
!           /* [over.over] enumerates the places where we can take the address
!              of an overloaded function, and this is not one of them.  */
!           cp_pedwarn ("%s has no context for overloaded function name `%E'",
!                       implicit ? implicit : "void cast", expr);
!         }
!     else if (implicit && probe == expr)
        /* Only warn when there is no &.  */
        cp_warning ("%s is a reference, not call, to function `%E'",
!                     implicit, expr);
    }
    
    if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
--- 976,992 ----
    
      if (TREE_CODE (probe) == ADDR_EXPR)
        probe = TREE_OPERAND (expr, 0);
!     if (type_unknown_p (probe))
!       {
! 	/* [over.over] enumerates the places where we can take the address
! 	   of an overloaded function, and this is not one of them.  */
! 	cp_pedwarn ("%s cannot resolve address of overloaded function",
! 		    implicit ? implicit : "void cast");
!       }
!     else if (implicit && probe == expr && is_overloaded_fn (probe))
        /* Only warn when there is no &.  */
        cp_warning ("%s is a reference, not call, to function `%E'",
! 		  implicit, expr);
    }
    
    if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))

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