]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR target/63764
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 21 Nov 2014 09:25:51 +0000 (09:25 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 21 Nov 2014 09:25:51 +0000 (09:25 +0000)
c-family/
* c-common.h (convert_vector_to_pointer_for_subscript): Change
return type to bool.
* c-common.c: Include gimple-expr.c.
(convert_vector_to_pointer_for_subscript): Change return type to
bool.  If *vecp is not lvalue_p and has VECTOR_TYPE, return true
and copy it into a TARGET_EXPR and use that instead of *vecp
directly.
c/
* c-typeck.c (build_array_ref): Adjust
convert_vector_to_pointer_for_subscript caller.  If it returns true,
call non_lvalue_loc on the result.
cp/
* typeck.c (cp_build_array_ref): Adjust
convert_vector_to_pointer_for_subscript caller.  If it returns true,
call non_lvalue_loc on the result.
testsuite/
* c-c++-common/pr63764-1.c: New test.
* c-c++-common/pr63764-2.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217909 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr63764-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr63764-2.c [new file with mode: 0644]

index cf919132e4d12ec889924a04b5c0cd160989c4a7..c9003ec66bda31d75a2126d14ff224662f9460ad 100644 (file)
@@ -1,3 +1,14 @@
+2014-11-21  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/63764
+       * c-common.h (convert_vector_to_pointer_for_subscript): Change
+       return type to bool.
+       * c-common.c: Include gimple-expr.c.
+       (convert_vector_to_pointer_for_subscript): Change return type to
+       bool.  If *vecp is not lvalue_p and has VECTOR_TYPE, return true
+       and copy it into a TARGET_EXPR and use that instead of *vecp
+       directly.
+
 2014-11-19  David Malcolm  <dmalcolm@redhat.com>
 
        Merger of git branch "gimple-classes-v2-option-3".
index 95b6b1b93e05a6461036cf845ea280176a172cab..bff8c2a5a9dc42393412a3264f86c6b4d8e02973 100644 (file)
@@ -60,6 +60,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target-def.h"
 #include "gimplify.h"
 #include "wide-int-print.h"
+#include "gimple-expr.h"
 
 cpp_reader *parse_in;          /* Declared in c-pragma.h.  */
 
@@ -12030,22 +12031,47 @@ build_userdef_literal (tree suffix_id, tree value,
 }
 
 /* For vector[index], convert the vector to a
-   pointer of the underlying type.  */
-void
+   pointer of the underlying type.  Return true if the resulting
+   ARRAY_REF should not be an lvalue.  */
+
+bool
 convert_vector_to_pointer_for_subscript (location_t loc,
-                                        treevecp, tree index)
+                                        tree *vecp, tree index)
 {
+  bool ret = false;
   if (TREE_CODE (TREE_TYPE (*vecp)) == VECTOR_TYPE)
     {
       tree type = TREE_TYPE (*vecp);
       tree type1;
 
+      ret = !lvalue_p (*vecp);
       if (TREE_CODE (index) == INTEGER_CST)
         if (!tree_fits_uhwi_p (index)
             || tree_to_uhwi (index) >= TYPE_VECTOR_SUBPARTS (type))
           warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
 
-      c_common_mark_addressable_vec (*vecp);
+      if (ret)
+       {
+         tree tmp = create_tmp_var_raw (type, NULL);
+         DECL_SOURCE_LOCATION (tmp) = loc;
+         *vecp = c_save_expr (*vecp);
+         if (TREE_CODE (*vecp) == C_MAYBE_CONST_EXPR)
+           {
+             bool non_const = C_MAYBE_CONST_EXPR_NON_CONST (*vecp);
+             *vecp = C_MAYBE_CONST_EXPR_EXPR (*vecp);
+             *vecp
+               = c_wrap_maybe_const (build4 (TARGET_EXPR, type, tmp,
+                                             *vecp, NULL_TREE, NULL_TREE),
+                                     non_const);
+           }
+         else
+           *vecp = build4 (TARGET_EXPR, type, tmp, *vecp,
+                           NULL_TREE, NULL_TREE);
+         SET_EXPR_LOCATION (*vecp, loc);
+         c_common_mark_addressable_vec (tmp);
+       }
+      else
+       c_common_mark_addressable_vec (*vecp);
       type = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
       type1 = build_pointer_type (TREE_TYPE (*vecp));
       bool ref_all = TYPE_REF_CAN_ALIAS_ALL (type1);
@@ -12065,6 +12091,7 @@ convert_vector_to_pointer_for_subscript (location_t loc,
       *vecp = build1 (ADDR_EXPR, type1, *vecp);
       *vecp = convert (type, *vecp);
     }
+  return ret;
 }
 
 /* Determine which of the operands, if any, is a scalar that needs to be
index 7e53923a551e5df0f8df024cd16ecd72cb2eb9cd..658cef0427d4d154c8def4ec8e691b6d322fe826 100644 (file)
@@ -1310,7 +1310,7 @@ extern tree build_userdef_literal (tree suffix_id, tree value,
                                   enum overflow_type overflow,
                                   tree num_string);
 
-extern void convert_vector_to_pointer_for_subscript (location_t, tree*, tree);
+extern bool convert_vector_to_pointer_for_subscript (location_t, tree *, tree);
 
 /* Possibe cases of scalar_to_vector conversion.  */
 enum stv_conv {
index fa3c925e74681bf18956e941e5e963efb988224b..79d41830ee161c914d891173693c3fa27278bebc 100644 (file)
@@ -1,3 +1,10 @@
+2014-11-21  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/63764
+       * c-typeck.c (build_array_ref): Adjust
+       convert_vector_to_pointer_for_subscript caller.  If it returns true,
+       call non_lvalue_loc on the result.
+
 2014-11-11  Richard Biener  <rguenther@suse.de>
 
        * c-decl.c (c_init_decl_processing): Do not set pedantic_lvalues
index 338ef44eefba190736ed1bba0f394e9e98d0c59c..67efb465a2440120d43a0b82fa25b7c94b408878 100644 (file)
@@ -2495,7 +2495,8 @@ build_array_ref (location_t loc, tree array, tree index)
 
   gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE);
 
-  convert_vector_to_pointer_for_subscript (loc, &array, index);
+  bool non_lvalue
+    = convert_vector_to_pointer_for_subscript (loc, &array, index);
 
   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
     {
@@ -2557,6 +2558,8 @@ build_array_ref (location_t loc, tree array, tree index)
            | TREE_THIS_VOLATILE (array));
       ret = require_complete_type (rval);
       protected_set_expr_location (ret, loc);
+      if (non_lvalue)
+       ret = non_lvalue_loc (loc, ret);
       return ret;
     }
   else
