This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++: Restoring -Wno-pmf-conversions
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++: Restoring -Wno-pmf-conversions
- From: "Martin v. Loewis" <martin at mira dot isdn dot cs dot tu-berlin dot de>
- Date: Tue, 21 Sep 1999 14:54:34 +0200
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);
}