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]

Re: [PATCH] PR middle-end/14289: TREE_STATIC global reg vars


On Thu, 4 Mar 2004, Richard Henderson wrote:

> On Sat, Feb 28, 2004 at 03:41:29PM -0700, Roger Sayle wrote:
> > register int a[2] asm("ebx");
>
> The error should be here.  The mere declaration makes no sense.

Agreed.  Unfortunately, the compilation errors in global
variable declarations aren't fatal, and the middle-end needs to
be able to gracefully handle the invalid declarations that
survive the front-end and appear in later functions.  The bugzilla
PR describes a segfault immediately after issuing a warning, which
should have been an error.


On Zack's advice I've now researched the area a bit more and have
found a precedent for using TREE_STATIC to distinguish local from
global register variables.  The error message on line 768 of
varasm.c:make_decl_rtl distinguishes global register variables
based upon TREE_STATIC, so it looks like the right thing to do.

Digging a bit deeper, the code at the top of make_decl_rtl checks
whether a variable is automatic, by excluding TREE_PUBLIC,
TREE_STATIC, DECL_EXTERNAL and DECL_REGISTER.  I then tried the
obvious test:

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

And indeed GCC also ICEs again, but isn't caught be my previous
patch.  [I love it when some detective work is predicitive...]


The following patch is an updated and improved version of my
original, to classify both TREE_STATIC and DECL_EXTERNAL register
variables as "global" in the middle-end.  Local register variables
are now conceptually a subset of "automatic" variables (as they
should be).

The following patch and additional test cases have been tested on
i686-pc-linux-gnu with a full "make bootstrap", all languages
except treelang, and regression tested with a top-level "make -k
check" with no new failures.

Is this version OK?  This mostly makes the middle-end more robust,
so perhaps additional front-end patches should also be investigated.



2004-03-04  Roger Sayle  <roger@eyesopen.com>

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

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


Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.281
diff -c -3 -p -r1.281 c-typeck.c
*** c-typeck.c	28 Feb 2004 23:23:30 -0000	1.281
--- c-typeck.c	4 Mar 2004 14:59:58 -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) || DECL_EXTERNAL (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) || DECL_EXTERNAL (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.499
diff -c -3 -p -r1.499 function.c
*** function.c	29 Feb 2004 14:07:39 -0000	1.499
--- function.c	4 Mar 2004 14:59:59 -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" } */
}


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

static register int a[2] asm("ebx");  /* { dg-error "multiple storage" } */

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


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

extern register int a[2] asm("ebx");  /* { dg-error "multiple storage" } */

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]