aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/constexpr.c31
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ext/constexpr-pr93549.C26
4 files changed, 68 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f1fe774..9205b20 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2020-02-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/93549
+ * constexpr.c (find_array_ctor_elt): If last element has no index,
+ for flag_checking verify all elts have no index. If i is within the
+ elts, return it directly, if it is right after the last elt, append
+ if NULL index, otherwise force indexes on all elts.
+ (cxx_eval_store_expression): Allow cep->index to be NULL.
+
2020-02-07 Marek Polacek <polacek@redhat.com>
PR c++/92947 - Paren init of aggregates in unevaluated context.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 8a02c6e..aa47ded 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -3028,8 +3028,32 @@ find_array_ctor_elt (tree ary, tree dindex, bool insert)
if (end > 0)
{
tree cindex = (*elts)[end - 1].index;
- if (TREE_CODE (cindex) == INTEGER_CST
- && compare_tree_int (cindex, end - 1) == 0)
+ if (cindex == NULL_TREE)
+ {
+ /* Verify that if the last index is missing, all indexes
+ are missing. */
+ if (flag_checking)
+ for (unsigned int j = 0; j < len - 1; ++j)
+ gcc_assert ((*elts)[j].index == NULL_TREE);
+ if (i < end)
+ return i;
+ else
+ {
+ begin = end;
+ if (i == end)
+ /* If the element is to be added right at the end,
+ make sure it is added with cleared index too. */
+ dindex = NULL_TREE;
+ else if (insert)
+ /* Otherwise, in order not to break the assumption
+ that CONSTRUCTOR either has all indexes or none,
+ we need to add indexes to all elements. */
+ for (unsigned int j = 0; j < len; ++j)
+ (*elts)[j].index = build_int_cst (TREE_TYPE (dindex), j);
+ }
+ }
+ else if (TREE_CODE (cindex) == INTEGER_CST
+ && compare_tree_int (cindex, end - 1) == 0)
{
if (i < end)
return i;
@@ -4551,7 +4575,8 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
= find_array_ctor_elt (*valp, index, /*insert*/true);
gcc_assert (i >= 0);
cep = CONSTRUCTOR_ELT (*valp, i);
- gcc_assert (TREE_CODE (cep->index) != RANGE_EXPR);
+ gcc_assert (cep->index == NULL_TREE
+ || TREE_CODE (cep->index) != RANGE_EXPR);
}
else
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1499966..cfe4197 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-02-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/93549
+ * g++.dg/ext/constexpr-pr93549.C: New test.
+
2020-02-08 Uroš Bizjak <ubizjak@gmail.com>
Jakub Jelinek <jakub@redhat.com>
diff --git a/gcc/testsuite/g++.dg/ext/constexpr-pr93549.C b/gcc/testsuite/g++.dg/ext/constexpr-pr93549.C
new file mode 100644
index 0000000..eaa232d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/constexpr-pr93549.C
@@ -0,0 +1,26 @@
+// PR c++/93549
+// { dg-do compile { target c++17 } }
+// { dg-options "-O2 -Wno-psabi -w" }
+
+struct simd {
+ using shortx8 [[gnu::vector_size(16)]] = short;
+ shortx8 data;
+ constexpr simd (short x) : data{x, x, x, x, x, x, x, x} {}
+ constexpr friend unsigned operator== (simd lhs, simd rhs)
+ {
+ shortx8 tmp = lhs.data == rhs.data;
+ using ushort = unsigned short;
+ auto bools = tmp ? ushort(1) : ushort(0);
+ unsigned bits = 0;
+ for (int i = 0; i < 8; ++i)
+ bits |= bools[i] << i;
+ return bits;
+ }
+};
+
+auto
+foo ()
+{
+ constexpr auto tmp = simd(1) == simd(2);
+ return tmp;
+}