diff options
Diffstat (limited to 'gcc/c-family/c-common.c')
-rw-r--r-- | gcc/c-family/c-common.c | 35 |
1 files changed, 31 insertions, 4 deletions
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 |