cp-tree.h (calls_setjmp_p): Declare.
* cp-tree.h (calls_setjmp_p): Declare. * decl.c (finish_function): Mark functions that call setjmp as uninlinable. * optimize.c (calls_setjmp_r): New function. (calls_setjmp_p): Likewise. From-SVN: r30789
This commit is contained in:
parent
3a8c995be7
commit
95fabfd362
4 changed files with 58 additions and 0 deletions
|
@ -1,3 +1,11 @@
|
|||
1999-12-05 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.h (calls_setjmp_p): Declare.
|
||||
* decl.c (finish_function): Mark functions that call setjmp as
|
||||
uninlinable.
|
||||
* optimize.c (calls_setjmp_r): New function.
|
||||
(calls_setjmp_p): Likewise.
|
||||
|
||||
1999-12-04 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* optimize.c (expand_call_inline): Wrap the expanded call in an
|
||||
|
|
|
@ -3777,6 +3777,7 @@ extern tree get_id_2 PROTO((const char *, tree));
|
|||
|
||||
/* In optimize.c */
|
||||
extern void optimize_function PROTO((tree));
|
||||
extern int calls_setjmp_p PROTO((tree));
|
||||
|
||||
/* in pt.c */
|
||||
extern void init_pt PROTO ((void));
|
||||
|
|
|
@ -13664,6 +13664,18 @@ finish_function (lineno, flags)
|
|||
if (!expanding_p && !processing_template_decl)
|
||||
save_function_data (fndecl);
|
||||
|
||||
/* If this function calls `setjmp' it cannot be inlined. When
|
||||
`longjmp' is called it is not guaranteed to restore the value of
|
||||
local variables that have been modified since the call to
|
||||
`setjmp'. So, if were to inline this function into some caller
|
||||
`c', then when we `longjmp', we might not restore all variables
|
||||
in `c'. (It might seem, at first blush, that there's no way for
|
||||
this function to modify local variables in `c', but their
|
||||
addresses may have been stored somewhere accessible to this
|
||||
function.) */
|
||||
if (!expanding_p && !processing_template_decl && calls_setjmp_p (fndecl))
|
||||
DECL_UNINLINABLE (fndecl) = 1;
|
||||
|
||||
if (expand_p)
|
||||
{
|
||||
int returns_null;
|
||||
|
|
|
@ -77,6 +77,7 @@ static int inlinable_function_p PROTO((tree, inline_data *));
|
|||
static tree remap_decl PROTO((tree, inline_data *));
|
||||
static void remap_block PROTO((tree, tree, inline_data *));
|
||||
static void copy_scope_stmt PROTO((tree *, int *, inline_data *));
|
||||
static tree calls_setjmp_r PROTO((tree *, int *, void *));
|
||||
|
||||
/* Remap DECL during the copying of the BLOCK tree for the function.
|
||||
DATA is really an `inline_data *'. */
|
||||
|
@ -720,3 +721,39 @@ optimize_function (fn)
|
|||
VARRAY_FREE (id.fns);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called from calls_setjmp_p via walk_tree. */
|
||||
|
||||
static tree
|
||||
calls_setjmp_r (tp, walk_subtrees, data)
|
||||
tree *tp;
|
||||
int *walk_subtrees ATTRIBUTE_UNUSED;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
int setjmp_p;
|
||||
int longjmp_p;
|
||||
int malloc_p;
|
||||
int alloca_p;
|
||||
|
||||
/* We're only interested in FUNCTION_DECLS. */
|
||||
if (TREE_CODE (*tp) != FUNCTION_DECL)
|
||||
return NULL_TREE;
|
||||
|
||||
special_function_p (*tp, &setjmp_p, &longjmp_p, &malloc_p, &alloca_p);
|
||||
|
||||
return setjmp_p ? *tp : NULL_TREE;
|
||||
}
|
||||
|
||||
/* Returns non-zero if FN calls `setjmp' or some other function that
|
||||
can return more than once. This function is conservative; it may
|
||||
occasionally return a non-zero value even when FN does not actually
|
||||
call `setjmp'. */
|
||||
|
||||
int
|
||||
calls_setjmp_p (fn)
|
||||
tree fn;
|
||||
{
|
||||
return (walk_tree (&DECL_SAVED_TREE (fn), calls_setjmp_r, NULL)
|
||||
!= NULL_TREE);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue