Patchwork C++ PATCH for c++/56701 (treating 'this' as an rvalue)

login
register
mail settings
Submitter Jason Merrill
Date March 28, 2013, 6:14 p.m.
Message ID <51548876.4040006@redhat.com>
Download mbox | patch
Permalink /patch/232159/
State New
Headers show

Comments

Jason Merrill - March 28, 2013, 6:14 p.m.
When 'this' appears in an expression, it should be an rvalue rather than 
a const lvalue; in C++11, the distinction matters.

The cp_build_indirect_ref change is to avoid building extra copies of 
*this due to this change.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit a668cad5042d5e499b4d3c78e40505d22f061e3a
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Mar 27 16:04:00 2013 -0400

    	PR c++/56701
    	* semantics.c (finish_this_expr): 'this' is an rvalue.
    	* typeck.c (cp_build_indirect_ref): Handle NOP_EXPR of 'this'.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index ad1c209..2fe2908 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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;
 }
 
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index a0caa30..fedcc6d 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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
index 0000000..8064a51
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv-this.C
@@ -0,0 +1,7 @@ 
+// PR c++/56701
+// { dg-require-effective-target c++11 }
+
+struct A
+{
+  void f(){ A*&& a = this; }
+};