* call.c (extend_ref_init_temps): Fix TARGET_EXPR handling.

From-SVN: r240818
This commit is contained in:
Jason Merrill 2016-10-05 18:57:58 -04:00 committed by Jason Merrill
parent eee8f0b07f
commit 27afd940ce
3 changed files with 44 additions and 14 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -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);
}