From c75ce5301b616b22f1c24f216eed8e84f9074469 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 17 Aug 2015 14:41:59 -0400 Subject: [PATCH] constexpr.c (cxx_eval_store_expression): Don't set CONSTRUCTOR_NO_IMPLICIT_ZERO if we have an enclosing CONSTRUCTOR... * 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. From-SVN: r226948 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/constexpr.c | 20 +++++++++++++++++-- .../g++.dg/cpp0x/constexpr-array12.C | 8 ++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-array12.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 595781cdb3e..c6bd397748a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2015-08-17 Jason Merrill + * 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. + * except.c (check_noexcept_r): Assert that fn is POINTER_TYPE_P. 2015-08-14 Jason Merrill diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 6048f062593..35875a84361 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1732,6 +1732,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); @@ -2674,13 +2686,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(); @@ -2708,7 +2724,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 00000000000..347ee54f06f --- /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" } +} -- 2.30.2