Commit f370e36d by Jakub Jelinek Committed by Jakub Jelinek

re PR c++/82781 (Vector extension operators return wrong result in constexpr)

	PR c++/82781
	* constexpr.c (cxx_eval_vector_conditional_expression): New function.
	(cxx_eval_constant_expression) <case VEC_COND_EXPR>: Use it instead
	of cxx_eval_conditional_expression.

	* g++.dg/ext/constexpr-pr82781.C: New test.

From-SVN: r254952
parent 1ebafce0
2017-11-20 Jakub Jelinek <jakub@redhat.com>
PR c++/82781
* constexpr.c (cxx_eval_vector_conditional_expression): New function.
(cxx_eval_constant_expression) <case VEC_COND_EXPR>: Use it instead
of cxx_eval_conditional_expression.
2017-11-19 Jakub Jelinek <jakub@redhat.com>
PR c/66618
......
......@@ -2086,6 +2086,45 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
jump_target);
}
/* Subroutine of cxx_eval_constant_expression.
Attempt to evaluate vector condition expressions. Unlike
cxx_eval_conditional_expression, VEC_COND_EXPR acts like a normal
ternary arithmetics operation, where all 3 arguments have to be
evaluated as constants and then folding computes the result from
them. */
static tree
cxx_eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t,
bool *non_constant_p, bool *overflow_p)
{
tree arg1 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
/*lval*/false,
non_constant_p, overflow_p);
VERIFY_CONSTANT (arg1);
tree arg2 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
/*lval*/false,
non_constant_p, overflow_p);
VERIFY_CONSTANT (arg2);
tree arg3 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
/*lval*/false,
non_constant_p, overflow_p);
VERIFY_CONSTANT (arg3);
location_t loc = EXPR_LOCATION (t);
tree type = TREE_TYPE (t);
tree r = fold_ternary_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
if (r == NULL_TREE)
{
if (arg1 == TREE_OPERAND (t, 0)
&& arg2 == TREE_OPERAND (t, 1)
&& arg3 == TREE_OPERAND (t, 2))
r = t;
else
r = build3_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
}
VERIFY_CONSTANT (r);
return r;
}
/* Returns less than, equal to, or greater than zero if KEY is found to be
less than, to match, or to be greater than the constructor_elt's INDEX. */
......@@ -4398,12 +4437,14 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
jump_target);
break;
}
/* FALLTHRU */
case VEC_COND_EXPR:
r = cxx_eval_conditional_expression (ctx, t, lval,
non_constant_p, overflow_p,
jump_target);
break;
case VEC_COND_EXPR:
r = cxx_eval_vector_conditional_expression (ctx, t, non_constant_p,
overflow_p);
break;
case CONSTRUCTOR:
if (TREE_CONSTANT (t))
......
2017-11-20 Jakub Jelinek <jakub@redhat.com>
PR c++/82781
* g++.dg/ext/constexpr-pr82781.C: New test.
2017-11-20 Christophe Lyon <christophe.lyon@linaro.org>
* gcc.target/arm/pr69180.c: Use -: for no column in expected
......
// PR c++/82781
// { dg-do compile { target c++11 } }
typedef int V __attribute__ ((vector_size (16)));
constexpr V b1 = { 0, 1, 10, 20 };
constexpr V b2 = { 0, 2, 10, 0 };
constexpr V b3 = b1 == b2;
static_assert (b3[0] == -1, "");
static_assert (b3[1] == 0, "");
static_assert (b3[2] == -1, "");
static_assert (b3[3] == 0, "");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment