This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR middle-end/18820
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 10 Jan 2005 13:52:21 +0100
- Subject: [PATCH] Fix PR middle-end/18820
Hi,
This is the ACATS c953002 failure. The problem was introduced with:
2004-11-03 Andrew Pinski <pinskia@physics.uc.edu>
PR tree-opt/18231
* tree.c (staticp) <case FUNCTION_DECL>: Nested functions are static
also.
which causes the compiler to now accept
struct S {
void (*f)(int);
};
extern void baz(struct S *);
extern void p(int);
void foo(void)
{
int u;
void bar(int val)
{
u = val;
}
static struct S s = { bar };
baz(&s);
p(u);
}
and of course no trampoline is built for 'bar'.
The patch looks questionable to me:
- /* Nested functions aren't static, since taking their address
- involves a trampoline. */
- return ((decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN
(arg))
- && ! DECL_NON_ADDR_CONST_P (arg)
- ? arg : NULL);
+ /* Nested functions are static, even though taking their address will
+ involve a trampoline as we unnest the nested function and create
+ the trampoline on the tree level. */
given the head comment of staticp:
/* If arg is static -- a reference to an object in static storage -- then
return the object. This is not the same as the C meaning of `static'.
If arg isn't static, return NULL. */
It seems to me that we have introduced an implementation bias. Reverting the
patch fixes c95300[123] and c980002, and introduces no regression since no
testcase was commited with the patch.
However the change was made partly because of pessimization problems, so it is
perhaps better to keep it. Another alternative is to test for nested
functions in the ADDR_EXPR case of initializer_constant_valid_p.
Bootstrapped/regtested on i586-mandrake-linux-gnu.
2005-01-10 Eric Botcazou <ebotcazou@libertysurf.fr>
PR middle-end/18820
* varasm.c (initializer_constant_valid_p) <ADDR_EXPR>: Return
zero for nested functions needing a static chain or functions with
a non-constant address.
2005-01-10 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/nested-func-2.c: New test.
--
Eric Botcazou
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.472
diff -u -p -r1.472 varasm.c
--- varasm.c 2 Jan 2005 07:52:28 -0000 1.472
+++ varasm.c 10 Jan 2005 09:28:07 -0000
@@ -3500,6 +3500,12 @@ initializer_constant_valid_p (tree value
&& TREE_CODE (value) == INDIRECT_REF
&& TREE_CONSTANT (TREE_OPERAND (value, 0)))
return null_pointer_node;
+ /* Taking the address of a nested function involves a trampoline. */
+ if (value
+ && TREE_CODE (value) == FUNCTION_DECL
+ && ((decl_function_context (value) && !DECL_NO_STATIC_CHAIN (value))
+ || DECL_NON_ADDR_CONST_P (value)))
+ return NULL_TREE;
return value;
case VIEW_CONVERT_EXPR:
/* PR middle-end/18820 */
/* Check that we reject nested functions as initializers
of static variables. */
/* { dg-do compile } */
/* { dg-options "" } */
struct S {
void (*f)(int);
};
extern void baz(struct S *);
extern void p(int);
void foo(void)
{
int u;
void bar(int val)
{
u = val;
}
static struct S s = { bar }; /* { dg-error "(is not constant)|(near initialization)" } */
baz(&s);
p(u);
}