diff options
-rw-r--r-- | gcc/c-family/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 35 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 2 | ||||
-rw-r--r-- | gcc/c/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 14 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr63764-1.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr63764-2.c | 35 |
10 files changed, 133 insertions, 10 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index cf91913..c9003ec 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -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". diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 95b6b1b..bff8c2a 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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, - 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 (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 diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 7e53923..658cef0 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -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 { diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index fa3c925..79d4183 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -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 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 338ef44..67efb46 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -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; } } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ee431a1..033ce7b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 7156851..e100d70 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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; } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f065cc2..034f4d9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..a858747 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr63764-1.c @@ -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 index 0000000..6bbf661 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr63764-2.c @@ -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; +} |