re PR c++/5636 (gcc-3.0.3, memory leakage: function that take a string as parameter will not call local variable destructors if exception is thrown.)
PR c++/5636 * tree.h (CLEANUP_EH_ONLY): New macro. * stmt.c (expand_decl_cleanup_eh): New fn. (expand_cleanups): Check CLEANUP_EH_ONLY. * c-semantics.c (genrtl_decl_cleanup): Just take the CLEANUP_STMT. Use expand_decl_cleanup_eh. (expand_stmt): Adjust. * c-common.h: Adjust prototype. * cp/semantics.c (nullify_returns_r): Just set CLEANUP_EH_ONLY on cleanup for nrv. From-SVN: r51826
This commit is contained in:
parent
933d821b1f
commit
661b5652b9
|
@ -1,3 +1,14 @@
|
|||
2002-04-03 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/5636
|
||||
* tree.h (CLEANUP_EH_ONLY): New macro.
|
||||
* stmt.c (expand_decl_cleanup_eh): New fn.
|
||||
(expand_cleanups): Check CLEANUP_EH_ONLY.
|
||||
* c-semantics.c (genrtl_decl_cleanup): Just take the CLEANUP_STMT.
|
||||
Use expand_decl_cleanup_eh.
|
||||
(expand_stmt): Adjust.
|
||||
* c-common.h: Adjust prototype.
|
||||
|
||||
2002-04-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* configure.in (HAVE_SPARC_UA_PCREL_HIDDEN): Test whether %r_disp32()
|
||||
|
|
|
@ -759,7 +759,7 @@ extern void genrtl_compound_stmt PARAMS ((tree));
|
|||
extern void genrtl_asm_stmt PARAMS ((tree, tree,
|
||||
tree, tree,
|
||||
tree, int));
|
||||
extern void genrtl_decl_cleanup PARAMS ((tree, tree));
|
||||
extern void genrtl_decl_cleanup PARAMS ((tree));
|
||||
extern int stmts_are_full_exprs_p PARAMS ((void));
|
||||
extern int anon_aggr_type_p PARAMS ((tree));
|
||||
|
||||
|
|
|
@ -737,12 +737,12 @@ genrtl_asm_stmt (cv_qualifier, string, output_operands,
|
|||
/* Generate the RTL for a DECL_CLEANUP. */
|
||||
|
||||
void
|
||||
genrtl_decl_cleanup (decl, cleanup)
|
||||
tree decl;
|
||||
tree cleanup;
|
||||
genrtl_decl_cleanup (t)
|
||||
tree t;
|
||||
{
|
||||
tree decl = CLEANUP_DECL (t);
|
||||
if (!decl || (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node))
|
||||
expand_decl_cleanup (decl, cleanup);
|
||||
expand_decl_cleanup_eh (decl, CLEANUP_EXPR (t), CLEANUP_EH_ONLY (t));
|
||||
}
|
||||
|
||||
/* We're about to expand T, a statement. Set up appropriate context
|
||||
|
@ -848,7 +848,7 @@ expand_stmt (t)
|
|||
break;
|
||||
|
||||
case CLEANUP_STMT:
|
||||
genrtl_decl_cleanup (CLEANUP_DECL (t), CLEANUP_EXPR (t));
|
||||
genrtl_decl_cleanup (t);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
2002-04-03 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/5636
|
||||
* semantics.c (nullify_returns_r): Just set CLEANUP_EH_ONLY on
|
||||
cleanup for nrv.
|
||||
|
||||
PR c++/5104
|
||||
* typeck.c (comptypes) [FUNCTION_TYPE]: Don't compare exception
|
||||
specifiers.
|
||||
|
|
|
@ -2453,7 +2453,7 @@ nullify_returns_r (tp, walk_subtrees, data)
|
|||
RETURN_EXPR (*tp) = NULL_TREE;
|
||||
else if (TREE_CODE (*tp) == CLEANUP_STMT
|
||||
&& CLEANUP_DECL (*tp) == nrv)
|
||||
CLEANUP_EXPR (*tp) = NULL_TREE;
|
||||
CLEANUP_EH_ONLY (*tp) = 1;
|
||||
|
||||
/* Keep iterating. */
|
||||
return NULL_TREE;
|
||||
|
|
19
gcc/stmt.c
19
gcc/stmt.c
|
@ -4167,6 +4167,23 @@ expand_decl_cleanup (decl, cleanup)
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Like expand_decl_cleanup, but maybe only run the cleanup if an exception
|
||||
is thrown. */
|
||||
|
||||
int
|
||||
expand_decl_cleanup_eh (decl, cleanup, eh_only)
|
||||
tree decl, cleanup;
|
||||
int eh_only;
|
||||
{
|
||||
int ret = expand_decl_cleanup (decl, cleanup);
|
||||
if (cleanup && ret)
|
||||
{
|
||||
tree node = block_stack->data.block.cleanups;
|
||||
CLEANUP_EH_ONLY (node) = eh_only;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* DECL is an anonymous union. CLEANUP is a cleanup for DECL.
|
||||
DECL_ELTS is the list of elements that belong to DECL's type.
|
||||
|
@ -4275,7 +4292,7 @@ expand_cleanups (list, dont_do, in_fixup, reachable)
|
|||
if (! in_fixup && using_eh_for_cleanups_p)
|
||||
expand_eh_region_end_cleanup (TREE_VALUE (tail));
|
||||
|
||||
if (reachable)
|
||||
if (reachable && !CLEANUP_EH_ONLY (tail))
|
||||
{
|
||||
/* Cleanups may be run multiple times. For example,
|
||||
when exiting a binding contour, we expand the
|
||||
|
|
13
gcc/tree.h
13
gcc/tree.h
|
@ -177,6 +177,9 @@ struct tree_common
|
|||
INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST
|
||||
TREE_SYMBOL_REFERENCED in
|
||||
IDENTIFIER_NODE
|
||||
CLEANUP_EH_ONLY in
|
||||
TARGET_EXPR, WITH_CLEANUP_EXPR, CLEANUP_STMT,
|
||||
TREE_LIST elements of a block's cleanup list.
|
||||
|
||||
public_flag:
|
||||
|
||||
|
@ -194,7 +197,7 @@ struct tree_common
|
|||
TREE_VIA_PRIVATE in
|
||||
TREE_LIST or TREE_VEC
|
||||
TREE_PRIVATE in
|
||||
??? unspecified nodes
|
||||
..._DECL
|
||||
|
||||
protected_flag:
|
||||
|
||||
|
@ -203,7 +206,7 @@ struct tree_common
|
|||
TREE_VEC
|
||||
TREE_PROTECTED in
|
||||
BLOCK
|
||||
??? unspecified nodes
|
||||
..._DECL
|
||||
|
||||
side_effects_flag:
|
||||
|
||||
|
@ -503,6 +506,11 @@ extern void tree_class_check_failed PARAMS ((const tree, int,
|
|||
In a CONSTRUCTOR, nonzero means allocate static storage. */
|
||||
#define TREE_STATIC(NODE) ((NODE)->common.static_flag)
|
||||
|
||||
/* In a TARGET_EXPR, WITH_CLEANUP_EXPR, CLEANUP_STMT, or element of a
|
||||
block's cleanup list, means that the pertinent cleanup should only be
|
||||
executed if an exception is thrown, not on normal exit of its scope. */
|
||||
#define CLEANUP_EH_ONLY(NODE) ((NODE)->common.static_flag)
|
||||
|
||||
/* In a CONVERT_EXPR, NOP_EXPR or COMPOUND_EXPR, this means the node was
|
||||
made implicitly and should not lead to an "unused value" warning. */
|
||||
#define TREE_NO_UNUSED_WARNING(NODE) ((NODE)->common.static_flag)
|
||||
|
@ -3082,6 +3090,7 @@ extern void expand_elseif PARAMS ((tree));
|
|||
extern void save_stack_pointer PARAMS ((void));
|
||||
extern void expand_decl PARAMS ((tree));
|
||||
extern int expand_decl_cleanup PARAMS ((tree, tree));
|
||||
extern int expand_decl_cleanup_eh PARAMS ((tree, tree, int));
|
||||
extern void expand_anon_union_decl PARAMS ((tree, tree, tree));
|
||||
extern void move_cleanups_up PARAMS ((void));
|
||||
extern void expand_start_case_dummy PARAMS ((void));
|
||||
|
|
Loading…
Reference in New Issue