Re: [PATCH] Fix ICE with non-lvalue vector subscripts and make sure non-lvalue vector subscripts aren't used as lvalues (PR target/63764)

2014-12-08 Thread Jeff Law

On 11/20/14 11:09, Jakub Jelinek wrote:

Hi!

This patch fixes ICEs if a non-lvalue vector (say cast of one vector
to another vector type) was subscripted and used as lhs.
The following patch, if *vecp is not lvalue, will copy it to a temporary
variable which can be made addressable for the subscription, and afterwards
wrap it into a NON_LVALUE_EXPR so that it is properly rejected if later used
on the lhs.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2014-11-20  Jakub Jelinek  ja...@redhat.com

PR target/63764
c-family/
* c-common.h (convert_vector_to_pointer_for_subscript): Change
return type to bool.
* c-common.c: Include gimple-expr.c.
This was in c-family and thus I didn't see it as committed...  So when I 
went to review, I saw the typo gimple-expr.c when you meant to write 
gimple-expr.h in the ChangeLog entry.


Fixed in the obvious way.

jeff


[PATCH] Fix ICE with non-lvalue vector subscripts and make sure non-lvalue vector subscripts aren't used as lvalues (PR target/63764)

2014-11-20 Thread Jakub Jelinek
Hi!

This patch fixes ICEs if a non-lvalue vector (say cast of one vector
to another vector type) was subscripted and used as lhs.
The following patch, if *vecp is not lvalue, will copy it to a temporary
variable which can be made addressable for the subscription, and afterwards
wrap it into a NON_LVALUE_EXPR so that it is properly rejected if later used
on the lhs.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2014-11-20  Jakub Jelinek  ja...@redhat.com

PR target/63764
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.

--- gcc/c-family/c-common.h.jj  2014-11-19 15:39:26.606065628 +0100
+++ gcc/c-family/c-common.h 2014-11-20 08:38:02.527655971 +0100
@@ -1310,7 +1310,7 @@ extern tree build_userdef_literal (tree
   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 {
--- gcc/c-family/c-common.c.jj  2014-11-19 15:39:26.606065628 +0100
+++ gcc/c-family/c-common.c 2014-11-20 08:50:21.000573676 +0100
@@ -60,6 +60,7 @@ along with GCC; see the file COPYING3.
 #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, t
 }
 
 /* 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,
-tree* vecp, 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
   *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
--- gcc/c/c-typeck.c.jj 2014-11-19 15:39:24.044113650 +0100
+++ gcc/c/c-typeck.c2014-11-20 08:38:02.534655847 +0100
@@ -2495,7 +2495,8 @@ build_array_ref (location_t loc, tree ar
 
   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 

Re: [PATCH] Fix ICE with non-lvalue vector subscripts and make sure non-lvalue vector subscripts aren't used as lvalues (PR target/63764)

2014-11-20 Thread Richard Henderson
On 11/20/2014 07:09 PM, Jakub Jelinek wrote:
 Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
 
 2014-11-20  Jakub Jelinek  ja...@redhat.com
 
   PR target/63764
 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.

Ok.


r~