commit 6a4d118d9ae128791a4f043cc1e079c82bad6fb8 Author: Jason Merrill Date: Wed Aug 12 17:54:04 2015 +0100 * constexpr.c (cxx_eval_store_expression): Don't set CONSTRUCTOR_NO_IMPLICIT_ZERO if we have an enclosing CONSTRUCTOR without it. (cxx_eval_array_reference): Check it. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 81afb47..2aef631 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1741,6 +1741,18 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, { if (tree_int_cst_lt (index, array_type_nelts_top (TREE_TYPE (ary)))) { + if (TREE_CODE (ary) == CONSTRUCTOR + && CONSTRUCTOR_NO_IMPLICIT_ZERO (ary)) + { + /* 'ary' is part of the aggregate initializer we're currently + building; if there's no initializer for this element yet, + that's an error. */ + if (!ctx->quiet) + error ("accessing uninitialized array element"); + *non_constant_p = true; + return t; + } + /* If it's within the array bounds but doesn't have an explicit initializer, it's value-initialized. */ tree val = build_value_init (elem_type, tf_warning_or_error); @@ -2683,13 +2695,17 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, return t; } type = TREE_TYPE (object); + bool no_zero_init = true; while (!refs->is_empty()) { if (*valp == NULL_TREE) { *valp = build_constructor (type, NULL); - CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp) = true; + CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp) = no_zero_init; } + /* If the value of object is already zero-initialized, any new ctors for + subobjects will also be zero-initialized. */ + no_zero_init = CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp); constructor_elt ce; type = refs->pop(); @@ -2717,7 +2733,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, new_ctx.ctor = build_constructor (type, NULL); if (*valp == NULL_TREE) *valp = new_ctx.ctor; - CONSTRUCTOR_NO_IMPLICIT_ZERO (new_ctx.ctor) = true; + CONSTRUCTOR_NO_IMPLICIT_ZERO (new_ctx.ctor) = no_zero_init; new_ctx.object = target; } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array12.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array12.C new file mode 100644 index 0000000..347ee54 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array12.C @@ -0,0 +1,8 @@ +// { dg-do compile { target c++11 } } + +struct A { int ar[3]; }; +int main() +{ + constexpr A a1 = { 0, a1.ar[0] }; + constexpr A a2 = { a2.ar[0] }; // { dg-error "uninitialized" } +}