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
This commit is contained in:
parent
260e910b11
commit
d96e840784
3 changed files with 60 additions and 29 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
*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;
|
||||
}
|
||||
}
|
||||
/* 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)
|
||||
|
|
30
gcc/testsuite/g++.dg/cpp0x/constexpr-aggr3.C
Normal file
30
gcc/testsuite/g++.dg/cpp0x/constexpr-aggr3.C
Normal file
|
@ -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, "");
|
Loading…
Add table
Reference in a new issue