mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-08 02:16:49 +08:00
decl.c (grokfndecl): Set TREE_NOTHROW if TYPE_NOTHROW_P.
* decl.c (grokfndecl): Set TREE_NOTHROW if TYPE_NOTHROW_P. * except.c (dtor_nothrow): New fn. (do_pop_exception): Use it. Take type parm. (push_eh_cleanup): Take type parm. (expand_start_catch_block): Pass it. (build_eh_type_type_ref): Accept null type. From-SVN: r32510
This commit is contained in:
parent
a8c73de3a4
commit
93ca4ba766
@ -1,3 +1,13 @@
|
||||
2000-03-13 Jason Merrill <jason@casey.cygnus.com>
|
||||
|
||||
* decl.c (grokfndecl): Set TREE_NOTHROW if TYPE_NOTHROW_P.
|
||||
|
||||
* except.c (dtor_nothrow): New fn.
|
||||
(do_pop_exception): Use it. Take type parm.
|
||||
(push_eh_cleanup): Take type parm.
|
||||
(expand_start_catch_block): Pass it.
|
||||
(build_eh_type_type_ref): Accept null type.
|
||||
|
||||
2000-03-12 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.h (revert_static_member_fn): Change prototype.
|
||||
|
@ -8771,7 +8771,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
|
||||
tentative. error_mark_node is replaced later with the BLOCK. */
|
||||
DECL_INITIAL (decl) = error_mark_node;
|
||||
|
||||
if (nothrow_libfn_p (decl))
|
||||
if (TYPE_NOTHROW_P (type) || nothrow_libfn_p (decl))
|
||||
TREE_NOTHROW (decl) = 1;
|
||||
|
||||
/* Caller will do the rest of this. */
|
||||
|
@ -37,7 +37,7 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "toplev.h"
|
||||
#include "eh-common.h"
|
||||
|
||||
static void push_eh_cleanup PARAMS ((void));
|
||||
static void push_eh_cleanup PARAMS ((tree));
|
||||
static tree build_eh_type_type PARAMS ((tree));
|
||||
static tree call_eh_info PARAMS ((void));
|
||||
static void push_eh_info PARAMS ((void));
|
||||
@ -48,7 +48,8 @@ static tree get_eh_type PARAMS ((void));
|
||||
static tree get_eh_caught PARAMS ((void));
|
||||
static tree get_eh_handlers PARAMS ((void));
|
||||
#endif
|
||||
static tree do_pop_exception PARAMS ((void));
|
||||
static int dtor_nothrow PARAMS ((tree));
|
||||
static tree do_pop_exception PARAMS ((tree));
|
||||
static tree build_eh_type_type_ref PARAMS ((tree));
|
||||
static tree build_terminate_handler PARAMS ((void));
|
||||
static tree alloc_eh_object PARAMS ((tree));
|
||||
@ -356,8 +357,8 @@ build_eh_type_type_ref (type)
|
||||
{
|
||||
tree exp;
|
||||
|
||||
if (type == error_mark_node)
|
||||
return error_mark_node;
|
||||
if (type == NULL_TREE || type == error_mark_node)
|
||||
return type;
|
||||
|
||||
/* peel back references, so they match. */
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
@ -376,6 +377,7 @@ build_eh_type_type_ref (type)
|
||||
/* This routine is called to mark all the symbols representing runtime
|
||||
type functions in the exception table as having been referenced.
|
||||
This will make sure code is emitted for them. Called from finish_file. */
|
||||
|
||||
void
|
||||
mark_all_runtime_matches ()
|
||||
{
|
||||
@ -401,13 +403,32 @@ mark_all_runtime_matches ()
|
||||
free (ptr);
|
||||
}
|
||||
|
||||
/* Returns nonzero if cleaning up an exception of type TYPE (which can be
|
||||
NULL_TREE for a ... handler) will not throw an exception. */
|
||||
|
||||
static int
|
||||
dtor_nothrow (type)
|
||||
tree type;
|
||||
{
|
||||
tree fn;
|
||||
|
||||
if (type == NULL_TREE)
|
||||
return 0;
|
||||
|
||||
if (! TYPE_HAS_DESTRUCTOR (type))
|
||||
return 1;
|
||||
|
||||
fn = lookup_member (type, dtor_identifier, 0, 0);
|
||||
fn = TREE_VALUE (fn);
|
||||
return TREE_NOTHROW (fn);
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
for the current catch block if no others are currently using it. */
|
||||
|
||||
static tree
|
||||
do_pop_exception ()
|
||||
do_pop_exception (type)
|
||||
tree type;
|
||||
{
|
||||
tree fn, cleanup;
|
||||
fn = get_identifier ("__cp_pop_exception");
|
||||
@ -427,15 +448,17 @@ do_pop_exception ()
|
||||
cleanup = lookup_name (get_identifier ("__exception_info"), 0);
|
||||
cleanup = build_function_call (fn, tree_cons
|
||||
(NULL_TREE, cleanup, NULL_TREE));
|
||||
TREE_NOTHROW (cleanup) = dtor_nothrow (type);
|
||||
return cleanup;
|
||||
}
|
||||
|
||||
/* This routine creates the cleanup for the current exception. */
|
||||
|
||||
static void
|
||||
push_eh_cleanup ()
|
||||
push_eh_cleanup (type)
|
||||
tree type;
|
||||
{
|
||||
finish_decl_cleanup (NULL_TREE, do_pop_exception ());
|
||||
finish_decl_cleanup (NULL_TREE, do_pop_exception (type));
|
||||
}
|
||||
|
||||
/* Build up a call to terminate on the function obstack, for use as an
|
||||
@ -587,7 +610,6 @@ expand_start_catch_block (decl)
|
||||
{
|
||||
tree compound_stmt_1;
|
||||
tree compound_stmt_2;
|
||||
tree type;
|
||||
|
||||
if (! doing_eh (1))
|
||||
return NULL_TREE;
|
||||
@ -603,15 +625,16 @@ expand_start_catch_block (decl)
|
||||
if (! decl || ! decl_is_java_type (TREE_TYPE (decl), 1))
|
||||
{
|
||||
/* The ordinary C++ case. */
|
||||
tree type;
|
||||
|
||||
if (decl)
|
||||
type = build_eh_type_type_ref (TREE_TYPE (decl));
|
||||
type = TREE_TYPE (decl);
|
||||
else
|
||||
type = NULL_TREE;
|
||||
begin_catch_block (type);
|
||||
begin_catch_block (build_eh_type_type_ref (type));
|
||||
|
||||
push_eh_info ();
|
||||
push_eh_cleanup ();
|
||||
push_eh_cleanup (type);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user