public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-8216] c++: partially initialized constexpr array [PR99700]
@ 2021-04-16 13:25 Patrick Palka
0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2021-04-16 13:25 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:baf05d54dc919c968d12de9d049e36e5bac10dec
commit r11-8216-gbaf05d54dc919c968d12de9d049e36e5bac10dec
Author: Patrick Palka <ppalka@redhat.com>
Date: Fri Apr 16 09:24:46 2021 -0400
c++: partially initialized constexpr array [PR99700]
Here, reduced_constant_expression_p is incorrectly returning true for a
partially initialized array CONSTRUCTOR (in C++20 mode) because when the
CONSTRUCTOR_NO_CLEARING flag is set, the predicate doesn't check that
the CONSTRUCTOR spans the entire array like it does for class CONSTRUCTORS.
This patch adds a dedicated loop for the array case that simultaneously
verifies the CONSTRUCTOR spans the entire array and is made up of valid
constant expressions.
gcc/cp/ChangeLog:
PR c++/99700
* constexpr.c (reduced_constant_expression_p): For array
CONSTRUCTORs, use a dedicated loop that additionally verifies
the CONSTRUCTOR spans the entire array.
gcc/testsuite/ChangeLog:
PR c++/99700
* g++.dg/cpp2a/constexpr-init21.C: New test.
Diff:
---
gcc/cp/constexpr.c | 24 ++++++++++++++++++++++--
gcc/testsuite/g++.dg/cpp2a/constexpr-init21.C | 27 +++++++++++++++++++++++++++
2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index c8d9dae36fb..b74bbac3cd2 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -46,6 +46,7 @@ do { \
static HOST_WIDE_INT find_array_ctor_elt (tree ary, tree dindex,
bool insert = false);
+static int array_index_cmp (tree key, tree index);
/* Returns true iff FUN is an instantiation of a constexpr function
template or a defaulted constexpr function. */
@@ -2910,9 +2911,27 @@ reduced_constant_expression_p (tree t)
/* An initialized vector would have a VECTOR_CST. */
return false;
else if (cxx_dialect >= cxx20
- /* An ARRAY_TYPE doesn't have any TYPE_FIELDS. */
&& TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
- field = NULL_TREE;
+ {
+ /* There must be a valid constant initializer at every array
+ index. */
+ tree min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (t)));
+ tree max = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t)));
+ tree cursor = min;
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, idx, val)
+ {
+ if (!reduced_constant_expression_p (val))
+ return false;
+ if (array_index_cmp (cursor, idx) != 0)
+ return false;
+ if (TREE_CODE (idx) == RANGE_EXPR)
+ cursor = TREE_OPERAND (idx, 1);
+ cursor = int_const_binop (PLUS_EXPR, cursor, size_one_node);
+ }
+ if (find_array_ctor_elt (t, max) == -1)
+ return false;
+ goto ok;
+ }
else if (cxx_dialect >= cxx20
&& TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
{
@@ -2946,6 +2965,7 @@ reduced_constant_expression_p (tree t)
for (; field; field = next_initializable_field (DECL_CHAIN (field)))
if (!is_really_empty_class (TREE_TYPE (field), /*ignore_vptr*/false))
return false;
+ok:
if (CONSTRUCTOR_NO_CLEARING (t))
/* All the fields are initialized. */
CONSTRUCTOR_NO_CLEARING (t) = false;
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-init21.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-init21.C
new file mode 100644
index 00000000000..f5e1b3e76da
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-init21.C
@@ -0,0 +1,27 @@
+// PR c++/99700
+// { dg-do compile { target c++20 } }
+
+template <class T>
+struct A {
+ T c[5];
+ constexpr A(int skip = -1) {
+ for (int i = 0; i < 5; i++)
+ if (i != skip)
+ c[i] = {};
+ }
+};
+
+constexpr A<int> a;
+constexpr A<int> a0(0); // { dg-error "not a constant expression|incompletely initialized" }
+constexpr A<int> a1(1); // { dg-error "not a constant expression|incompletely initialized" }
+constexpr A<int> a2(2); // { dg-error "not a constant expression|incompletely initialized" }
+constexpr A<int> a3(3); // { dg-error "not a constant expression|incompletely initialized" }
+constexpr A<int> a4(4); // { dg-error "not a constant expression|incompletely initialized" }
+
+struct s { int n; };
+constexpr A<s> b;
+constexpr A<s> b0(0); // { dg-error "not a constant expression|incompletely initialized" }
+
+struct empty {};
+constexpr A<empty> c;
+constexpr A<empty> c0(0);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-04-16 13:25 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-16 13:25 [gcc r11-8216] c++: partially initialized constexpr array [PR99700] Patrick Palka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).