aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-05-25 16:55:32 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-05-25 16:55:32 -0400
commit3983063e76edec0a49badb341daa1ba438c5a9a7 (patch)
tree2ee21aa22979566ce1dcc603f781ca65fe8136d4
parent9d502741aa65321078d059865865bdc93af445b6 (diff)
downloadgcc-3983063e76edec0a49badb341daa1ba438c5a9a7.zip
gcc-3983063e76edec0a49badb341daa1ba438c5a9a7.tar.gz
gcc-3983063e76edec0a49badb341daa1ba438c5a9a7.tar.bz2
CWG 616, 1213 - value category of subobject references.
* tree.c (lvalue_kind): Fix handling of ARRAY_REF of pointer. From-SVN: r260780
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/tree.c24
-rw-r--r--gcc/testsuite/g++.dg/template/array31.C7
3 files changed, 29 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 371c8b7..9c2548d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2018-05-25 Jason Merrill <jason@redhat.com>
+
+ CWG 616, 1213 - value category of subobject references.
+ * tree.c (lvalue_kind): Fix handling of ARRAY_REF of pointer.
+
2018-05-24 Jason Merrill <jason@redhat.com>
PR c++/85842 - -Wreturn-type, constexpr if and generic lambda.
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 9d97816..f21daac 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -95,14 +95,24 @@ lvalue_kind (const_tree ref)
case TRY_CATCH_EXPR:
case REALPART_EXPR:
case IMAGPART_EXPR:
- 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;
+ return lvalue_kind (TREE_OPERAND (ref, 0));
+
+ case ARRAY_REF:
+ {
+ tree op1 = TREE_OPERAND (ref, 0);
+ if (TREE_CODE (TREE_TYPE (op1)) == ARRAY_TYPE)
+ {
+ op1_lvalue_kind = lvalue_kind (op1);
+ 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;
+ }
+ else
+ return clk_ordinary;
+ }
case MEMBER_REF:
case DOTSTAR_EXPR:
diff --git a/gcc/testsuite/g++.dg/template/array31.C b/gcc/testsuite/g++.dg/template/array31.C
new file mode 100644
index 0000000..007d0dc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/array31.C
@@ -0,0 +1,7 @@
+int *g();
+
+template <class T>
+void f(int i)
+{
+ int *p = &g()[3];
+}