aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-05-23 13:21:22 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-05-23 13:21:22 -0400
commit955da5e5443724cb59f8fbd854c13e78c68bf000 (patch)
tree5376594ef4febecacfb8c0a3a1831fbdda417c0c /gcc/cp
parenta6b29221604547ab14143081b45d955dd7a61a26 (diff)
downloadgcc-955da5e5443724cb59f8fbd854c13e78c68bf000.zip
gcc-955da5e5443724cb59f8fbd854c13e78c68bf000.tar.gz
gcc-955da5e5443724cb59f8fbd854c13e78c68bf000.tar.bz2
CWG 616, 1213 - value category of subobject references.
* tree.c (lvalue_kind): A reference to a subobject of a prvalue is an xvalue. * typeck2.c (build_m_component_ref): Likewise. * typeck.c (cp_build_addr_expr_1, lvalue_or_else): Remove diagnostic distinction between temporary and xvalue. From-SVN: r260621
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/tree.c35
-rw-r--r--gcc/cp/typeck.c14
-rw-r--r--gcc/cp/typeck2.c6
4 files changed, 37 insertions, 27 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1e0854f..3adb570 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2018-05-23 Jason Merrill <jason@redhat.com>
+
+ CWG 616, 1213 - value category of subobject references.
+ * tree.c (lvalue_kind): A reference to a subobject of a prvalue is
+ an xvalue.
+ * typeck2.c (build_m_component_ref): Likewise.
+ * typeck.c (cp_build_addr_expr_1, lvalue_or_else): Remove diagnostic
+ distinction between temporary and xvalue.
+
2018-05-23 Marek Polacek <polacek@redhat.com>
Implement P0614R1, Range-based for statements with initializer.
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 15b9697..efb8c2b 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -87,6 +87,7 @@ lvalue_kind (const_tree ref)
{
case SAVE_EXPR:
return clk_none;
+
/* preincrements and predecrements are valid lvals, provided
what they refer to are valid lvals. */
case PREINCREMENT_EXPR:
@@ -94,7 +95,14 @@ lvalue_kind (const_tree ref)
case TRY_CATCH_EXPR:
case REALPART_EXPR:
case IMAGPART_EXPR:
- return lvalue_kind (TREE_OPERAND (ref, 0));
+ case ARRAY_REF:
+ case VIEW_CONVERT_EXPR:
+ op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
+ if (op1_lvalue_kind == clk_class)
+ /* in the case of an array operand, the result is an lvalue if that
+ operand is an lvalue and an xvalue otherwise */
+ op1_lvalue_kind = clk_rvalueref;
+ return op1_lvalue_kind;
case MEMBER_REF:
case DOTSTAR_EXPR:
@@ -104,6 +112,11 @@ lvalue_kind (const_tree ref)
op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (ref, 1))))
op1_lvalue_kind = clk_none;
+ else if (op1_lvalue_kind == clk_class)
+ /* The result of a .* expression whose second operand is a pointer to a
+ data member is an lvalue if the first operand is an lvalue and an
+ xvalue otherwise. */
+ op1_lvalue_kind = clk_rvalueref;
return op1_lvalue_kind;
case COMPONENT_REF:
@@ -119,6 +132,11 @@ lvalue_kind (const_tree ref)
return lvalue_kind (TREE_OPERAND (ref, 1));
}
op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
+ if (op1_lvalue_kind == clk_class)
+ /* If E1 is an lvalue, then E1.E2 is an lvalue;
+ otherwise E1.E2 is an xvalue. */
+ op1_lvalue_kind = clk_rvalueref;
+
/* Look at the member designator. */
if (!op1_lvalue_kind)
;
@@ -165,7 +183,6 @@ lvalue_kind (const_tree ref)
/* FALLTHRU */
case INDIRECT_REF:
case ARROW_EXPR:
- case ARRAY_REF:
case PARM_DECL:
case RESULT_DECL:
case PLACEHOLDER_EXPR:
@@ -203,11 +220,7 @@ lvalue_kind (const_tree ref)
type-dependent expr, that is, but we shouldn't be testing
lvalueness if we can't even tell the types yet! */
gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE (ref)));
- if (CLASS_TYPE_P (TREE_TYPE (ref))
- || TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE)
- return clk_class;
- else
- return clk_none;
+ goto default_;
}
op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 1)
? TREE_OPERAND (ref, 1)
@@ -257,18 +270,14 @@ lvalue_kind (const_tree ref)
case PAREN_EXPR:
return lvalue_kind (TREE_OPERAND (ref, 0));
- case VIEW_CONVERT_EXPR:
- if (location_wrapper_p (ref))
- return lvalue_kind (TREE_OPERAND (ref, 0));
- /* Fallthrough. */
-
default:
+ default_:
if (!TREE_TYPE (ref))
return clk_none;
if (CLASS_TYPE_P (TREE_TYPE (ref))
|| TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE)
return clk_class;
- break;
+ return clk_none;
}
/* If one operand is not an lvalue at all, then this expression is
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index ecb334d..82089c4 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5860,11 +5860,8 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
{
if (!(complain & tf_error))
return error_mark_node;
- if (kind & clk_class)
- /* Make this a permerror because we used to accept it. */
- permerror (input_location, "taking address of temporary");
- else
- error ("taking address of xvalue (rvalue reference)");
+ /* Make this a permerror because we used to accept it. */
+ permerror (input_location, "taking address of rvalue");
}
}
@@ -9866,11 +9863,8 @@ lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
{
if (!(complain & tf_error))
return 0;
- if (kind & clk_class)
- /* Make this a permerror because we used to accept it. */
- permerror (input_location, "using temporary as lvalue");
- else
- error ("using xvalue (rvalue reference) as lvalue");
+ /* Make this a permerror because we used to accept it. */
+ permerror (input_location, "using rvalue as lvalue");
}
return 1;
}
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index ad0774c..40233e6 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1965,7 +1965,7 @@ build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
if (TYPE_PTRDATAMEM_P (ptrmem_type))
{
- cp_lvalue_kind kind = lvalue_kind (datum);
+ bool is_lval = real_lvalue_p (datum);
tree ptype;
/* Compute the type of the field, as described in [expr.ref].
@@ -1995,9 +1995,7 @@ build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
return error_mark_node;
/* If the object expression was an rvalue, return an rvalue. */
- if (kind & clk_class)
- datum = rvalue (datum);
- else if (kind & clk_rvalueref)
+ if (!is_lval)
datum = move (datum);
return datum;
}