stmt.c (expand_decl_cleanup_no_eh): New fn.
* stmt.c (expand_decl_cleanup_no_eh): New fn. * except.c (expand_leftover_cleanups): do_pending_stack_adjust. Complete nested exception support. * except.c (do_pop_exception): Split out... (push_eh_cleanup): From here. Handle the EH region by hand. (expand_start_catch_block): Add a new level for the catch parm. Move the rethrow region outside the two cleanup regions. Protect the initializer for the catch parm with terminate. (expand_end_catch_block): Likewise. End the region for the eh_cleanup. * exception.cc (__cp_pop_exception): Now takes two parms. Handle popping off the middle of the stack. * tree.c (lvalue_p, real_lvalue_p): Handle TRY_CATCH_EXPR, WITH_CLEANUP_EXPR, and UNSAVE_EXPR. (build_cplus_new): Only wrap CALL_EXPRs. * init.c (expand_default_init): Handle a TRY_CATCH_EXPR around the constructor call. From-SVN: r16419
This commit is contained in:
parent
26f578a228
commit
c7ae64f2cc
|
@ -1,3 +1,9 @@
|
||||||
|
Mon Nov 10 03:02:19 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||||
|
|
||||||
|
* stmt.c (expand_decl_cleanup_no_eh): New fn.
|
||||||
|
|
||||||
|
* except.c (expand_leftover_cleanups): do_pending_stack_adjust.
|
||||||
|
|
||||||
Mon Nov 10 00:05:56 1997 Jeffrey A Law (law@cygnus.com)
|
Mon Nov 10 00:05:56 1997 Jeffrey A Law (law@cygnus.com)
|
||||||
|
|
||||||
* alias.c (MAX_ALIAS_LOOP_PASSES): Define.
|
* alias.c (MAX_ALIAS_LOOP_PASSES): Define.
|
||||||
|
|
|
@ -4,6 +4,27 @@ Sun Nov 9 01:29:55 1997 Jim Wilson (wilson@cygnus.com)
|
||||||
* init.c (build_vec_delete_1): Delete build_block and
|
* init.c (build_vec_delete_1): Delete build_block and
|
||||||
add_block_current_level calls.
|
add_block_current_level calls.
|
||||||
|
|
||||||
|
Mon Nov 10 03:04:20 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||||
|
|
||||||
|
Complete nested exception support.
|
||||||
|
* except.c (do_pop_exception): Split out...
|
||||||
|
(push_eh_cleanup): From here. Handle the EH region by hand.
|
||||||
|
(expand_start_catch_block): Add a new level for the catch parm.
|
||||||
|
Move the rethrow region outside the two cleanup regions.
|
||||||
|
Protect the initializer for the catch parm with terminate.
|
||||||
|
(expand_end_catch_block): Likewise. End the region for the eh_cleanup.
|
||||||
|
* exception.cc (__cp_pop_exception): Now takes two parms. Handle
|
||||||
|
popping off the middle of the stack.
|
||||||
|
* tree.c (lvalue_p, real_lvalue_p): Handle TRY_CATCH_EXPR,
|
||||||
|
WITH_CLEANUP_EXPR, and UNSAVE_EXPR.
|
||||||
|
(build_cplus_new): Only wrap CALL_EXPRs.
|
||||||
|
* init.c (expand_default_init): Handle a TRY_CATCH_EXPR around
|
||||||
|
the constructor call.
|
||||||
|
|
||||||
|
Sun Nov 9 18:00:26 1997 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||||
|
|
||||||
|
* Make-lang.in (c++.distdir): Make inc subdirectory.
|
||||||
|
|
||||||
Fri Nov 7 11:57:28 1997 Jason Merrill <jason@yorick.cygnus.com>
|
Fri Nov 7 11:57:28 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||||
|
|
||||||
* decl2.c (finish_file): Put back some code.
|
* decl2.c (finish_file): Put back some code.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Top level makefile fragment for GNU C++.
|
# Top level makefile fragment for GNU C++.
|
||||||
# Copyright (C) 1994, 1995 Free Software Foundation, Inc.
|
# Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
|
||||||
|
|
||||||
#This file is part of GNU CC.
|
#This file is part of GNU CC.
|
||||||
|
|
||||||
|
@ -265,8 +265,14 @@ c++.stage4: stage4-start
|
||||||
# distribution anyway. It then copies the files to the distdir directory.
|
# distribution anyway. It then copies the files to the distdir directory.
|
||||||
c++.distdir:
|
c++.distdir:
|
||||||
mkdir tmp/cp
|
mkdir tmp/cp
|
||||||
|
mkdir tmp/cp/inc
|
||||||
cd cp ; $(MAKE) $(FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) parse.c hash.h
|
cd cp ; $(MAKE) $(FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) parse.c hash.h
|
||||||
cd cp; \
|
cd cp; \
|
||||||
for file in *[0-9a-zA-Z+]; do \
|
for file in *[0-9a-zA-Z+]; do \
|
||||||
$(LN) $$file ../tmp/cp; \
|
$(LN) $$file ../tmp/cp; \
|
||||||
done
|
done
|
||||||
|
cd cp/inc; \
|
||||||
|
for file in *[0-9a-zA-Z+]; do \
|
||||||
|
ln $$file ../../tmp/cp/inc >/dev/null 2>&1 \
|
||||||
|
|| cp $$file ../../tmp/cp/inc; \
|
||||||
|
done
|
||||||
|
|
134
gcc/cp/except.c
134
gcc/cp/except.c
|
@ -461,26 +461,31 @@ build_eh_type (exp)
|
||||||
return build_eh_type_type (TREE_TYPE (exp));
|
return build_eh_type_type (TREE_TYPE (exp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This routine creates the cleanup for the current exception. */
|
/* Build up a call to __cp_pop_exception, to destroy the exception object
|
||||||
|
for the current catch block. HANDLER is either true or false, telling
|
||||||
|
the library whether or not it is being called from an exception handler;
|
||||||
|
if it is, it avoids destroying the object on rethrow. */
|
||||||
|
|
||||||
static void
|
static tree
|
||||||
push_eh_cleanup ()
|
do_pop_exception (handler)
|
||||||
|
tree handler;
|
||||||
{
|
{
|
||||||
/* All cleanups must last longer than normal. */
|
|
||||||
int yes = suspend_momentary ();
|
|
||||||
tree fn, cleanup;
|
tree fn, cleanup;
|
||||||
|
|
||||||
fn = get_identifier ("__cp_pop_exception");
|
fn = get_identifier ("__cp_pop_exception");
|
||||||
if (IDENTIFIER_GLOBAL_VALUE (fn))
|
if (IDENTIFIER_GLOBAL_VALUE (fn))
|
||||||
fn = IDENTIFIER_GLOBAL_VALUE (fn);
|
fn = IDENTIFIER_GLOBAL_VALUE (fn);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Declare void __cp_pop_exception (void), as defined in exception.cc. */
|
/* Declare void __cp_pop_exception (void *),
|
||||||
|
as defined in exception.cc. */
|
||||||
push_obstacks_nochange ();
|
push_obstacks_nochange ();
|
||||||
end_temporary_allocation ();
|
end_temporary_allocation ();
|
||||||
fn = build_lang_decl (FUNCTION_DECL, fn,
|
fn = build_lang_decl
|
||||||
build_function_type (void_type_node,
|
(FUNCTION_DECL, fn,
|
||||||
void_list_node));
|
build_function_type (void_type_node, tree_cons
|
||||||
|
(NULL_TREE, ptr_type_node, tree_cons
|
||||||
|
(NULL_TREE, boolean_type_node,
|
||||||
|
void_list_node))));
|
||||||
DECL_EXTERNAL (fn) = 1;
|
DECL_EXTERNAL (fn) = 1;
|
||||||
TREE_PUBLIC (fn) = 1;
|
TREE_PUBLIC (fn) = 1;
|
||||||
DECL_ARTIFICIAL (fn) = 1;
|
DECL_ARTIFICIAL (fn) = 1;
|
||||||
|
@ -491,12 +496,26 @@ push_eh_cleanup ()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Arrange to do a dynamically scoped cleanup upon exit from this region. */
|
/* Arrange to do a dynamically scoped cleanup upon exit from this region. */
|
||||||
cleanup = build_function_call (fn, NULL_TREE);
|
cleanup = lookup_name (get_identifier ("__exception_info"), 0);
|
||||||
expand_decl_cleanup (NULL_TREE, cleanup);
|
cleanup = build_function_call (fn, expr_tree_cons
|
||||||
|
(NULL_TREE, cleanup, expr_tree_cons
|
||||||
resume_momentary (yes);
|
(NULL_TREE, handler, NULL_TREE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This routine creates the cleanup for the current exception. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
push_eh_cleanup ()
|
||||||
|
{
|
||||||
|
/* All cleanups must last longer than normal. */
|
||||||
|
int yes = suspend_momentary ();
|
||||||
|
expand_decl_cleanup_no_eh (NULL_TREE, do_pop_exception (boolean_false_node));
|
||||||
|
resume_momentary (yes);
|
||||||
|
|
||||||
|
/* We don't destroy the exception object on rethrow, so we can't use
|
||||||
|
the normal cleanup mechanism for it. */
|
||||||
|
expand_eh_region_start ();
|
||||||
|
}
|
||||||
|
|
||||||
/* call this to start a catch block. Typename is the typename, and identifier
|
/* call this to start a catch block. Typename is the typename, and identifier
|
||||||
is the variable to place the object in or NULL if the variable doesn't
|
is the variable to place the object in or NULL if the variable doesn't
|
||||||
|
@ -530,7 +549,18 @@ expand_start_catch_block (declspecs, declarator)
|
||||||
if (! doing_eh (1))
|
if (! doing_eh (1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Create a binding level for the parm. */
|
/* If we are not doing setjmp/longjmp EH, because we are reordered
|
||||||
|
out of line, we arrange to rethrow in the outer context so as to
|
||||||
|
skip through the terminate region we are nested in, should we
|
||||||
|
encounter an exception in the catch handler. We also need to do
|
||||||
|
this because we are not physically within the try block, if any,
|
||||||
|
that contains this catch block.
|
||||||
|
|
||||||
|
Matches the end in expand_end_catch_block. */
|
||||||
|
expand_eh_region_start ();
|
||||||
|
|
||||||
|
/* Create a binding level for the eh_info and the exception object
|
||||||
|
cleanup. */
|
||||||
pushlevel (0);
|
pushlevel (0);
|
||||||
expand_start_bindings (0);
|
expand_start_bindings (0);
|
||||||
|
|
||||||
|
@ -543,23 +573,17 @@ expand_start_catch_block (declspecs, declarator)
|
||||||
|
|
||||||
if (declspecs)
|
if (declspecs)
|
||||||
{
|
{
|
||||||
tree exp;
|
|
||||||
rtx call_rtx, return_value_rtx;
|
|
||||||
tree init_type;
|
|
||||||
|
|
||||||
decl = grokdeclarator (declarator, declspecs, CATCHPARM, 1, NULL_TREE);
|
decl = grokdeclarator (declarator, declspecs, CATCHPARM, 1, NULL_TREE);
|
||||||
|
|
||||||
if (decl == NULL_TREE)
|
if (decl == NULL_TREE)
|
||||||
{
|
error ("invalid catch parameter");
|
||||||
error ("invalid catch parameter");
|
}
|
||||||
|
|
||||||
/* This is cheap, but we want to maintain the data
|
if (decl)
|
||||||
structures. */
|
{
|
||||||
|
tree exp;
|
||||||
expand_eh_region_start ();
|
rtx call_rtx, return_value_rtx;
|
||||||
|
tree init_type;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure we mark the catch param as used, otherwise we'll get
|
/* Make sure we mark the catch param as used, otherwise we'll get
|
||||||
a warning about an unused ((anonymous)). */
|
a warning about an unused ((anonymous)). */
|
||||||
|
@ -592,37 +616,44 @@ expand_start_catch_block (declspecs, declarator)
|
||||||
|
|
||||||
push_eh_cleanup ();
|
push_eh_cleanup ();
|
||||||
|
|
||||||
init = convert_from_reference (save_expr (make_tree (init_type, call_rtx)));
|
/* Create a binding level for the parm. */
|
||||||
|
pushlevel (0);
|
||||||
|
expand_start_bindings (0);
|
||||||
|
|
||||||
|
init = convert_from_reference (make_tree (init_type, call_rtx));
|
||||||
|
|
||||||
|
/* If the constructor for the catch parm exits via an exception, we
|
||||||
|
must call terminate. See eh23.C. */
|
||||||
|
if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
|
||||||
|
{
|
||||||
|
/* Generate the copy constructor call directly so we can wrap it.
|
||||||
|
See also expand_default_init. */
|
||||||
|
init = ocp_convert (TREE_TYPE (decl), init,
|
||||||
|
CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
|
||||||
|
init = build (TRY_CATCH_EXPR, TREE_TYPE (init), init,
|
||||||
|
TerminateFunctionCall);
|
||||||
|
}
|
||||||
|
|
||||||
/* Do we need the below two lines? */
|
|
||||||
/* Let `cp_finish_decl' know that this initializer is ok. */
|
/* Let `cp_finish_decl' know that this initializer is ok. */
|
||||||
DECL_INITIAL (decl) = init;
|
DECL_INITIAL (decl) = init;
|
||||||
decl = pushdecl (decl);
|
decl = pushdecl (decl);
|
||||||
|
|
||||||
cp_finish_decl (decl, init, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
|
cp_finish_decl (decl, init, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
push_eh_cleanup ();
|
push_eh_cleanup ();
|
||||||
|
|
||||||
|
/* Create a binding level for the parm. */
|
||||||
|
pushlevel (0);
|
||||||
|
expand_start_bindings (0);
|
||||||
|
|
||||||
/* Fall into the catch all section. */
|
/* Fall into the catch all section. */
|
||||||
}
|
}
|
||||||
|
|
||||||
init = build_modify_expr (get_eh_caught (), NOP_EXPR, integer_one_node);
|
init = build_modify_expr (get_eh_caught (), NOP_EXPR, integer_one_node);
|
||||||
expand_expr (init, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
expand_expr (init, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||||
|
|
||||||
/* If we are not doing setjmp/longjmp EH, because we are reordered
|
|
||||||
out of line, we arrange to rethrow in the outer context so as to
|
|
||||||
skip through the terminate region we are nested in, should we
|
|
||||||
encounter an exception in the catch handler.
|
|
||||||
|
|
||||||
If we are doing setjmp/longjmp EH, we need to skip through the EH
|
|
||||||
object cleanup region. This isn't quite right, as we really need
|
|
||||||
to clean the object up, but we cannot do that until we track
|
|
||||||
multiple EH objects.
|
|
||||||
|
|
||||||
Matches the end in expand_end_catch_block. */
|
|
||||||
expand_eh_region_start ();
|
|
||||||
|
|
||||||
emit_line_note (input_filename, lineno);
|
emit_line_note (input_filename, lineno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,6 +673,17 @@ expand_end_catch_block ()
|
||||||
if (! doing_eh (1))
|
if (! doing_eh (1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Cleanup the EH parameter. */
|
||||||
|
expand_end_bindings (getdecls (), kept_level_p (), 0);
|
||||||
|
poplevel (kept_level_p (), 1, 0);
|
||||||
|
|
||||||
|
/* Matches push_eh_cleanup. */
|
||||||
|
expand_eh_region_end (do_pop_exception (boolean_true_node));
|
||||||
|
|
||||||
|
/* Cleanup the EH object. */
|
||||||
|
expand_end_bindings (getdecls (), kept_level_p (), 0);
|
||||||
|
poplevel (kept_level_p (), 1, 0);
|
||||||
|
|
||||||
t = make_node (RTL_EXPR);
|
t = make_node (RTL_EXPR);
|
||||||
TREE_TYPE (t) = void_type_node;
|
TREE_TYPE (t) = void_type_node;
|
||||||
RTL_EXPR_RTL (t) = const0_rtx;
|
RTL_EXPR_RTL (t) = const0_rtx;
|
||||||
|
@ -672,7 +714,7 @@ expand_end_catch_block ()
|
||||||
RTL_EXPR_SEQUENCE (t) = get_insns ();
|
RTL_EXPR_SEQUENCE (t) = get_insns ();
|
||||||
end_sequence ();
|
end_sequence ();
|
||||||
|
|
||||||
/* Matches the start in expand_start_catch_block. */
|
/* For the rethrow region. */
|
||||||
expand_eh_region_end (t);
|
expand_eh_region_end (t);
|
||||||
|
|
||||||
/* Fall to outside the try statement when done executing handler and
|
/* Fall to outside the try statement when done executing handler and
|
||||||
|
@ -682,10 +724,6 @@ expand_end_catch_block ()
|
||||||
|
|
||||||
expand_leftover_cleanups ();
|
expand_leftover_cleanups ();
|
||||||
|
|
||||||
/* Cleanup the EH parameter. */
|
|
||||||
expand_end_bindings (getdecls (), kept_level_p (), 0);
|
|
||||||
poplevel (kept_level_p (), 1, 0);
|
|
||||||
|
|
||||||
/* label we emit to jump to if this catch block didn't match. */
|
/* label we emit to jump to if this catch block didn't match. */
|
||||||
/* This the closing } in the `if (eq) {' of the documentation. */
|
/* This the closing } in the `if (eq) {' of the documentation. */
|
||||||
emit_label (pop_label_entry (&false_label_stack));
|
emit_label (pop_label_entry (&false_label_stack));
|
||||||
|
|
|
@ -118,12 +118,26 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compiler hook to pop an exception that has been finalized. Used by
|
/* Compiler hook to pop an exception that has been finalized. Used by
|
||||||
push_eh_cleanup(). */
|
push_eh_cleanup(). P is the info for the exception caught by the
|
||||||
|
current catch block, and HANDLER determines if we've been called from
|
||||||
|
an exception handler; if so, we avoid destroying the object on rethrow. */
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
__cp_pop_exception (void)
|
__cp_pop_exception (cp_eh_info *p, bool handler)
|
||||||
{
|
{
|
||||||
cp_eh_info *p = __eh_info;
|
cp_eh_info **q = &__eh_info;
|
||||||
|
|
||||||
|
if (handler && p == *q)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (; *q; q = &((*q)->next))
|
||||||
|
if (*q == p)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (! *q)
|
||||||
|
terminate ();
|
||||||
|
|
||||||
|
*q = p->next;
|
||||||
|
|
||||||
if (p->cleanup)
|
if (p->cleanup)
|
||||||
/* 3 is a magic value for destructors; see build_delete(). */
|
/* 3 is a magic value for destructors; see build_delete(). */
|
||||||
|
@ -133,7 +147,6 @@ __cp_pop_exception (void)
|
||||||
else
|
else
|
||||||
delete p->value;
|
delete p->value;
|
||||||
|
|
||||||
__eh_info = p->next;
|
|
||||||
delete p;
|
delete p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1266,7 +1266,17 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags)
|
||||||
&& TREE_CODE (init) == TARGET_EXPR && TREE_TYPE (init) == type))
|
&& TREE_CODE (init) == TARGET_EXPR && TREE_TYPE (init) == type))
|
||||||
init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
|
init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
|
||||||
|
|
||||||
expand_assignment (exp, init, 0, 0);
|
if (TREE_CODE (init) == TRY_CATCH_EXPR)
|
||||||
|
/* We need to protect the initialization of a catch parm
|
||||||
|
with a call to terminate(), which shows up as a TRY_CATCH_EXPR
|
||||||
|
around the TARGET_EXPR for the copy constructor. See
|
||||||
|
expand_start_catch_block. */
|
||||||
|
TREE_OPERAND (init, 0) = build (INIT_EXPR, TREE_TYPE (exp), exp,
|
||||||
|
TREE_OPERAND (init, 0));
|
||||||
|
else
|
||||||
|
init = build (INIT_EXPR, TREE_TYPE (exp), exp, init);
|
||||||
|
TREE_SIDE_EFFECTS (init) = 1;
|
||||||
|
expand_expr_stmt (init);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,9 @@ real_lvalue_p (ref)
|
||||||
case PREDECREMENT_EXPR:
|
case PREDECREMENT_EXPR:
|
||||||
case COMPONENT_REF:
|
case COMPONENT_REF:
|
||||||
case SAVE_EXPR:
|
case SAVE_EXPR:
|
||||||
|
case UNSAVE_EXPR:
|
||||||
|
case TRY_CATCH_EXPR:
|
||||||
|
case WITH_CLEANUP_EXPR:
|
||||||
return real_lvalue_p (TREE_OPERAND (ref, 0));
|
return real_lvalue_p (TREE_OPERAND (ref, 0));
|
||||||
|
|
||||||
case STRING_CST:
|
case STRING_CST:
|
||||||
|
@ -152,6 +155,9 @@ lvalue_p (ref)
|
||||||
case IMAGPART_EXPR:
|
case IMAGPART_EXPR:
|
||||||
case COMPONENT_REF:
|
case COMPONENT_REF:
|
||||||
case SAVE_EXPR:
|
case SAVE_EXPR:
|
||||||
|
case UNSAVE_EXPR:
|
||||||
|
case TRY_CATCH_EXPR:
|
||||||
|
case WITH_CLEANUP_EXPR:
|
||||||
return lvalue_p (TREE_OPERAND (ref, 0));
|
return lvalue_p (TREE_OPERAND (ref, 0));
|
||||||
|
|
||||||
case STRING_CST:
|
case STRING_CST:
|
||||||
|
@ -238,7 +244,7 @@ build_cplus_new (type, init)
|
||||||
tree slot;
|
tree slot;
|
||||||
tree rval;
|
tree rval;
|
||||||
|
|
||||||
if (TREE_CODE (init) == TARGET_EXPR || init == error_mark_node)
|
if (TREE_CODE (init) != CALL_EXPR && TREE_CODE (init) != NEW_EXPR)
|
||||||
return init;
|
return init;
|
||||||
|
|
||||||
slot = build (VAR_DECL, type);
|
slot = build (VAR_DECL, type);
|
||||||
|
|
|
@ -1224,6 +1224,7 @@ expand_leftover_cleanups ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_pending_stack_adjust ();
|
||||||
free (entry);
|
free (entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
13
gcc/stmt.c
13
gcc/stmt.c
|
@ -4012,6 +4012,19 @@ expand_decl_cleanup (decl, cleanup)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Like expand_decl_cleanup, but suppress generating an exception handler
|
||||||
|
to perform the cleanup. */
|
||||||
|
|
||||||
|
int
|
||||||
|
expand_decl_cleanup_no_eh (decl, cleanup)
|
||||||
|
tree decl, cleanup;
|
||||||
|
{
|
||||||
|
int save_eh = using_eh_for_cleanups_p;
|
||||||
|
using_eh_for_cleanups_p = 0;
|
||||||
|
expand_decl_cleanup (decl, cleanup);
|
||||||
|
using_eh_for_cleanups_p = save_eh;
|
||||||
|
}
|
||||||
|
|
||||||
/* Arrange for the top element of the dynamic cleanup chain to be
|
/* Arrange for the top element of the dynamic cleanup chain to be
|
||||||
popped if we exit the current binding contour. DECL is the
|
popped if we exit the current binding contour. DECL is the
|
||||||
associated declaration, if any, otherwise NULL_TREE. If the
|
associated declaration, if any, otherwise NULL_TREE. If the
|
||||||
|
|
Loading…
Reference in New Issue