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] PR middle-end/14289: TREE_STATIC global reg vars


The following patch is my proposed solution to PR middle-end/14289
which is an ICE in invalid regression.  The issue is that the code
in c_mark_addressable attempts to distinguish taking the address
of a "local" register variable [which generates a warning] from
taking the address of a "global" register variable [which generates
an error].  In the PR, we misclassify the register variable and
call put_reg_into_stack with it.  This then confuses everything and
an ICE ensues.

I believe the issue is that TREE_PUBLIC isn't sufficient to distinguish
global from local register variables.  TREE_PUBLIC requires visibility
outside of the current compilation unit, whereas a "global register
variable" is really any register variable that has a scope/lifetime
beyond a single function.

[An earlier attempt to resolve this problem by keeping this a warning
and robustifying put_reg_into_stack just moved the ICE downstream].

Just to be cautious I've also added an "abort" to the middle-end where
the current failure causes a segmentation fault.  This should help if
ever a similar problem affects another of GCC's front-ends in future.


Is this the correct fix?  Ok for mainline, 3.4 and 3.3.4?


Roger


2004-02-28  Roger Sayle  <roger@eyesopen.com>

	PR middle-end/14289
	* c-typeck.c (c_mark_addressable): A register variable should be
	considered global if its TREE_PUBLIC or TREE_STATIC.
	* function.c (put_var_into_stack): Call abort when placing a hard
	register into the stack, if x_parm_reg_stack_loc is NULL.
	Wrap long lines.

	* gcc.dg/pr14289-1.c: New test case.


Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.280
diff -c -3 -p -r1.280 c-typeck.c
*** c-typeck.c	27 Feb 2004 22:33:02 -0000	1.280
--- c-typeck.c	28 Feb 2004 19:24:12 -0000
*************** c_mark_addressable (tree exp)
*** 2603,2609 ****
  	if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
  	    && DECL_NONLOCAL (x))
  	  {
! 	    if (TREE_PUBLIC (x))
  	      {
  		error ("global register variable `%s' used in nested function",
  		       IDENTIFIER_POINTER (DECL_NAME (x)));
--- 2603,2609 ----
  	if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
  	    && DECL_NONLOCAL (x))
  	  {
! 	    if (TREE_PUBLIC (x) || TREE_STATIC (x))
  	      {
  		error ("global register variable `%s' used in nested function",
  		       IDENTIFIER_POINTER (DECL_NAME (x)));
*************** c_mark_addressable (tree exp)
*** 2614,2620 ****
  	  }
  	else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
  	  {
! 	    if (TREE_PUBLIC (x))
  	      {
  		error ("address of global register variable `%s' requested",
  		       IDENTIFIER_POINTER (DECL_NAME (x)));
--- 2614,2620 ----
  	  }
  	else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
  	  {
! 	    if (TREE_PUBLIC (x) || TREE_STATIC (x))
  	      {
  		error ("address of global register variable `%s' requested",
  		       IDENTIFIER_POINTER (DECL_NAME (x)));
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.498
diff -c -3 -p -r1.498 function.c
*** function.c	27 Feb 2004 12:02:55 -0000	1.498
--- function.c	28 Feb 2004 19:24:16 -0000
*************** put_var_into_stack (tree decl, int resca
*** 1430,1437 ****

  static void
  put_reg_into_stack (struct function *function, rtx reg, tree type,
! 		    enum machine_mode promoted_mode, enum machine_mode decl_mode,
! 		    int volatile_p, unsigned int original_regno, int used_p, htab_t ht)
  {
    struct function *func = function ? function : cfun;
    rtx new = 0;
--- 1430,1438 ----

  static void
  put_reg_into_stack (struct function *function, rtx reg, tree type,
! 		    enum machine_mode promoted_mode,
! 		    enum machine_mode decl_mode, int volatile_p,
! 		    unsigned int original_regno, int used_p, htab_t ht)
  {
    struct function *func = function ? function : cfun;
    rtx new = 0;
*************** put_reg_into_stack (struct function *fun
*** 1441,1447 ****
      regno = REGNO (reg);

    if (regno < func->x_max_parm_reg)
!     new = func->x_parm_reg_stack_loc[regno];

    if (new == 0)
      new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func);
--- 1442,1452 ----
      regno = REGNO (reg);

    if (regno < func->x_max_parm_reg)
!     {
!       if (!func->x_parm_reg_stack_loc)
! 	abort ();
!       new = func->x_parm_reg_stack_loc[regno];
!     }

    if (new == 0)
      new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func);


/* PR middle-end/14289 */
/* { dg-do compile { target i?86-*-* } } */
/* { dg-options "-O0" } */

register int a[2] asm("ebx");

void Nase(void)
{
  int i=6;
  a[i]=5;  /* { dg-error "address of global" } */
}


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


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