aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-05-24 07:55:56 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-05-24 07:55:56 +0000
commitf17a223de829cb5fa0b32a9f12c22a4fa929506c (patch)
tree8563bc5695a3444a499e0c3f237354120053f294 /gcc/cp/constexpr.c
parent64fc0cd9b2a83a4b0301d8d7890bf27880d8384e (diff)
downloadgcc-f17a223de829cb5fa0b32a9f12c22a4fa929506c.zip
gcc-f17a223de829cb5fa0b32a9f12c22a4fa929506c.tar.gz
gcc-f17a223de829cb5fa0b32a9f12c22a4fa929506c.tar.bz2
re PR middle-end/70434 (adding an extraneous cast to vector type results in inferior code)
2016-05-24 Richard Biener <rguenther@suse.de> PR middle-end/70434 PR c/69504 c-family/ * c-common.h (convert_vector_to_pointer_for_subscript): Rename to ... (convert_vector_to_array_for_subscript): ... this. * c-common.c (convert_vector_to_pointer_for_subscript): Use a VIEW_CONVERT_EXPR to an array type. Rename to ... (convert_vector_to_array_for_subscript): ... this. cp/ * expr.c (mark_exp_read): Handle VIEW_CONVERT_EXPR. * constexpr.c (cxx_eval_array_reference): Handle indexed vectors. * typeck.c (cp_build_array_ref): Adjust. c/ * c-typeck.c (build_array_ref): Do not complain about indexing non-lvalue vectors. Adjust for function name change. * tree-ssa.c (non_rewritable_mem_ref_base): Make sure to mark bases which are accessed with non-invariant indices. * gimple-fold.c (maybe_canonicalize_mem_ref_addr): Re-write constant index ARRAY_REFs of vectors into BIT_FIELD_REFs. * c-c++-common/vector-subscript-4.c: New testcase. * c-c++-common/vector-subscript-5.c: Likewise. From-SVN: r236630
Diffstat (limited to 'gcc/cp/constexpr.c')
-rw-r--r--gcc/cp/constexpr.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index bb723f4..482f8af 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1983,6 +1983,10 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
else if (lval)
return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
elem_type = TREE_TYPE (TREE_TYPE (ary));
+ if (TREE_CODE (ary) == VIEW_CONVERT_EXPR
+ && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
+ && TREE_TYPE (t) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0))))
+ ary = TREE_OPERAND (ary, 0);
if (TREE_CODE (ary) == CONSTRUCTOR)
len = CONSTRUCTOR_NELTS (ary);
else if (TREE_CODE (ary) == STRING_CST)
@@ -1991,6 +1995,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
/ TYPE_PRECISION (char_type_node));
len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
}
+ else if (TREE_CODE (ary) == VECTOR_CST)
+ len = VECTOR_CST_NELTS (ary);
else
{
/* We can't do anything with other tree codes, so use
@@ -2007,7 +2013,14 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
return t;
}
- tree nelts = array_type_nelts_top (TREE_TYPE (ary));
+ tree nelts;
+ if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
+ nelts = array_type_nelts_top (TREE_TYPE (ary));
+ else if (VECTOR_TYPE_P (TREE_TYPE (ary)))
+ nelts = size_int (TYPE_VECTOR_SUBPARTS (TREE_TYPE (ary)));
+ else
+ gcc_unreachable ();
+
/* For VLAs, the number of elements won't be an integer constant. */
nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
overflow_p);
@@ -2053,6 +2066,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
if (TREE_CODE (ary) == CONSTRUCTOR)
return (*CONSTRUCTOR_ELTS (ary))[i].value;
+ else if (TREE_CODE (ary) == VECTOR_CST)
+ return VECTOR_CST_ELT (ary, i);
else if (elem_nchars == 1)
return build_int_cst (cv_unqualified (TREE_TYPE (TREE_TYPE (ary))),
TREE_STRING_POINTER (ary)[i]);