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.
commit a668cad5042d5e499b4d3c78e40505d22f061e3a
Author: Jason Merrill <ja...@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; }
+};