diff options
author | Jason Merrill <jason@redhat.com> | 2016-03-06 01:47:22 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-03-06 01:47:22 -0500 |
commit | d96e840784d5c589120b9df69536097e5d15ec39 (patch) | |
tree | edb4359b26a408a79a4116b98ba144fdba93bd74 | |
parent | 260e910b1155c0f6c524b8d4e07a9414bd227d6f (diff) | |
download | gcc-d96e840784d5c589120b9df69536097e5d15ec39.zip gcc-d96e840784d5c589120b9df69536097e5d15ec39.tar.gz gcc-d96e840784d5c589120b9df69536097e5d15ec39.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 55 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-aggr3.C | 30 |
3 files changed, 61 insertions, 30 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0ef1ac7..a803ec9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-03-05 Jason Merrill <jason@redhat.com> + + PR c++/67364 + * constexpr.c (cxx_eval_store_expression): Replace + CONSTRUCTOR_ELTS in nested CONSTRUCTORs, too. + 2016-03-05 Patrick Palka <ppalka@gcc.gnu.org> PR c++/66786 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index c9f9c47..f23e7c9 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 0000000..547dec4 --- /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 <typename Xn> +struct tuple { + Xn storage_; + + constexpr tuple(Xn const& xn) + : storage_(xn) + { } + + template <typename ...dummy> + constexpr tuple(tuple const& other) + : storage_(other.storage_) + { } + + template <typename ...dummy> + constexpr tuple(tuple& other) + : tuple(const_cast<tuple const&>(other)) + { } +}; + +template <typename T> +struct wrapper { T value; }; + +template <typename T> +constexpr wrapper<T> wrap(T t) { return {t}; } + +constexpr wrapper<tuple<int>> t = wrap(tuple<int>{2}); +static_assert(t.value.storage_ == 2, ""); |