@@ -2569,9 +2572,12 @@ build_array_ref (location_t loc, tree array, tree index)
       gcc_assert (TREE_CODE (TREE_TYPE (ar)) == POINTER_TYPE);
       gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE);
 
-      return build_indirect_ref
-       (loc, build_binary_op (loc, PLUS_EXPR, ar, index, 0),
-        RO_ARRAY_INDEXING);
+      ret = build_indirect_ref (loc, build_binary_op (loc, PLUS_EXPR, ar,
+                                                     index, 0),
+                               RO_ARRAY_INDEXING);
+      if (non_lvalue)
+       ret = non_lvalue_loc (loc, ret);
+      return ret;
     }
 }
 \f
index ee431a1091d0a5c93aa2265a88759b2119ab6488..033ce7b74992d3921ee6d1d42995f2030aa85ff1 100644 (file)
@@ -1,3 +1,10 @@
+2014-11-21  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/63764
+       * typeck.c (cp_build_array_ref): Adjust
+       convert_vector_to_pointer_for_subscript caller.  If it returns true,
+       call non_lvalue_loc on the result.
+
 2014-11-20  Jason Merrill  <jason@redhat.com>
 
        PR c++/63658
index 71568515389516a88cca5c30adfb4066482d8635..e100d70b1f2d7353a4e8292f162566edd85279cb 100644 (file)
@@ -3072,7 +3072,8 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
       break;
     }
 
-  convert_vector_to_pointer_for_subscript (loc, &array, idx);
+  bool non_lvalue
+    = convert_vector_to_pointer_for_subscript (loc, &array, idx);
 
   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
     {
@@ -3155,6 +3156,8 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
       ret = require_complete_type_sfinae (fold_if_not_in_template (rval),
                                          complain);
       protected_set_expr_location (ret, loc);
+      if (non_lvalue)
+       ret = non_lvalue_loc (loc, ret);
       return ret;
     }
 
@@ -3194,6 +3197,8 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
                                  RO_ARRAY_INDEXING,
                                  complain);
     protected_set_expr_location (ret, loc);
+    if (non_lvalue)
+      ret = non_lvalue_loc (loc, ret);
     return ret;
   }
 }
index f065cc24c192bb4286773bce76fdb6353dcbb117..034f4d941745f59b76d19f10651fc062be10a1c7 100644 (file)
@@ -1,5 +1,9 @@
 2014-11-21  Jakub Jelinek  <jakub@redhat.com>
 
+       PR target/63764
+       * c-c++-common/pr63764-1.c: New test.
+       * c-c++-common/pr63764-2.c: New test.
+
        PR target/63910
        * gcc.target/i386/pr63910.c: New test.
 
diff --git a/gcc/testsuite/c-c++-common/pr63764-1.c b/gcc/testsuite/c-c++-common/pr63764-1.c
new file mode 100644 (file)
index 0000000..a858747
--- /dev/null
@@ -0,0 +1,21 @@
+/* PR target/63764 */
+/* { dg-do compile } */
+
+#define A __attribute__((vector_size (4 * sizeof (float))))
+typedef float V A;
+
+void
+fn1 (V *x)
+{
+  V a = *x;
+  ((V) a)[0] = 0;      /* { dg-error "lvalue required as left operand of assignment" } */
+  *x = a;
+}
+
+void
+fn2 (V *x)
+{
+  float A a = *x;
+  ((float A) a)[0] = 0;        /* { dg-error "lvalue required as left operand of assignment" } */
+  *x = a;
+}
diff --git a/gcc/testsuite/c-c++-common/pr63764-2.c b/gcc/testsuite/c-c++-common/pr63764-2.c
new file mode 100644 (file)
index 0000000..6bbf661
--- /dev/null
@@ -0,0 +1,35 @@
+/* PR target/63764 */
+/* { dg-do compile } */
+
+#define A __attribute__((vector_size (4 * sizeof (float))))
+typedef float V A;
+
+float
+fn1 (V *x)
+{
+  V a = *x;
+  return ((V) a)[0];
+}
+
+float
+fn2 (V *x)
+{
+  float A a = *x;
+  return ((float A) a)[0];
+}
+
+void
+fn3 (V *x)
+{
+  V a = *x;
+  a[0] = 0;
+  *x = a;
+}
+
+void
+fn4 (V *x)
+{
+  float A a = *x;
+  a[0] = 0;
+  *x = a;
+}