This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for &a.f
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ PATCH for &a.f
- From: Jason Merrill <jason at redhat dot com>
- Date: 02 Jan 2001 19:34:15 +0000
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)))