mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-22 19:41:06 +08:00
re PR c++/57510 (subobjects not destroyed when exception thrown during list-initialization)
PR c++/57510 * typeck2.c (split_nonconstant_init_1): Handle arrays here. (store_init_value): Not here. (split_nonconstant_init): Look through TARGET_EXPR. No longer static. * cp-tree.h: Declare split_nonconstant_init. * call.c (set_up_extended_ref_temp): Use split_nonconstant_init. From-SVN: r218653
This commit is contained in:
parent
923e09ee92
commit
89631a4336
@ -1,3 +1,12 @@
|
||||
2014-12-11 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/57510
|
||||
* typeck2.c (split_nonconstant_init_1): Handle arrays here.
|
||||
(store_init_value): Not here.
|
||||
(split_nonconstant_init): Look through TARGET_EXPR. No longer static.
|
||||
* cp-tree.h: Declare split_nonconstant_init.
|
||||
* call.c (set_up_extended_ref_temp): Use split_nonconstant_init.
|
||||
|
||||
2014-12-11 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
* typeck.c (maybe_warn_about_useless_cast): Remove unnecessary
|
||||
|
@ -9574,7 +9574,7 @@ set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups,
|
||||
else
|
||||
/* Create the INIT_EXPR that will initialize the temporary
|
||||
variable. */
|
||||
init = build2 (INIT_EXPR, type, var, expr);
|
||||
init = split_nonconstant_init (var, expr);
|
||||
if (at_function_scope_p ())
|
||||
{
|
||||
add_decl_expr (var);
|
||||
|
@ -6291,6 +6291,7 @@ extern int abstract_virtuals_error_sfinae (tree, tree, tsubst_flags_t);
|
||||
extern int abstract_virtuals_error_sfinae (abstract_class_use, tree, tsubst_flags_t);
|
||||
|
||||
extern tree store_init_value (tree, tree, vec<tree, va_gc>**, int);
|
||||
extern tree split_nonconstant_init (tree, tree);
|
||||
extern bool check_narrowing (tree, tree, tsubst_flags_t);
|
||||
extern tree digest_init (tree, tree, tsubst_flags_t);
|
||||
extern tree digest_init_flags (tree, tree, int);
|
||||
|
@ -604,6 +604,17 @@ split_nonconstant_init_1 (tree dest, tree init)
|
||||
case ARRAY_TYPE:
|
||||
inner_type = TREE_TYPE (type);
|
||||
array_type_p = true;
|
||||
if ((TREE_SIDE_EFFECTS (init)
|
||||
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
|
||||
|| array_of_runtime_bound_p (type))
|
||||
{
|
||||
/* For an array, we only need/want a single cleanup region rather
|
||||
than one per element. */
|
||||
tree code = build_vec_init (dest, NULL_TREE, init, false, 1,
|
||||
tf_warning_or_error);
|
||||
add_stmt (code);
|
||||
return true;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
|
||||
case RECORD_TYPE:
|
||||
@ -721,11 +732,13 @@ split_nonconstant_init_1 (tree dest, tree init)
|
||||
perform the non-constant part of the initialization to DEST.
|
||||
Returns the code for the runtime init. */
|
||||
|
||||
static tree
|
||||
tree
|
||||
split_nonconstant_init (tree dest, tree init)
|
||||
{
|
||||
tree code;
|
||||
|
||||
if (TREE_CODE (init) == TARGET_EXPR)
|
||||
init = TARGET_EXPR_INITIAL (init);
|
||||
if (TREE_CODE (init) == CONSTRUCTOR)
|
||||
{
|
||||
code = push_stmt_list ();
|
||||
@ -830,17 +843,7 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
|
||||
&& (TREE_SIDE_EFFECTS (value)
|
||||
|| array_of_runtime_bound_p (type)
|
||||
|| ! reduced_constant_expression_p (value)))
|
||||
{
|
||||
if (TREE_CODE (type) == ARRAY_TYPE
|
||||
&& (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (type))
|
||||
|| array_of_runtime_bound_p (type)))
|
||||
/* For an array, we only need/want a single cleanup region rather
|
||||
than one per element. */
|
||||
return build_vec_init (decl, NULL_TREE, value, false, 1,
|
||||
tf_warning_or_error);
|
||||
else
|
||||
return split_nonconstant_init (decl, value);
|
||||
}
|
||||
return split_nonconstant_init (decl, value);
|
||||
/* If the value is a constant, just put it in DECL_INITIAL. If DECL
|
||||
is an automatic variable, the middle end will turn this into a
|
||||
dynamic initialization later. */
|
||||
|
35
gcc/testsuite/g++.dg/cpp0x/initlist90.C
Normal file
35
gcc/testsuite/g++.dg/cpp0x/initlist90.C
Normal file
@ -0,0 +1,35 @@
|
||||
// PR c++/57510
|
||||
// { dg-do run { target c++11 } }
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
struct counter
|
||||
{
|
||||
static int n;
|
||||
|
||||
counter() { ++n; }
|
||||
counter(const counter&) { ++n; }
|
||||
~counter() { --n; }
|
||||
};
|
||||
|
||||
int counter::n = 0;
|
||||
|
||||
struct X
|
||||
{
|
||||
X () { if (counter::n > 1) throw 1; }
|
||||
|
||||
counter c;
|
||||
};
|
||||
|
||||
int main ()
|
||||
{
|
||||
try
|
||||
{
|
||||
auto x = { X{}, X{} };
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if ( counter::n != 0 )
|
||||
throw;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user