diff options
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/constexpr-pr93549.C | 26 |
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; +} |