diff options
author | Jason Merrill <jason@redhat.com> | 2016-10-05 18:57:58 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-10-05 18:57:58 -0400 |
commit | 27afd940ce6d91b1bf91f12f833ffce459919af6 (patch) | |
tree | 97b38ae6b43e3b176785dffd9d9739637daa0052 /gcc | |
parent | eee8f0b07f845f17e89b1e38711910fc8339139f (diff) | |
download | gcc-27afd940ce6d91b1bf91f12f833ffce459919af6.zip gcc-27afd940ce6d91b1bf91f12f833ffce459919af6.tar.gz gcc-27afd940ce6d91b1bf91f12f833ffce459919af6.tar.bz2 |
* call.c (extend_ref_init_temps): Fix TARGET_EXPR handling.
From-SVN: r240818
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/cp/call.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/elide2.C | 25 |
3 files changed, 44 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e95faf6..f8752a6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,7 @@ 2016-10-05 Jason Merrill <jason@redhat.com> + * 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 0914ae2..c333418 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -10172,28 +10172,31 @@ extend_ref_init_temps (tree decl, tree init, vec<tree, va_gc> **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<constructor_elt, va_gc> *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<constructor_elt, va_gc> *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 0000000..277decf --- /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); +} |