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 optimization/12544


Hi,

This is a regression from GCC 3.2.3 present on the 3.3 branch and mainline 
that shows up on SPARC (and more generally on targets that pass structures 
by invisible references), caused by my patch that has instructed the 
compiler to set the DECL_NONLOCAL flag on variables used by nested functions 
during the parsing of their parent, instead of during the RTL generation of 
the child functions.

It turns out that put_var_into_stack implicitly thinks that DECL_NONLOCAL can 
only be seen from within nested functions, which is of course not true 
anymore. More precisely, it applies a first transformation reserved to 
special DECL_NONLOCAL decls then a second one reserved to non-DECL_NONLOCAL 
decls, because it doesn't test the DECL_NONLOCAL flag in the second case. So 
we end up putting a DECL_NONLOCAL argument in an ADDRESSOF with a bogus mode 
and ICE when attempting to generate a SImode to BLKmode move.

Bootstrapped/regtested on sparc-sun-solaris2.8 (3.3 branch except Ada). Ok 
for mainline and 3.3 branch?

Mark, I'm not sure you want this patch for 3.3.2 so I'm prepared to wait 
until the branch reopens (if it ever reopens).


2003-10-11  Eric Botcazou  <ebotcazou@libertysurf.fr>

        PR optimization/12544
        * function.c (put_var_into_stack): Don't generate
	ADDRESSOFs for DECL_NONLOCAL decls.


2003-10-11  Eric Botcazou  <ebotcazou@libertysurf.fr>

        * gcc.c-torture/compile/20031011-1.c: New test.

-- 
Eric Botcazou
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.389.2.10
diff -u -p -r1.389.2.10 function.c
--- function.c	10 Apr 2003 22:26:04 -0000	1.389.2.10
+++ function.c	11 Oct 2003 12:13:15 -0000
@@ -1373,8 +1373,9 @@ put_var_into_stack (decl, rescan)
       if (function->decl == context)
 	break;
 
-  /* If this is a variable-size object with a pseudo to address it,
-     put that pseudo into the stack, if the var is nonlocal.  */
+  /* If this is a variable-sized object or a structure passed by invisible
+     reference, with a pseudo to address it, put that pseudo into the stack
+     if the var is non-local.  */
   if (TREE_CODE (decl) != SAVE_EXPR && DECL_NONLOCAL (decl)
       && GET_CODE (reg) == MEM
       && GET_CODE (XEXP (reg, 0)) == REG
@@ -1384,8 +1385,12 @@ put_var_into_stack (decl, rescan)
       decl_mode = promoted_mode = GET_MODE (reg);
     }
 
+  /* If this variable lives in the current function and we don't need to put it
+     in the stack for the sake of setjmp or the non-locality, try to keep it in
+     a register until we know we actually need the address.  */
   can_use_addressof
     = (function == 0
+       && ! (TREE_CODE (decl) != SAVE_EXPR && DECL_NONLOCAL (decl))
        && optimize > 0
        /* FIXME make it work for promoted modes too */
        && decl_mode == promoted_mode
@@ -1404,9 +1409,6 @@ put_var_into_stack (decl, rescan)
 
   if (GET_CODE (reg) == REG)
     {
-      /* If this variable lives in the current function and we don't need
-	 to put things in the stack for the sake of setjmp, try to keep it
-	 in a register until we know we actually need the address.  */
       if (can_use_addressof)
 	gen_mem_addressof (reg, decl, rescan);
       else
/* PR optimization/12544 */
/* Origin: Tony Hosking <hosking@cs.purdue.edu> */

/* Verify that non-local structures passed by reference
   are correctly put in the stack.  */

typedef struct {
  int a;
  int f;
} A;

A *b;

void x (A a) {
  void y () {
    a.a = 0;
  }

  b = &a;
  y();
}

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