aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-11-20 13:57:50 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-11-20 13:57:50 +0100
commitf370e36dc9aba0a5cafa4e6fac893b49acbfb6e8 (patch)
treee033191b795202233509a9f5a4c1100f881dfdc6 /gcc
parent1ebafce0bc9072f9aabd0692bbb1aeda672f6b60 (diff)
downloadgcc-f370e36dc9aba0a5cafa4e6fac893b49acbfb6e8.zip
gcc-f370e36dc9aba0a5cafa4e6fac893b49acbfb6e8.tar.gz
gcc-f370e36dc9aba0a5cafa4e6fac893b49acbfb6e8.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/constexpr.c45
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ext/constexpr-pr82781.C12
4 files changed, 67 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 410b18b..6f4d30e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+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
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index d6b6843..5eac64b 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -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))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c6b860c..6148d4b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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
diff --git a/gcc/testsuite/g++.dg/ext/constexpr-pr82781.C b/gcc/testsuite/g++.dg/ext/constexpr-pr82781.C
new file mode 100644
index 0000000..eee0159
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/constexpr-pr82781.C
@@ -0,0 +1,12 @@
+// 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, "");