Commit 2092ee7d by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/29484 (tree-inline.c bug with local static vars)

	PR tree-optimization/29484
	* tree-inline.c (inline_forbidden_p_2): New function.
	(inline_forbidden_p): Disallow inlining if some static var
	has an address of a local LABEL_DECL in its initializer.
	* doc/extend.texi (Labels as Values): Document &&foo behaviour
	vs. inlining.

	* gcc.c-torture/execute/20071220-1.c: New test.
	* gcc.c-torture/execute/20071220-2.c: New test.

From-SVN: r131300
parent 097392de
2008-01-03 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/29484
* tree-inline.c (inline_forbidden_p_2): New function.
(inline_forbidden_p): Disallow inlining if some static var
has an address of a local LABEL_DECL in its initializer.
* doc/extend.texi (Labels as Values): Document &&foo behaviour
vs. inlining.
2007-12-19 Sebastian Pop <sebastian.pop@amd.com> 2007-12-19 Sebastian Pop <sebastian.pop@amd.com>
PR tree-optimization/34635 PR tree-optimization/34635
...@@ -370,6 +370,12 @@ This is more friendly to code living in shared libraries, as it reduces ...@@ -370,6 +370,12 @@ This is more friendly to code living in shared libraries, as it reduces
the number of dynamic relocations that are needed, and by consequence, the number of dynamic relocations that are needed, and by consequence,
allows the data to be read-only. allows the data to be read-only.
The @code{&&foo} expressions for the same label might have different values
if the containing function is inlined or cloned. If a program relies on
them being always the same, @code{__attribute__((__noinline__))} should
be used to prevent inlining. If @code{&&foo} is used
in a static variable initializer, inlining is forbidden.
@node Nested Functions @node Nested Functions
@section Nested Functions @section Nested Functions
@cindex nested functions @cindex nested functions
......
2008-01-03 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/29484
* gcc.c-torture/execute/20071220-1.c: New test.
* gcc.c-torture/execute/20071220-2.c: New test.
2007-12-19 Sebastian Pop <sebastian.pop@amd.com> 2007-12-19 Sebastian Pop <sebastian.pop@amd.com>
PR tree-optimization/34635 PR tree-optimization/34635
/* PR tree-optimization/29484 */
extern void abort (void);
void *__attribute__((noinline))
baz (void **lab)
{
asm volatile ("" : "+r" (lab));
return *lab;
}
static inline
int bar (void)
{
static void *b[] = { &&addr };
void *p = baz (b);
goto *p;
addr:
return 17;
}
int __attribute__((noinline))
f1 (void)
{
return bar ();
}
int __attribute__((noinline))
f2 (void)
{
return bar ();
}
int
main (void)
{
if (f1 () != 17 || f1 () != 17 || f2 () != 17 || f2 () != 17)
abort ();
return 0;
}
/* PR tree-optimization/29484 */
extern void abort (void);
void *__attribute__((noinline))
baz (void **lab)
{
asm volatile ("" : "+r" (lab));
return *lab;
}
static inline
int bar (void)
{
static void *b[] = { &&addr };
baz (b);
addr:
return 17;
}
int __attribute__((noinline))
f1 (void)
{
return bar ();
}
int __attribute__((noinline))
f2 (void)
{
return bar ();
}
int
main (void)
{
if (f1 () != 17 || f1 () != 17 || f2 () != 17 || f2 () != 17)
abort ();
return 0;
}
...@@ -1951,6 +1951,27 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED, ...@@ -1951,6 +1951,27 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
return NULL_TREE; return NULL_TREE;
} }
static tree
inline_forbidden_p_2 (tree *nodep, int *walk_subtrees,
void *fnp)
{
tree node = *nodep;
tree fn = (tree) fnp;
if (TREE_CODE (node) == LABEL_DECL && DECL_CONTEXT (node) == fn)
{
inline_forbidden_reason
= G_("function %q+F can never be inlined "
"because it saves address of local label in a static variable");
return node;
}
if (TYPE_P (node))
*walk_subtrees = 0;
return NULL_TREE;
}
/* Return subexpression representing possible alloca call, if any. */ /* Return subexpression representing possible alloca call, if any. */
static tree static tree
inline_forbidden_p (tree fndecl) inline_forbidden_p (tree fndecl)
...@@ -1959,16 +1980,31 @@ inline_forbidden_p (tree fndecl) ...@@ -1959,16 +1980,31 @@ inline_forbidden_p (tree fndecl)
block_stmt_iterator bsi; block_stmt_iterator bsi;
basic_block bb; basic_block bb;
tree ret = NULL_TREE; tree ret = NULL_TREE;
struct function *fun = DECL_STRUCT_FUNCTION (fndecl);
tree step;
FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (fndecl)) FOR_EACH_BB_FN (bb, fun)
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{ {
ret = walk_tree_without_duplicates (bsi_stmt_ptr (bsi), ret = walk_tree_without_duplicates (bsi_stmt_ptr (bsi),
inline_forbidden_p_1, fndecl); inline_forbidden_p_1, fndecl);
if (ret) if (ret)
goto egress; goto egress;
} }
for (step = fun->unexpanded_var_list; step; step = TREE_CHAIN (step))
{
tree decl = TREE_VALUE (step);
if (TREE_CODE (decl) == VAR_DECL
&& TREE_STATIC (decl)
&& !DECL_EXTERNAL (decl)
&& DECL_INITIAL (decl))
ret = walk_tree_without_duplicates (&DECL_INITIAL (decl),
inline_forbidden_p_2, fndecl);
if (ret)
goto egress;
}
egress: egress:
input_location = saved_loc; input_location = saved_loc;
return ret; return ret;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment