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++: Restoring -Wno-pmf-conversions


This patch fixes the test cases I broke a couple of days before
(p10769a.C and p11012.C).

Interesting enough, the feature being tested was broken awhile ago,
when convert_for_assignment was restructured: Even though the code
compiled with no error, there was no code generated for the
assignment. This is fixed with this patch as well.

The extension now has a slightly different semantics: It is possible
to convert a PMF constant to a function pointer no matter whether the
member function is virtual or not - you always get the address of the
function code. Previously, the compiler would reject conversion if the
class was polymorphic.

Ok to install?

Martin

Tue Sep 21 11:15:03 1999  Martin v. Löwis  <loewis@informatik.hu-berlin.de>

	* extend.texi (Bound member functions): Document unbound pmf
	conversion.

1999-09-21  Martin v. Löwis  <loewis@informatik.hu-berlin.de>

	* typeck.c (get_member_function_from_ptrfunc): Allow extraction of
	function pointer from pmfs with no object given.
	(convert_for_assignment): Do not return error when converting
	pmfs.

// Test conversion of pointers to virtual member functions to
// pointers to non-member functions.

struct A{
  int i;
  A::A():i(1){}
  virtual void foo();
}a;

void A::foo()
{
  i = 0;
}

int main()
{
  void (*f)(A*) = (void(*)(A*))(&A::foo);
  f(&a);
  return a.i;
}


Index: extend.texi
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/extend.texi,v
retrieving revision 1.34
diff -c -p -r1.34 extend.texi
*** extend.texi	1999/09/14 10:06:06	1.34
--- extend.texi	1999/09/21 12:35:57
*************** typedef int (*fptr)(A *);
*** 3749,3753 ****
--- 3749,3761 ----
  fptr p = (fptr)(a.*fp);
  @end example
  
+ For PMF constants (i.e. expressions of the form @samp{&Klasse::Member}),
+ no object is needed to obtain the address of the function. They can be
+ converted to function pointers directly:
+ 
+ @example
+ fptr p1 = (fptr)(&A::foo);
+ @end example
+ 
  You must specify @samp{-Wno-pmf-conversions} to use this extension.
  
Index: cp/typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.214
diff -c -p -r1.214 typeck.c
*** typeck.c	1999/09/20 20:19:03	1.214
--- typeck.c	1999/09/21 12:36:27
*************** get_member_function_from_ptrfunc (instan
*** 2808,2813 ****
--- 2808,2824 ----
  
        tree instance_ptr = *instance_ptrptr;
  
+       if (instance_ptr == error_mark_node
+ 	  && TREE_CODE (function) == PTRMEM_CST)
+ 	{
+ 	  /* Extracting the function address from a pmf is only
+ 	     allowed with -Wno-pmf-conversions. It only works for
+ 	     pmf constants. */
+ 	  e1 = build_addr_func (PTRMEM_CST_MEMBER (function));
+ 	  e1 = convert (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function)), e1);
+ 	  return e1;
+ 	}
+ 
        if (TREE_SIDE_EFFECTS (instance_ptr))
  	instance_ptr = save_expr (instance_ptr);
  
*************** convert_for_assignment (type, rhs, errty
*** 6425,6449 ****
       cv-unqualified type of the left operand.  */
    if (!can_convert_arg (type, rhstype, rhs))
      {
!       /* When -Wno-pmf-converions is use, we just silently allow
  	 conversions from pointers-to-members to plain pointers.  If
  	 the conversion doesn't work, cp_convert will complain.  */
        if (!warn_pmf2ptr 
  	  && TYPE_PTR_P (type) 
  	  && TYPE_PTRMEMFUNC_P (rhstype))
  	rhs = cp_convert (strip_top_quals (type), rhs);
!       /* If the right-hand side has unknown type, then it is an
! 	 overloaded function.  Call instantiate_type to get error
! 	 messages.  */
!       else if (rhstype == unknown_type_node)
! 	instantiate_type (type, rhs, 1);
!       else if (fndecl)
! 	cp_error ("cannot convert `%T' to `%T' for argument `%P' to `%D'",
! 		  rhstype, type, parmnum, fndecl);
!       else
! 	cp_error ("cannot convert `%T' to `%T' in %s", rhstype, type, 
! 		  errtype);
!       return error_mark_node;
      }
    return perform_implicit_conversion (strip_top_quals (type), rhs);
  }
--- 6436,6463 ----
       cv-unqualified type of the left operand.  */
    if (!can_convert_arg (type, rhstype, rhs))
      {
!       /* When -Wno-pmf-conversions is use, we just silently allow
  	 conversions from pointers-to-members to plain pointers.  If
  	 the conversion doesn't work, cp_convert will complain.  */
        if (!warn_pmf2ptr 
  	  && TYPE_PTR_P (type) 
  	  && TYPE_PTRMEMFUNC_P (rhstype))
  	rhs = cp_convert (strip_top_quals (type), rhs);
!       else 
! 	{
! 	  /* If the right-hand side has unknown type, then it is an
! 	     overloaded function.  Call instantiate_type to get error
! 	     messages.  */
! 	  if (rhstype == unknown_type_node)
! 	    instantiate_type (type, rhs, 1);
! 	  else if (fndecl)
! 	    cp_error ("cannot convert `%T' to `%T' for argument `%P' to `%D'",
! 		      rhstype, type, parmnum, fndecl);
! 	  else
! 	    cp_error ("cannot convert `%T' to `%T' in %s", rhstype, type, 
! 		      errtype);
! 	  return error_mark_node;
! 	}
      }
    return perform_implicit_conversion (strip_top_quals (type), rhs);
  }


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