This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR middle-end/14289: TREE_STATIC global reg vars
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 28 Feb 2004 15:41:29 -0700 (MST)
- Subject: [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