aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/c-common.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-11-21 10:25:51 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2014-11-21 10:25:51 +0100
commitaa7da51a8c95366b781d0ce5e6cb046ef0aa899f (patch)
treec648ac0560be23d2a39d095a04c8de340e96f4bc /gcc/c-family/c-common.c
parent0daaf8aa4d32fee71136021003bca60cc350a04e (diff)
downloadgcc-aa7da51a8c95366b781d0ce5e6cb046ef0aa899f.zip
gcc-aa7da51a8c95366b781d0ce5e6cb046ef0aa899f.tar.gz
gcc-aa7da51a8c95366b781d0ce5e6cb046ef0aa899f.tar.bz2
re PR target/63764 (ICE: in verify_ssa, at tree-ssa.c:939)
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. From-SVN: r217909
Diffstat (limited to 'gcc/c-family/c-common.c')
-rw-r--r--gcc/c-family/c-common.c35
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