From 27afd940ce6d91b1bf91f12f833ffce459919af6 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 5 Oct 2016 18:57:58 -0400 Subject: [PATCH] * call.c (extend_ref_init_temps): Fix TARGET_EXPR handling. From-SVN: r240818 --- gcc/cp/ChangeLog | 2 ++ gcc/cp/call.c | 31 ++++++++++++++++------------- gcc/testsuite/g++.dg/cpp1z/elide2.C | 25 +++++++++++++++++++++++ 3 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/elide2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e95faf65e92..f8752a6911c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,7 @@ 2016-10-05 Jason Merrill + * call.c (extend_ref_init_temps): Fix TARGET_EXPR handling. + * parser.c (cp_parser_skip_to_end_of_statement): Add missing break. * semantics.c (finish_compound_literal): Handle class placeholder. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 0914ae2a0f3..c33341813cf 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -10172,28 +10172,31 @@ extend_ref_init_temps (tree decl, tree init, vec **cleanups) return init; if (TREE_CODE (type) == REFERENCE_TYPE) init = extend_ref_init_temps_1 (decl, init, cleanups); - else if (is_std_init_list (type)) + else { - /* The temporary array underlying a std::initializer_list - is handled like a reference temporary. */ tree ctor = init; if (TREE_CODE (ctor) == TARGET_EXPR) ctor = TARGET_EXPR_INITIAL (ctor); if (TREE_CODE (ctor) == CONSTRUCTOR) { - tree array = CONSTRUCTOR_ELT (ctor, 0)->value; - array = extend_ref_init_temps_1 (decl, array, cleanups); - CONSTRUCTOR_ELT (ctor, 0)->value = array; + if (is_std_init_list (type)) + { + /* The temporary array underlying a std::initializer_list + is handled like a reference temporary. */ + tree array = CONSTRUCTOR_ELT (ctor, 0)->value; + array = extend_ref_init_temps_1 (decl, array, cleanups); + CONSTRUCTOR_ELT (ctor, 0)->value = array; + } + else + { + unsigned i; + constructor_elt *p; + vec *elts = CONSTRUCTOR_ELTS (ctor); + FOR_EACH_VEC_SAFE_ELT (elts, i, p) + p->value = extend_ref_init_temps (decl, p->value, cleanups); + } } } - else if (TREE_CODE (init) == CONSTRUCTOR) - { - unsigned i; - constructor_elt *p; - vec *elts = CONSTRUCTOR_ELTS (init); - FOR_EACH_VEC_SAFE_ELT (elts, i, p) - p->value = extend_ref_init_temps (decl, p->value, cleanups); - } return init; } diff --git a/gcc/testsuite/g++.dg/cpp1z/elide2.C b/gcc/testsuite/g++.dg/cpp1z/elide2.C new file mode 100644 index 00000000000..277decff487 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/elide2.C @@ -0,0 +1,25 @@ +// DR 1697 +// { dg-do run { target c++11 } } + +#define assert(X) do { if (!(X)) __builtin_abort(); } while(0) + +int i; +struct S { + ~S() { assert (i++ == 2); } +}; +struct X { + X() { assert (i++ == 0); } + X(const X&); +}; +struct T { + S &&s; + X x; +}; +void f() { assert (i++ == 1); } +int main() { + { + T t = T{ {}, {} }; + f(); + } + assert (i == 3); +} -- 2.30.2