re PR c++/56701 ([C++11] The *this* pointer fails to bind to rvalue reference to...
authorJason Merrill <jason@redhat.com>
Thu, 28 Mar 2013 18:20:51 +0000 (14:20 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 28 Mar 2013 18:20:51 +0000 (14:20 -0400)
PR c++/56701
* semantics.c (finish_this_expr): 'this' is an rvalue.
* typeck.c (cp_build_indirect_ref): Handle NOP_EXPR of 'this'.

From-SVN: r197212

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/cpp0x/rv-this.C [new file with mode: 0644]

index 2b02880c63f02d2575a897df3e34e69fcd3159ff..b0a952a741cf787d4298993ca9177c51eb8d50d5 100644 (file)
@@ -1,5 +1,9 @@
 2013-03-28  Jason Merrill  <jason@redhat.com>
 
+       PR c++/56701
+       * semantics.c (finish_this_expr): 'this' is an rvalue.
+       * typeck.c (cp_build_indirect_ref): Handle NOP_EXPR of 'this'.
+
        PR c++/56710
        * semantics.c (finish_member_declaration): Don't push closure
        members.
index ad1c209b2362016619d6f8a778329e2a83e2c5f4..2fe2908bf86118f4192e21746cbd3a2a38a771e4 100644 (file)
@@ -2297,7 +2297,6 @@ finish_this_expr (void)
         result = lambda_expr_this_capture (CLASSTYPE_LAMBDA_EXPR (type));
       else
         result = current_class_ptr;
-
     }
   else if (current_function_decl
           && DECL_STATIC_FUNCTION_P (current_function_decl))
@@ -2314,6 +2313,9 @@ finish_this_expr (void)
       result = error_mark_node;
     }
 
+  /* The keyword 'this' is a prvalue expression.  */
+  result = rvalue (result);
+
   return result;
 }
 
index 4b6468ce6952354ba20395c410d8cbd670e4090e..90c7ce495051ff00f4de9e787c1319cdd1dd8bdd 100644 (file)
@@ -2843,7 +2843,11 @@ cp_build_indirect_ref (tree ptr, ref_operator errorstring,
 {
   tree pointer, type;
 
-  if (ptr == current_class_ptr)
+  if (ptr == current_class_ptr
+      || (TREE_CODE (ptr) == NOP_EXPR
+         && TREE_OPERAND (ptr, 0) == current_class_ptr
+         && (same_type_ignoring_top_level_qualifiers_p
+             (TREE_TYPE (ptr), TREE_TYPE (current_class_ptr)))))
     return current_class_ref;
 
   pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-this.C b/gcc/testsuite/g++.dg/cpp0x/rv-this.C
new file mode 100644 (file)
index 0000000..8064a51
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/56701
+// { dg-require-effective-target c++11 }
+
+struct A
+{
+  void f(){ A*&& a = this; }
+};