summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-02-09 19:15:55 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-02-09 19:15:55 +0000
commitb627b020b0237ded188fe0a3bf8c2a8cad97251c (patch)
treeb8a9314cd7479a79c90e0c94d9a35788a1f6ac1a
parent5300bef09ec5bfba9459b1d51df36a83f33f12ca (diff)
downloadgcc-b627b020b0237ded188fe0a3bf8c2a8cad97251c.tar.gz
PR c++/64899
* init.c (build_vec_init): Handle default-initialized array with constexpr default constructor. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@220544 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/init.c13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-array10.C12
3 files changed, 30 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3ab1d77a362..37ce9098c10 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2015-02-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/64899
+ * init.c (build_vec_init): Handle default-initialized array with
+ constexpr default constructor.
+
2015-02-04 Jakub Jelinek <jakub@redhat.com>
PR c/64824
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index e600472c72c..0274663c8f4 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3539,7 +3539,9 @@ build_vec_init (tree base, tree maxindex, tree init,
/* Should we try to create a constant initializer? */
bool try_const = (TREE_CODE (atype) == ARRAY_TYPE
&& TREE_CONSTANT (maxindex)
- && init && TREE_CODE (init) == CONSTRUCTOR
+ && (init ? TREE_CODE (init) == CONSTRUCTOR
+ : (type_has_constexpr_default_constructor
+ (inner_elt_type)))
&& (literal_type_p (inner_elt_type)
|| TYPE_HAS_CONSTEXPR_CTOR (inner_elt_type)));
vec<constructor_elt, va_gc> *const_vec = NULL;
@@ -3677,6 +3679,12 @@ build_vec_init (tree base, tree maxindex, tree init,
We do need to keep going if we're copying an array. */
+ if (try_const && !init)
+ /* With a constexpr default constructor, which we checked for when
+ setting try_const above, default-initialization is equivalent to
+ value-initialization, and build_value_init gives us something more
+ friendly to maybe_constant_init. */
+ explicit_value_init_p = true;
if (from_array
|| ((type_build_ctor_call (type) || init || explicit_value_init_p)
&& ! (tree_fits_shwi_p (maxindex)
@@ -3781,6 +3789,7 @@ build_vec_init (tree base, tree maxindex, tree init,
if (try_const)
{
+ /* FIXME refs to earlier elts */
tree e = maybe_constant_init (elt_init);
if (reduced_constant_expression_p (e))
{
@@ -3795,6 +3804,8 @@ build_vec_init (tree base, tree maxindex, tree init,
saw_non_const = true;
if (do_static_init)
e = build_zero_init (TREE_TYPE (e), NULL_TREE, true);
+ else
+ e = NULL_TREE;
}
if (e)
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array10.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array10.C
new file mode 100644
index 00000000000..f7aaa4b943e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array10.C
@@ -0,0 +1,12 @@
+// PR c++/64899
+// { dg-do compile { target c++11 } }
+
+struct S
+{
+ int i;
+ constexpr S (): i(42) {}
+};
+
+constexpr S sa[2];
+#define SA(X) static_assert((X),#X)
+SA(sa[1].i == 42);