mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-24 20:26:16 +08:00
c-objc-common.c (c_cannot_inline_tree_fn): Warn on why function is not inlinable; do not check the body.
* c-objc-common.c (c_cannot_inline_tree_fn): Warn on why function is not inlinable; do not check the body. (inline_forbidden_p): Move to... * tree-inline.c (inline_forbidden_p_1): ... here; Add warnings; deal with alloca, longjmp. (inline_forbidden_p): New static function. (find_alloca_call_1, find_alloca_call, find_builtin_longjmp_call_1, find_builtin_longjmp_call): Kill. From-SVN: r71283
This commit is contained in:
parent
25c84396dd
commit
f08545a8f2
@ -1,3 +1,15 @@
|
|||||||
|
Thu Sep 11 01:21:05 CEST 2003 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
|
* c-objc-common.c (c_cannot_inline_tree_fn): Warn
|
||||||
|
on why function is not inlinable; do not check
|
||||||
|
the body.
|
||||||
|
(inline_forbidden_p): Move to...
|
||||||
|
* tree-inline.c (inline_forbidden_p_1): ... here; Add warnings;
|
||||||
|
deal with alloca, longjmp.
|
||||||
|
(inline_forbidden_p): New static function.
|
||||||
|
(find_alloca_call_1, find_alloca_call, find_builtin_longjmp_call_1,
|
||||||
|
find_builtin_longjmp_call): Kill.
|
||||||
|
|
||||||
2003-09-10 Richard Henderson <rth@redhat.com>
|
2003-09-10 Richard Henderson <rth@redhat.com>
|
||||||
|
|
||||||
* cgraph.h (struct cgraph_node): Rename lowered to analyzed.
|
* cgraph.h (struct cgraph_node): Rename lowered to analyzed.
|
||||||
|
@ -40,7 +40,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||||||
#include "cgraph.h"
|
#include "cgraph.h"
|
||||||
|
|
||||||
static bool c_tree_printer (pretty_printer *, text_info *);
|
static bool c_tree_printer (pretty_printer *, text_info *);
|
||||||
static tree inline_forbidden_p (tree *, int *, void *);
|
|
||||||
static tree start_cdtor (int);
|
static tree start_cdtor (int);
|
||||||
static void finish_cdtor (tree);
|
static void finish_cdtor (tree);
|
||||||
|
|
||||||
@ -65,110 +64,45 @@ c_disregard_inline_limits (tree fn)
|
|||||||
return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
|
return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static tree
|
|
||||||
inline_forbidden_p (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
|
|
||||||
void *fn)
|
|
||||||
{
|
|
||||||
tree node = *nodep;
|
|
||||||
tree t;
|
|
||||||
|
|
||||||
switch (TREE_CODE (node))
|
|
||||||
{
|
|
||||||
case CALL_EXPR:
|
|
||||||
t = get_callee_fndecl (node);
|
|
||||||
|
|
||||||
if (! t)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* We cannot inline functions that call setjmp. */
|
|
||||||
if (setjmp_call_p (t))
|
|
||||||
return node;
|
|
||||||
|
|
||||||
switch (DECL_FUNCTION_CODE (t))
|
|
||||||
{
|
|
||||||
/* We cannot inline functions that take a variable number of
|
|
||||||
arguments. */
|
|
||||||
case BUILT_IN_VA_START:
|
|
||||||
case BUILT_IN_STDARG_START:
|
|
||||||
#if 0
|
|
||||||
/* Functions that need information about the address of the
|
|
||||||
caller can't (shouldn't?) be inlined. */
|
|
||||||
case BUILT_IN_RETURN_ADDRESS:
|
|
||||||
#endif
|
|
||||||
return node;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DECL_STMT:
|
|
||||||
/* We cannot inline functions that contain other functions. */
|
|
||||||
if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
|
|
||||||
&& DECL_INITIAL (TREE_OPERAND (node, 0)))
|
|
||||||
return node;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GOTO_STMT:
|
|
||||||
case GOTO_EXPR:
|
|
||||||
t = TREE_OPERAND (node, 0);
|
|
||||||
|
|
||||||
/* We will not inline a function which uses computed goto. The
|
|
||||||
addresses of its local labels, which may be tucked into
|
|
||||||
global storage, are of course not constant across
|
|
||||||
instantiations, which causes unexpected behavior. */
|
|
||||||
if (TREE_CODE (t) != LABEL_DECL)
|
|
||||||
return node;
|
|
||||||
|
|
||||||
/* We cannot inline a nested function that jumps to a nonlocal
|
|
||||||
label. */
|
|
||||||
if (TREE_CODE (t) == LABEL_DECL
|
|
||||||
&& !DECL_FILE_SCOPE_P (t) && DECL_CONTEXT (t) != fn)
|
|
||||||
return node;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RECORD_TYPE:
|
|
||||||
case UNION_TYPE:
|
|
||||||
/* We cannot inline a function of the form
|
|
||||||
|
|
||||||
void F (int i) { struct S { int ar[i]; } s; }
|
|
||||||
|
|
||||||
Attempting to do so produces a catch-22 in tree-inline.c.
|
|
||||||
If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
|
|
||||||
UNION_TYPE nodes, then it goes into infinite recursion on a
|
|
||||||
structure containing a pointer to its own type. If it doesn't,
|
|
||||||
then the type node for S doesn't get adjusted properly when
|
|
||||||
F is inlined, and we abort in find_function_data. */
|
|
||||||
for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
|
|
||||||
if (variably_modified_type_p (TREE_TYPE (t)))
|
|
||||||
return node;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL_TREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
c_cannot_inline_tree_fn (tree *fnp)
|
c_cannot_inline_tree_fn (tree *fnp)
|
||||||
{
|
{
|
||||||
tree fn = *fnp;
|
tree fn = *fnp;
|
||||||
tree t;
|
tree t;
|
||||||
|
bool do_warning = (warn_inline
|
||||||
|
&& DECL_INLINE (fn)
|
||||||
|
&& DECL_DECLARED_INLINE_P (fn)
|
||||||
|
&& !DECL_IN_SYSTEM_HEADER (fn));
|
||||||
|
|
||||||
if (flag_really_no_inline
|
if (flag_really_no_inline
|
||||||
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
|
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
|
||||||
return 1;
|
{
|
||||||
|
if (do_warning)
|
||||||
|
warning ("%Hfunction '%F' can never be inlined because it "
|
||||||
|
"is supressed using -fno-inline",
|
||||||
|
&DECL_SOURCE_LOCATION (fn), fn);
|
||||||
|
goto cannot_inline;
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't auto-inline anything that might not be bound within
|
/* Don't auto-inline anything that might not be bound within
|
||||||
this unit of translation. */
|
this unit of translation. */
|
||||||
if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
|
if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
|
||||||
goto cannot_inline;
|
{
|
||||||
|
if (do_warning)
|
||||||
|
warning ("%Hfunction '%F' can never be inlined because it might not "
|
||||||
|
"be bound within this unit of translation",
|
||||||
|
&DECL_SOURCE_LOCATION (fn), fn);
|
||||||
|
goto cannot_inline;
|
||||||
|
}
|
||||||
|
|
||||||
if (! function_attribute_inlinable_p (fn))
|
if (! function_attribute_inlinable_p (fn))
|
||||||
goto cannot_inline;
|
{
|
||||||
|
if (do_warning)
|
||||||
|
warning ("%Hfunction '%F' can never be inlined because it uses "
|
||||||
|
"attributes conflicting with inlining",
|
||||||
|
&DECL_SOURCE_LOCATION (fn), fn);
|
||||||
|
goto cannot_inline;
|
||||||
|
}
|
||||||
|
|
||||||
/* If a function has pending sizes, we must not defer its
|
/* If a function has pending sizes, we must not defer its
|
||||||
compilation, and we can't inline it as a tree. */
|
compilation, and we can't inline it as a tree. */
|
||||||
@ -178,7 +112,13 @@ c_cannot_inline_tree_fn (tree *fnp)
|
|||||||
put_pending_sizes (t);
|
put_pending_sizes (t);
|
||||||
|
|
||||||
if (t)
|
if (t)
|
||||||
goto cannot_inline;
|
{
|
||||||
|
if (do_warning)
|
||||||
|
warning ("%Hfunction '%F' can never be inlined because it has "
|
||||||
|
"pending sizes",
|
||||||
|
&DECL_SOURCE_LOCATION (fn), fn);
|
||||||
|
goto cannot_inline;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! DECL_FILE_SCOPE_P (fn))
|
if (! DECL_FILE_SCOPE_P (fn))
|
||||||
@ -186,30 +126,14 @@ c_cannot_inline_tree_fn (tree *fnp)
|
|||||||
/* If a nested function has pending sizes, we may have already
|
/* If a nested function has pending sizes, we may have already
|
||||||
saved them. */
|
saved them. */
|
||||||
if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
|
if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
|
||||||
goto cannot_inline;
|
{
|
||||||
|
if (do_warning)
|
||||||
|
warning ("%Hnested function '%F' can never be inlined because it "
|
||||||
|
"has possibly saved pending sizes",
|
||||||
|
&DECL_SOURCE_LOCATION (fn), fn);
|
||||||
|
goto cannot_inline;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* We rely on the fact that this function is called upfront,
|
|
||||||
just before we start expanding a function. If FN is active
|
|
||||||
(i.e., it's the current_function_decl or a parent thereof),
|
|
||||||
we have to walk FN's saved tree. Otherwise, we can safely
|
|
||||||
assume we have done it before and, if we didn't mark it as
|
|
||||||
uninlinable (in which case we wouldn't have been called), it
|
|
||||||
is inlinable. Unfortunately, this strategy doesn't work for
|
|
||||||
nested functions, because they're only expanded as part of
|
|
||||||
their enclosing functions, so the inlinability test comes in
|
|
||||||
late. */
|
|
||||||
t = current_function_decl;
|
|
||||||
|
|
||||||
while (t && t != fn)
|
|
||||||
t = DECL_CONTEXT (t);
|
|
||||||
if (! t)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (walk_tree (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn, NULL))
|
|
||||||
goto cannot_inline;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -128,10 +128,6 @@ static tree initialize_inlined_parameters (inline_data *, tree, tree, tree);
|
|||||||
static void remap_block (tree *, tree, inline_data *);
|
static void remap_block (tree *, tree, inline_data *);
|
||||||
static tree add_stmt_to_compound (tree, tree, tree);
|
static tree add_stmt_to_compound (tree, tree, tree);
|
||||||
#endif /* INLINER_FOR_JAVA */
|
#endif /* INLINER_FOR_JAVA */
|
||||||
static tree find_alloca_call_1 (tree *, int *, void *);
|
|
||||||
static tree find_alloca_call (tree);
|
|
||||||
static tree find_builtin_longjmp_call_1 (tree *, int *, void *);
|
|
||||||
static tree find_builtin_longjmp_call (tree);
|
|
||||||
|
|
||||||
/* Remap DECL during the copying of the BLOCK tree for the function. */
|
/* Remap DECL during the copying of the BLOCK tree for the function. */
|
||||||
|
|
||||||
@ -880,50 +876,148 @@ tree_inlinable_function_p (tree fn)
|
|||||||
return inlinable_function_p (fn);
|
return inlinable_function_p (fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If *TP is possibly call to alloca, return nonzero. */
|
static const char *inline_forbidden_reason;
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
find_alloca_call_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
|
inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
|
||||||
void *data ATTRIBUTE_UNUSED)
|
void *fn)
|
||||||
{
|
{
|
||||||
if (alloca_call_p (*tp))
|
tree node = *nodep;
|
||||||
return *tp;
|
tree t;
|
||||||
return NULL;
|
|
||||||
|
switch (TREE_CODE (node))
|
||||||
|
{
|
||||||
|
case CALL_EXPR:
|
||||||
|
/* Refuse to inline alloca call unless user explicitly forced so as this
|
||||||
|
may change program's memory overhead drastically when the function
|
||||||
|
using alloca is called in loop. In GCC present in SPEC2000 inlining
|
||||||
|
into schedule_block cause it to require 2GB of ram instead of 256MB. */
|
||||||
|
if (alloca_call_p (node)
|
||||||
|
&& !lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)))
|
||||||
|
{
|
||||||
|
inline_forbidden_reason = "%Hfunction '%F' can never be inlined "
|
||||||
|
"because it uses alloca (override using "
|
||||||
|
"the always_inline attribute)";
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
t = get_callee_fndecl (node);
|
||||||
|
if (! t)
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
/* We cannot inline functions that call setjmp. */
|
||||||
|
if (setjmp_call_p (t))
|
||||||
|
{
|
||||||
|
inline_forbidden_reason = "%Hfunction '%F' can never be inlined"
|
||||||
|
" because it uses setjmp";
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (DECL_FUNCTION_CODE (t))
|
||||||
|
{
|
||||||
|
/* We cannot inline functions that take a variable number of
|
||||||
|
arguments. */
|
||||||
|
case BUILT_IN_VA_START:
|
||||||
|
case BUILT_IN_STDARG_START:
|
||||||
|
{
|
||||||
|
inline_forbidden_reason = "%Hfunction '%F' can never be inlined "
|
||||||
|
"because it uses variable argument lists";
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
case BUILT_IN_LONGJMP:
|
||||||
|
{
|
||||||
|
/* We can't inline functions that call __builtin_longjmp at all.
|
||||||
|
The non-local goto machinery really requires the destination
|
||||||
|
be in a different function. If we allow the function calling
|
||||||
|
__builtin_longjmp to be inlined into the function calling
|
||||||
|
__builtin_setjmp, Things will Go Awry. */
|
||||||
|
/* ??? Need front end help to identify "regular" non-local goto. */
|
||||||
|
if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL)
|
||||||
|
{
|
||||||
|
inline_forbidden_reason = "%Hfunction '%F' can never be inlined "
|
||||||
|
"because it uses setjmp-longjmp "
|
||||||
|
"exception handling";
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifndef INLINER_FOR_JAVA
|
||||||
|
case DECL_STMT:
|
||||||
|
/* We cannot inline functions that contain other functions. */
|
||||||
|
if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
|
||||||
|
&& DECL_INITIAL (TREE_OPERAND (node, 0)))
|
||||||
|
{
|
||||||
|
inline_forbidden_reason = "%Hfunction '%F' can never be inlined "
|
||||||
|
"because it contains a nested function";
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GOTO_STMT:
|
||||||
|
case GOTO_EXPR:
|
||||||
|
t = TREE_OPERAND (node, 0);
|
||||||
|
|
||||||
|
/* We will not inline a function which uses computed goto. The
|
||||||
|
addresses of its local labels, which may be tucked into
|
||||||
|
global storage, are of course not constant across
|
||||||
|
instantiations, which causes unexpected behavior. */
|
||||||
|
if (TREE_CODE (t) != LABEL_DECL)
|
||||||
|
{
|
||||||
|
inline_forbidden_reason = "%Hfunction '%F' can never be inlined "
|
||||||
|
"because it contains a nonlocal label";
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We cannot inline a nested function that jumps to a nonlocal
|
||||||
|
label. */
|
||||||
|
if (TREE_CODE (t) == LABEL_DECL && DECL_CONTEXT (t) != fn)
|
||||||
|
{
|
||||||
|
inline_forbidden_reason = "%Hfunction '%F' can never be inlined "
|
||||||
|
"because it contains a nonlocal goto";
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECORD_TYPE:
|
||||||
|
case UNION_TYPE:
|
||||||
|
/* We cannot inline a function of the form
|
||||||
|
|
||||||
|
void F (int i) { struct S { int ar[i]; } s; }
|
||||||
|
|
||||||
|
Attempting to do so produces a catch-22.
|
||||||
|
If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
|
||||||
|
UNION_TYPE nodes, then it goes into infinite recursion on a
|
||||||
|
structure containing a pointer to its own type. If it doesn't,
|
||||||
|
then the type node for S doesn't get adjusted properly when
|
||||||
|
F is inlined, and we abort in find_function_data. */
|
||||||
|
for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
|
||||||
|
if (variably_modified_type_p (TREE_TYPE (t)))
|
||||||
|
{
|
||||||
|
inline_forbidden_reason = "%Hfunction '%F' can never be inlined "
|
||||||
|
"because it uses variable sized variables";
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL_TREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return subexpression representing possible alloca call, if any. */
|
/* Return subexpression representing possible alloca call, if any. */
|
||||||
static tree
|
static tree
|
||||||
find_alloca_call (tree exp)
|
inline_forbidden_p (tree fndecl)
|
||||||
{
|
{
|
||||||
location_t saved_loc = input_location;
|
location_t saved_loc = input_location;
|
||||||
tree ret = walk_tree_without_duplicates
|
tree ret = walk_tree_without_duplicates
|
||||||
(&exp, find_alloca_call_1, NULL);
|
(&DECL_SAVED_TREE (fndecl), inline_forbidden_p_1, fndecl);
|
||||||
input_location = saved_loc;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static tree
|
|
||||||
find_builtin_longjmp_call_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
|
|
||||||
void *data ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
tree exp = *tp, decl;
|
|
||||||
|
|
||||||
if (TREE_CODE (exp) == CALL_EXPR
|
|
||||||
&& TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
|
|
||||||
&& (decl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
|
|
||||||
TREE_CODE (decl) == FUNCTION_DECL)
|
|
||||||
&& DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
|
|
||||||
&& DECL_FUNCTION_CODE (decl) == BUILT_IN_LONGJMP)
|
|
||||||
return decl;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static tree
|
|
||||||
find_builtin_longjmp_call (tree exp)
|
|
||||||
{
|
|
||||||
location_t saved_loc = input_location;
|
|
||||||
tree ret = walk_tree_without_duplicates
|
|
||||||
(&exp, find_builtin_longjmp_call_1, NULL);
|
|
||||||
input_location = saved_loc;
|
input_location = saved_loc;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -935,8 +1029,6 @@ static bool
|
|||||||
inlinable_function_p (tree fn)
|
inlinable_function_p (tree fn)
|
||||||
{
|
{
|
||||||
bool inlinable = true;
|
bool inlinable = true;
|
||||||
bool calls_builtin_longjmp = false;
|
|
||||||
bool calls_alloca = false;
|
|
||||||
|
|
||||||
/* If we've already decided this function shouldn't be inlined,
|
/* If we've already decided this function shouldn't be inlined,
|
||||||
there's no need to check again. */
|
there's no need to check again. */
|
||||||
@ -980,24 +1072,7 @@ inlinable_function_p (tree fn)
|
|||||||
inlinable = false;
|
inlinable = false;
|
||||||
#endif /* INLINER_FOR_JAVA */
|
#endif /* INLINER_FOR_JAVA */
|
||||||
|
|
||||||
/* We can't inline functions that call __builtin_longjmp at all.
|
else if (inline_forbidden_p (fn))
|
||||||
The non-local goto machinery really requires the destination
|
|
||||||
be in a different function. If we allow the function calling
|
|
||||||
__builtin_longjmp to be inlined into the function calling
|
|
||||||
__builtin_setjmp, Things will Go Awry. */
|
|
||||||
/* ??? Need front end help to identify "regular" non-local goto. */
|
|
||||||
else if (find_builtin_longjmp_call (DECL_SAVED_TREE (fn)))
|
|
||||||
calls_builtin_longjmp = true;
|
|
||||||
|
|
||||||
/* Refuse to inline alloca call unless user explicitly forced so as this
|
|
||||||
may change program's memory overhead drastically when the function
|
|
||||||
using alloca is called in loop. In GCC present in SPEC2000 inlining
|
|
||||||
into schedule_block cause it to require 2GB of ram instead of 256MB. */
|
|
||||||
else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL
|
|
||||||
&& find_alloca_call (DECL_SAVED_TREE (fn)))
|
|
||||||
calls_alloca = true;
|
|
||||||
|
|
||||||
if (calls_builtin_longjmp || calls_alloca)
|
|
||||||
{
|
{
|
||||||
/* See if we should warn about uninlinable functions. Previously,
|
/* See if we should warn about uninlinable functions. Previously,
|
||||||
some of these warnings would be issued while trying to expand
|
some of these warnings would be issued while trying to expand
|
||||||
@ -1012,13 +1087,8 @@ inlinable_function_p (tree fn)
|
|||||||
&& DECL_DECLARED_INLINE_P (fn)
|
&& DECL_DECLARED_INLINE_P (fn)
|
||||||
&& !DECL_IN_SYSTEM_HEADER (fn));
|
&& !DECL_IN_SYSTEM_HEADER (fn));
|
||||||
|
|
||||||
if (do_warning && calls_builtin_longjmp)
|
if (do_warning)
|
||||||
warning ("%Hfunction '%F' can never be inlined because it uses "
|
warning (inline_forbidden_reason,
|
||||||
"setjmp-longjmp exception handling",
|
|
||||||
&DECL_SOURCE_LOCATION (fn), fn);
|
|
||||||
if (do_warning && calls_alloca)
|
|
||||||
warning ("%Hfunction '%F' can never be inlined because it uses "
|
|
||||||
"setjmp-longjmp exception handling",
|
|
||||||
&DECL_SOURCE_LOCATION (fn), fn);
|
&DECL_SOURCE_LOCATION (fn), fn);
|
||||||
|
|
||||||
inlinable = false;
|
inlinable = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user