c-tree.h (C_DECL_REGISTER): New.
* c-tree.h (C_DECL_REGISTER): New. * c-aux-info.c (gen_decl), c-decl.c (objc_mark_locals_volatile, finish_decl, grokdeclarator, get_parm_info), c-typeck.c (build_array_ref, c_mark_addressable): Set and use it. * c-decl.c (grokdeclarator), c-typeck.c (c_mark_addressable): Allow structures with volatile fields to be declared register. Don't check TREE_ADDRESSABLE before warning about taking address of register. * c-decl.c (finish_decl): Don't allow structures with volatile fields to be placed in named register. * doc/trouble.texi: Remove reference to structures with volatile fields in registers. testsuite: * gcc.dg/940409-1.c: Remove XFAIL. * gcc.dg/reg-vol-struct-1.c: New test. From-SVN: r80037
This commit is contained in:
parent
4c24abdce4
commit
5baeaac067
|
@ -1,3 +1,18 @@
|
|||
2004-03-28 Joseph S. Myers <jsm@polyomino.org.uk>
|
||||
|
||||
* c-tree.h (C_DECL_REGISTER): New.
|
||||
* c-aux-info.c (gen_decl), c-decl.c (objc_mark_locals_volatile,
|
||||
finish_decl, grokdeclarator, get_parm_info), c-typeck.c
|
||||
(build_array_ref, c_mark_addressable): Set and use it.
|
||||
* c-decl.c (grokdeclarator), c-typeck.c (c_mark_addressable):
|
||||
Allow structures with volatile fields to be declared register.
|
||||
Don't check TREE_ADDRESSABLE before warning about taking address
|
||||
of register.
|
||||
* c-decl.c (finish_decl): Don't allow structures with volatile
|
||||
fields to be placed in named register.
|
||||
* doc/trouble.texi: Remove reference to structures with volatile
|
||||
fields in registers.
|
||||
|
||||
2004-03-27 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* function.c (thread_prologue_and_epilogue): Move
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
on information stored in GCC's tree structure. This code implements the
|
||||
-aux-info option.
|
||||
Copyright (C) 1989, 1991, 1994, 1995, 1997, 1998,
|
||||
1999, 2000, 2003 Free Software Foundation, Inc.
|
||||
1999, 2000, 2003, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Ron Guilmette (rfg@segfault.us.com).
|
||||
|
||||
This file is part of GCC.
|
||||
|
@ -531,7 +531,7 @@ gen_decl (tree decl, int is_func_definition, formals_style style)
|
|||
|
||||
ret_val = affix_data_type (ret_val);
|
||||
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL && C_DECL_REGISTER (decl))
|
||||
ret_val = concat ("register ", ret_val, NULL);
|
||||
if (TREE_PUBLIC (decl))
|
||||
ret_val = concat ("extern ", ret_val, NULL);
|
||||
|
|
32
gcc/c-decl.c
32
gcc/c-decl.c
|
@ -488,6 +488,7 @@ objc_mark_locals_volatile (void *enclosing_blk)
|
|||
if (TREE_CODE (b->decl) == VAR_DECL
|
||||
|| TREE_CODE (b->decl) == PARM_DECL)
|
||||
{
|
||||
C_DECL_REGISTER (b->decl) = 0;
|
||||
DECL_REGISTER (b->decl) = 0;
|
||||
TREE_THIS_VOLATILE (b->decl) = 1;
|
||||
}
|
||||
|
@ -2901,8 +2902,15 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
|
|||
/* In conjunction with an ASMSPEC, the `register'
|
||||
keyword indicates that we should place the variable
|
||||
in a particular register. */
|
||||
if (DECL_REGISTER (decl))
|
||||
DECL_C_HARD_REGISTER (decl) = 1;
|
||||
if (C_DECL_REGISTER (decl))
|
||||
{
|
||||
DECL_C_HARD_REGISTER (decl) = 1;
|
||||
/* This cannot be done for a structure with volatile
|
||||
fields, on which DECL_REGISTER will have been
|
||||
reset. */
|
||||
if (!DECL_REGISTER (decl))
|
||||
error ("cannot put object with volatile field into register");
|
||||
}
|
||||
|
||||
/* If this is not a static variable, issue a warning.
|
||||
It doesn't make any sense to give an ASMSPEC for an
|
||||
|
@ -2910,7 +2918,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
|
|||
GCC has accepted -- but ignored -- the ASMSPEC in
|
||||
this case. */
|
||||
if (TREE_CODE (decl) == VAR_DECL
|
||||
&& !DECL_REGISTER (decl)
|
||||
&& !C_DECL_REGISTER (decl)
|
||||
&& !TREE_STATIC (decl))
|
||||
warning ("%Jignoring asm-specifier for non-static local "
|
||||
"variable '%D'", decl, decl);
|
||||
|
@ -4527,7 +4535,10 @@ grokdeclarator (tree declarator, tree declspecs,
|
|||
and in case doing stupid register allocation. */
|
||||
|
||||
if (specbits & (1 << (int) RID_REGISTER))
|
||||
DECL_REGISTER (decl) = 1;
|
||||
{
|
||||
C_DECL_REGISTER (decl) = 1;
|
||||
DECL_REGISTER (decl) = 1;
|
||||
}
|
||||
|
||||
/* Record constancy and volatility. */
|
||||
c_apply_type_quals_to_decl (type_quals, decl);
|
||||
|
@ -4536,7 +4547,16 @@ grokdeclarator (tree declarator, tree declspecs,
|
|||
Otherwise, the fact that those components are volatile
|
||||
will be ignored, and would even crash the compiler. */
|
||||
if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl)))
|
||||
c_mark_addressable (decl);
|
||||
{
|
||||
/* It is not an error for a structure with volatile fields to
|
||||
be declared register, but reset DECL_REGISTER since it
|
||||
cannot actually go in a register. */
|
||||
int was_reg = C_DECL_REGISTER (decl);
|
||||
C_DECL_REGISTER (decl) = 0;
|
||||
DECL_REGISTER (decl) = 0;
|
||||
c_mark_addressable (decl);
|
||||
C_DECL_REGISTER (decl) = was_reg;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
/* This is the earliest point at which we might know the assembler
|
||||
|
@ -4684,7 +4704,7 @@ get_parm_info (bool ellipsis)
|
|||
{
|
||||
if (TREE_THIS_VOLATILE (b->decl)
|
||||
|| TREE_READONLY (b->decl)
|
||||
|| DECL_REGISTER (b->decl))
|
||||
|| C_DECL_REGISTER (b->decl))
|
||||
error ("'void' as only parameter may not be qualified");
|
||||
|
||||
/* There cannot be an ellipsis. */
|
||||
|
|
|
@ -115,6 +115,11 @@ struct lang_type GTY(())
|
|||
been declared. */
|
||||
#define C_DECL_DECLARED_BUILTIN(EXP) DECL_LANG_FLAG_4 (EXP)
|
||||
|
||||
/* Record whether a decl was declared register. This is strictly a
|
||||
front-end flag, whereas DECL_REGISTER is used for code generation;
|
||||
they may differ for structures with volatile fields. */
|
||||
#define C_DECL_REGISTER(EXP) DECL_LANG_FLAG_5 (EXP)
|
||||
|
||||
/* Nonzero for a decl which either doesn't exist or isn't a prototype.
|
||||
N.B. Could be simplified if all built-in decls had complete prototypes
|
||||
(but this is presently difficult because some of them need FILE*). */
|
||||
|
|
|
@ -1525,7 +1525,7 @@ build_array_ref (tree array, tree index)
|
|||
tree foo = array;
|
||||
while (TREE_CODE (foo) == COMPONENT_REF)
|
||||
foo = TREE_OPERAND (foo, 0);
|
||||
if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo))
|
||||
if (TREE_CODE (foo) == VAR_DECL && C_DECL_REGISTER (foo))
|
||||
pedwarn ("ISO C forbids subscripting `register' array");
|
||||
else if (! flag_isoc99 && ! lvalue_p (foo))
|
||||
pedwarn ("ISO C90 forbids subscripting non-lvalue array");
|
||||
|
@ -2495,7 +2495,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
|
|||
|
||||
/* Return nonzero if REF is an lvalue valid for this language.
|
||||
Lvalues can be assigned, unless their type has TYPE_READONLY.
|
||||
Lvalues can have their address taken, unless they have DECL_REGISTER. */
|
||||
Lvalues can have their address taken, unless they have C_DECL_REGISTER. */
|
||||
|
||||
int
|
||||
lvalue_p (tree ref)
|
||||
|
@ -2604,7 +2604,7 @@ c_mark_addressable (tree exp)
|
|||
case CONST_DECL:
|
||||
case PARM_DECL:
|
||||
case RESULT_DECL:
|
||||
if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
|
||||
if (C_DECL_REGISTER (x)
|
||||
&& DECL_NONLOCAL (x))
|
||||
{
|
||||
if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
|
||||
|
@ -2616,7 +2616,7 @@ c_mark_addressable (tree exp)
|
|||
pedwarn ("register variable `%s' used in nested function",
|
||||
IDENTIFIER_POINTER (DECL_NAME (x)));
|
||||
}
|
||||
else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
|
||||
else if (C_DECL_REGISTER (x))
|
||||
{
|
||||
if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
|
||||
{
|
||||
|
@ -2625,17 +2625,6 @@ c_mark_addressable (tree exp)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* If we are making this addressable due to its having
|
||||
volatile components, give a different error message. Also
|
||||
handle the case of an unnamed parameter by not trying
|
||||
to give the name. */
|
||||
|
||||
else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x)))
|
||||
{
|
||||
error ("cannot put object with volatile field into register");
|
||||
return false;
|
||||
}
|
||||
|
||||
pedwarn ("address of register variable `%s' requested",
|
||||
IDENTIFIER_POINTER (DECL_NAME (x)));
|
||||
}
|
||||
|
|
|
@ -1413,14 +1413,6 @@ definitions) that the increments will be evaluated in any particular
|
|||
order. Either increment might happen first. @code{func} might get the
|
||||
arguments @samp{2, 3}, or it might get @samp{3, 2}, or even @samp{2, 2}.
|
||||
|
||||
@item
|
||||
Not allowing structures with volatile fields in registers.
|
||||
|
||||
Strictly speaking, there is no prohibition in the ISO C standard
|
||||
against allowing structures with volatile fields in registers, but
|
||||
it does not seem to make any sense and is probably not what you wanted
|
||||
to do. So the compiler will give an error message in this case.
|
||||
|
||||
@item
|
||||
Making certain warnings into errors by default.
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2004-03-28 Joseph S. Myers <jsm@polyomino.org.uk>
|
||||
|
||||
* gcc.dg/940409-1.c: Remove XFAIL.
|
||||
* gcc.dg/reg-vol-struct-1.c: New test.
|
||||
|
||||
2004-03-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* gcc.dg/torture/builtin-wctype-1.c: New test.
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* GCC should allow struct S to be in a register, but it doesn't. This is
|
||||
an obscure corner case, hasn't worked since 1994, and we don't expect it
|
||||
to work anytime soon, hence XFAIL. */
|
||||
/* GCC should allow struct S to be in a register. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
struct S { volatile int field; };
|
||||
int f (register struct S arg); /* { dg-bogus "volatile field" "with arg" { xfail *-*-* } } */
|
||||
int g (register struct S); /* { dg-bogus "volatile field" "no arg" { xfail *-*-* } } */
|
||||
int f (register struct S arg); /* { dg-bogus "volatile field" "with arg" } */
|
||||
int g (register struct S); /* { dg-bogus "volatile field" "no arg" } */
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/* Test cases of structures with volatile fields declared register:
|
||||
should be allowed unless register name given but explicitly taking
|
||||
the address forbidden. */
|
||||
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
struct S { volatile int field; };
|
||||
|
||||
void
|
||||
f (void)
|
||||
{
|
||||
register struct S a;
|
||||
register struct S b[2];
|
||||
register struct S c __asm__("nosuchreg"); /* { dg-error "object with volatile field" "explicit reg name" } */
|
||||
&a; /* { dg-warning "address of register" "explicit address" } */
|
||||
b; /* { dg-warning "address of register" "implicit address" } */
|
||||
}
|
Loading…
Reference in New Issue