diff options
author | Jason Merrill <jason@redhat.com> | 2008-01-21 23:53:33 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2008-01-21 23:53:33 -0500 |
commit | 33b45227e0826ce8ddfe659c42f2c35cc0814065 (patch) | |
tree | 1cf758304e987f9c212d745d72e58a7eefe2e85f /gcc/cp | |
parent | 9444edce910401a6aaf7fb7a535d52f6c2780be4 (diff) | |
download | gcc-33b45227e0826ce8ddfe659c42f2c35cc0814065.zip gcc-33b45227e0826ce8ddfe659c42f2c35cc0814065.tar.gz gcc-33b45227e0826ce8ddfe659c42f2c35cc0814065.tar.bz2 |
re PR c++/34196 (uninitialized variable warning in dead exception region)
PR c++/34196
* tree.h (TRY_CATCH_IS_CLEANUP): New macro.
* cp/decl.c (wrap_cleanups_r): Set TRY_CATCH_IS_CLEANUP.
* tree-eh.c (honor_protect_cleanup_actions): Strip TRY_CATCH_EXPR
if it is set.
From-SVN: r131710
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/decl.c | 18 |
2 files changed, 21 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 768efc5..fa48f7c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2008-01-21 Jason Merrill <jason@redhat.com> + + PR c++/34196 + * decl.c (wrap_cleanups_r): Set TRY_CATCH_IS_CLEANUP. + 2008-01-21 Richard Guenther <rguenther@suse.de> PR c++/34850 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 4b2a55f..338e1ed 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5165,7 +5165,10 @@ wrap_cleanups_r (tree *stmt_p, int *walk_subtrees, void *data) tree tcleanup = TARGET_EXPR_CLEANUP (*stmt_p); tcleanup = build2 (TRY_CATCH_EXPR, void_type_node, tcleanup, guard); - + /* Tell honor_protect_cleanup_actions to handle this as a separate + cleanup. */ + TRY_CATCH_IS_CLEANUP (tcleanup) = 1; + TARGET_EXPR_CLEANUP (*stmt_p) = tcleanup; } @@ -5175,7 +5178,18 @@ wrap_cleanups_r (tree *stmt_p, int *walk_subtrees, void *data) /* We're initializing a local variable which has a cleanup GUARD. If there are any temporaries used in the initializer INIT of this variable, we need to wrap their cleanups with TRY_CATCH_EXPR (, GUARD) so that the - variable will be cleaned up properly if one of them throws. */ + variable will be cleaned up properly if one of them throws. + + Unfortunately, there's no way to express this properly in terms of + nesting, as the regions for the temporaries overlap the region for the + variable itself; if there are two temporaries, the variable needs to be + the first thing destroyed if either of them throws. However, we only + want to run the variable's cleanup if it actually got constructed. So + we need to guard the temporary cleanups with the variable's cleanup if + they are run on the normal path, but not if they are run on the + exceptional path. We implement this by telling + honor_protect_cleanup_actions to strip the variable cleanup from the + exceptional path. */ static void wrap_temporary_cleanups (tree init, tree guard) |