re PR c++/11131 (Unrelated declaration removes inline flag from function)
PR c++/11131 * tree-inline.c (inlinable_function_p): Call the language-specific hook early. PR c++/11131 * cp-tree.h (template_for_substitution): Declare. * decl2.c (mark_used): Use it when figuring out whether or not a function is inline. * pt.c (template_for_substitution): Give it external linkage. * tree.c (cp_cannot_inline_tree_fn): Instantiate as early as possible. PR c++/11131 * g++.dg/opt/template1.C: New test. From-SVN: r67698
This commit is contained in:
parent
c566f9bd36
commit
d58b7c2d5d
@ -1,3 +1,9 @@
|
||||
2003-06-10 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/11131
|
||||
* tree-inline.c (inlinable_function_p): Call the language-specific
|
||||
hook early.
|
||||
|
||||
2003-06-09 David Taylor <dtaylor@emc.com>
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_va_start, rs6000_va_arg): Skip over
|
||||
|
@ -1,3 +1,13 @@
|
||||
2003-06-10 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/11131
|
||||
* cp-tree.h (template_for_substitution): Declare.
|
||||
* decl2.c (mark_used): Use it when figuring out whether or not a
|
||||
function is inline.
|
||||
* pt.c (template_for_substitution): Give it external linkage.
|
||||
* tree.c (cp_cannot_inline_tree_fn): Instantiate as early as
|
||||
possible.
|
||||
|
||||
2003-06-09 Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
PR 8861
|
||||
|
@ -3978,6 +3978,7 @@ extern bool type_dependent_expression_p (tree);
|
||||
extern bool value_dependent_expression_p (tree);
|
||||
extern tree resolve_typename_type (tree, bool);
|
||||
extern tree resolve_typename_type_in_current_instantiation (tree);
|
||||
extern tree template_for_substitution (tree);
|
||||
|
||||
/* in repo.c */
|
||||
extern void repo_template_used (tree);
|
||||
|
@ -4590,7 +4590,9 @@ mark_used (tree decl)
|
||||
if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL)
|
||||
&& DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
|
||||
&& (!DECL_EXPLICIT_INSTANTIATION (decl)
|
||||
|| (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))))
|
||||
|| (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_INLINE (DECL_TEMPLATE_RESULT
|
||||
(template_for_substitution (decl))))))
|
||||
{
|
||||
bool defer;
|
||||
|
||||
|
@ -171,7 +171,6 @@ static tree copy_default_args_to_explicit_spec_1 PARAMS ((tree, tree));
|
||||
static void copy_default_args_to_explicit_spec PARAMS ((tree));
|
||||
static int invalid_nontype_parm_type_p PARAMS ((tree, tsubst_flags_t));
|
||||
static int eq_local_specializations (const void *, const void *);
|
||||
static tree template_for_substitution (tree);
|
||||
static bool dependent_type_p_r (tree);
|
||||
static bool dependent_template_id_p (tree, tree);
|
||||
static tree tsubst (tree, tree, tsubst_flags_t, tree);
|
||||
@ -10736,7 +10735,7 @@ regenerate_decl_from_template (decl, tmpl)
|
||||
/* Return the TEMPLATE_DECL into which DECL_TI_ARGS(DECL) should be
|
||||
substituted to get DECL. */
|
||||
|
||||
static tree
|
||||
tree
|
||||
template_for_substitution (tree decl)
|
||||
{
|
||||
tree tmpl = DECL_TI_TEMPLATE (decl);
|
||||
|
@ -2204,10 +2204,6 @@ cp_cannot_inline_tree_fn (fnp)
|
||||
{
|
||||
tree fn = *fnp;
|
||||
|
||||
if (flag_really_no_inline
|
||||
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
|
||||
return 1;
|
||||
|
||||
/* We can inline a template instantiation only if it's fully
|
||||
instantiated. */
|
||||
if (DECL_TEMPLATE_INFO (fn)
|
||||
@ -2218,6 +2214,13 @@ cp_cannot_inline_tree_fn (fnp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!DECL_INLINE (fn))
|
||||
return 1;
|
||||
|
||||
if (flag_really_no_inline
|
||||
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
|
||||
return 1;
|
||||
|
||||
/* Don't auto-inline anything that might not be bound within
|
||||
this unit of translation. */
|
||||
if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
|
||||
|
@ -1,3 +1,8 @@
|
||||
2003-06-10 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/11131
|
||||
* g++.dg/opt/template1.C: New test.
|
||||
|
||||
2003-06-09 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* lib/gcc-dg.exp (dg-test): Clear additional_files and
|
||||
|
19
gcc/testsuite/g++.dg/opt/template1.C
Normal file
19
gcc/testsuite/g++.dg/opt/template1.C
Normal file
@ -0,0 +1,19 @@
|
||||
// { dg-options "-O2" }
|
||||
// { dg-final { scan-assembler-not "foo1" } }
|
||||
|
||||
template <int>
|
||||
struct A {
|
||||
void foo1 () throw ();
|
||||
void foo2 ();
|
||||
|
||||
void UNRELATED ();
|
||||
};
|
||||
|
||||
template <> void A<0>::UNRELATED ();
|
||||
|
||||
template <int dim> inline void A<dim>::foo1 () throw () {}
|
||||
template <int dim> inline void A<dim>::foo2 () {}
|
||||
|
||||
void bar (A<0> &a) {
|
||||
a.foo1 ();
|
||||
}
|
@ -979,8 +979,10 @@ inlinable_function_p (fn, id, nolimit)
|
||||
if (DECL_UNINLINABLE (fn))
|
||||
return 0;
|
||||
|
||||
/* Assume it is not inlinable. */
|
||||
inlinable = 0;
|
||||
/* See if there is any language-specific reason it cannot be
|
||||
inlined. (It is important that this hook be called early because
|
||||
in C++ it may result in template instantiation.) */
|
||||
inlinable = !(*lang_hooks.tree_inlining.cannot_inline_tree_fn) (&fn);
|
||||
|
||||
/* We may be here either because fn is declared inline or because
|
||||
we use -finline-functions. For the second case, we are more
|
||||
@ -993,7 +995,7 @@ inlinable_function_p (fn, id, nolimit)
|
||||
|
||||
/* If we're not inlining things, then nothing is inlinable. */
|
||||
if (! flag_inline_trees)
|
||||
;
|
||||
inlinable = 0;
|
||||
/* If we're not inlining all functions and the function was not
|
||||
declared `inline', we don't inline it. Don't think of
|
||||
disregarding DECL_INLINE when flag_inline_trees == 2; it's the
|
||||
@ -1001,11 +1003,11 @@ inlinable_function_p (fn, id, nolimit)
|
||||
dwarf2out loses if a function is inlined that doesn't have
|
||||
DECL_INLINE set. */
|
||||
else if (! DECL_INLINE (fn) && !nolimit)
|
||||
;
|
||||
inlinable = 0;
|
||||
#ifdef INLINER_FOR_JAVA
|
||||
/* Synchronized methods can't be inlined. This is a bug. */
|
||||
else if (METHOD_SYNCHRONIZED (fn))
|
||||
;
|
||||
inlinable = 0;
|
||||
#endif /* INLINER_FOR_JAVA */
|
||||
/* We can't inline functions that are too big. Only allow a single
|
||||
function to be of MAX_INLINE_INSNS_SINGLE size. Make special
|
||||
@ -1013,7 +1015,7 @@ inlinable_function_p (fn, id, nolimit)
|
||||
else if (!nolimit
|
||||
&& ! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
|
||||
&& currfn_insns > max_inline_insns_single)
|
||||
;
|
||||
inlinable = 0;
|
||||
/* We can't inline functions that call __builtin_longjmp at all.
|
||||
The non-local goto machenery really requires the destination
|
||||
be in a different function. If we allow the function calling
|
||||
@ -1021,20 +1023,14 @@ inlinable_function_p (fn, id, nolimit)
|
||||
__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)))
|
||||
;
|
||||
inlinable = 0;
|
||||
/* 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)))
|
||||
;
|
||||
/* All is well. We can inline this function. Traditionally, GCC
|
||||
has refused to inline functions using alloca, or functions whose
|
||||
values are returned in a PARALLEL, and a few other such obscure
|
||||
conditions. We are not equally constrained at the tree level. */
|
||||
else
|
||||
inlinable = 1;
|
||||
inlinable = 0;
|
||||
|
||||
/* Squirrel away the result so that we don't have to check again. */
|
||||
DECL_UNINLINABLE (fn) = ! inlinable;
|
||||
@ -1065,9 +1061,6 @@ inlinable_function_p (fn, id, nolimit)
|
||||
}
|
||||
}
|
||||
|
||||
if (inlinable && (*lang_hooks.tree_inlining.cannot_inline_tree_fn) (&fn))
|
||||
inlinable = 0;
|
||||
|
||||
/* If we don't have the function body available, we can't inline
|
||||
it. */
|
||||
if (! DECL_SAVED_TREE (fn))
|
||||
|
Loading…
x
Reference in New Issue
Block a user