This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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);
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]