CWG 616, 1213 - value category of subobject references.
authorJason Merrill <jason@redhat.com>
Fri, 25 May 2018 20:55:32 +0000 (16:55 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 25 May 2018 20:55:32 +0000 (16:55 -0400)
* tree.c (lvalue_kind): Fix handling of ARRAY_REF of pointer.

From-SVN: r260780

gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/g++.dg/template/array31.C [new file with mode: 0644]

index 371c8b76fef474471534fc01b9c730c965bf5c61..9c2548d53779529ee0c88a2a6962d5d26299b74a 100644 (file)
@@ -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.
index 9d97816029235f89f5a38b5846b22b6eaf8ef0a5..f21daaca1d0991b0145e3fa64c47b750d943e229 100644 (file)
@@ -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 (file)
index 0000000..007d0dc
--- /dev/null
@@ -0,0 +1,7 @@
+int *g();
+
+template <class T> 
+void f(int i)
+{
+  int *p = &g()[3];
+}