From: Jason Merrill Date: Sun, 6 Mar 2016 06:47:22 +0000 (-0500) Subject: re PR c++/67364 ("accessing uninitialized member" error in constexpr context) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d96e840784d5c589120b9df69536097e5d15ec39;p=gcc.git re PR c++/67364 ("accessing uninitialized member" error in constexpr context) PR c++/67364 * constexpr.c (cxx_eval_store_expression): Replace CONSTRUCTOR_ELTS in nested CONSTRUCTORs, too. From-SVN: r234013 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0ef1ac744ad..a803ec98486 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-03-05 Jason Merrill + + PR c++/67364 + * constexpr.c (cxx_eval_store_expression): Replace + CONSTRUCTOR_ELTS in nested CONSTRUCTORs, too. + 2016-03-05 Patrick Palka PR c++/66786 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index c9f9c47472f..f23e7c91755 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2939,39 +2939,34 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, /* Don't share a CONSTRUCTOR that might be changed later. */ init = unshare_expr (init); if (target == object) + /* The hash table might have moved since the get earlier. */ + valp = ctx->values->get (object); + + if (TREE_CODE (init) == CONSTRUCTOR) { - /* The hash table might have moved since the get earlier. */ - valp = ctx->values->get (object); - if (TREE_CODE (init) == CONSTRUCTOR) - { - /* An outer ctx->ctor might be pointing to *valp, so replace - its contents. */ - CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init); - TREE_CONSTANT (*valp) = TREE_CONSTANT (init); - TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init); - } - else - *valp = init; + /* An outer ctx->ctor might be pointing to *valp, so replace + its contents. */ + CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init); + TREE_CONSTANT (*valp) = TREE_CONSTANT (init); + TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init); } else - { - *valp = init; - - /* Update TREE_CONSTANT and TREE_SIDE_EFFECTS on enclosing - CONSTRUCTORs. */ - tree elt; - unsigned i; - bool c = TREE_CONSTANT (init); - bool s = TREE_SIDE_EFFECTS (init); - if (!c || s) - FOR_EACH_VEC_SAFE_ELT (ctors, i, elt) - { - if (!c) - TREE_CONSTANT (elt) = false; - if (s) - TREE_SIDE_EFFECTS (elt) = true; - } - } + *valp = init; + + /* Update TREE_CONSTANT and TREE_SIDE_EFFECTS on enclosing + CONSTRUCTORs, if any. */ + tree elt; + unsigned i; + bool c = TREE_CONSTANT (init); + bool s = TREE_SIDE_EFFECTS (init); + if (!c || s) + FOR_EACH_VEC_SAFE_ELT (ctors, i, elt) + { + if (!c) + TREE_CONSTANT (elt) = false; + if (s) + TREE_SIDE_EFFECTS (elt) = true; + } release_tree_vector (ctors); if (*non_constant_p) diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-aggr3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-aggr3.C new file mode 100644 index 00000000000..547dec4c97e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-aggr3.C @@ -0,0 +1,30 @@ +// PR c++/67364 +// { dg-do compile { target c++11 } } + +template +struct tuple { + Xn storage_; + + constexpr tuple(Xn const& xn) + : storage_(xn) + { } + + template + constexpr tuple(tuple const& other) + : storage_(other.storage_) + { } + + template + constexpr tuple(tuple& other) + : tuple(const_cast(other)) + { } +}; + +template +struct wrapper { T value; }; + +template +constexpr wrapper wrap(T t) { return {t}; } + +constexpr wrapper> t = wrap(tuple{2}); +static_assert(t.value.storage_ == 2, "");