Patchwork [c++] : Fix PR/47211 - ICE: in cp_build_addr_expr_1, at cp/typeck.c:4866 with -fms-extensions

login
register
mail settings
Submitter Kai Tietz
Date Jan. 8, 2011, 12:44 p.m.
Message ID <AANLkTimy1a0KU8DtZVE4tdMky23F1Zi99MYLizSZyhmm@mail.gmail.com>
Download mbox | patch
Permalink /patch/77950/
State New
Headers show

Comments

Kai Tietz - Jan. 8, 2011, 12:44 p.m.
2011/1/7 Jason Merrill <jason@redhat.com>:
> As we discussed on IRC, we should reject this testcase with the same error
> we gave in 3.4.
>
> Jason
>

According to our discussion I modified patch and do checking in
build_x_unary_op. We use same code as without enable
flag_ms_extension, beside that we allow parentheses around
pointer-to-member for ms_extension.

ChangeLog

2011-01-08  Kai Tietz

          PR c++/47211
          * typeck.c (build_x_unary_op): Handle ms-extension flag.
          (cp_build_addr_expr_1): Move assert after reference check.

2011-01-08  Kai Tietz

          * g++.dg/ext/pr47211.C: New

Tested for x86_64-w64-mingw32 and i686-pc-cygwin. Ok for apply?

Regards,
Kai
Paolo Carlini - Jan. 8, 2011, 1:39 p.m.
... watch trailing blank lines... ;)

Paolo
Jason Merrill - Jan. 9, 2011, 10:42 p.m.
On 01/08/2011 07:44 AM, Kai Tietz wrote:
> -      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;
> +	}

This doesn't look like the right change; we should give the same error 
that we gave in 3.4.  The case we want to reject is trying to take the 
address of a bound pointer to member, i.e. the case where operand 1 of 
the OFFSET_REF is not a member.

Jason

Patch

Index: gcc/gcc/cp/typeck.c
===================================================================
--- gcc.orig/gcc/cp/typeck.c	2011-01-08 13:27:11.000000000 +0100
+++ gcc/gcc/cp/typeck.c	2011-01-08 13:41:40.666964900 +0100
@@ -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));
Index: gcc/gcc/testsuite/g++.dg/ext/pr47211.C
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/g++.dg/ext/pr47211.C	2011-01-08 13:32:52.527757100 +0100
@@ -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); }
+};
+