===================================================================
@@ -4558,7 +4558,14 @@ build_x_unary_op (enum tree_code code, t
/* A pointer to member-function can be formed only by saying
&X::mf. */
- if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
+ if (flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
+ && !PTRMEM_OK_P (xarg) && TREE_CODE (xarg) == OFFSET_REF)
+ {
+ if (TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
+ && TYPE_P (TREE_OPERAND (xarg, 0)))
+ PTRMEM_OK_P (xarg) = 1;
+ }
+ if (TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
&& (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg)))
{
if (TREE_CODE (xarg) != OFFSET_REF
@@ -4863,8 +4870,6 @@ cp_build_addr_expr_1 (tree arg, bool str
tree type;
tree t;
- gcc_assert (PTRMEM_OK_P (arg));
-
t = TREE_OPERAND (arg, 1);
if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
{
@@ -4873,6 +4878,8 @@ cp_build_addr_expr_1 (tree arg, bool str
return error_mark_node;
}
+ gcc_assert (PTRMEM_OK_P (arg));
+
type = build_ptrmem_type (context_for_name_lookup (t),
TREE_TYPE (t));
t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1));
===================================================================
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fms-extensions" } */
+
+class chile
+{
+ typedef void (chile::* pmf) ();
+ void bar (pmf pmethod)
+ {
+ &(this->*pmethod); // { dg-error "invalid use of" }
+ }
+ void doo(void) { }
+ pmf foo(pmf pmethod) { return &(chile::doo); }
+};
+