Commit 5baeaac0 by Joseph Myers Committed by Joseph Myers

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
parent 4c24abdc
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> 2004-03-27 Ulrich Weigand <uweigand@de.ibm.com>
* function.c (thread_prologue_and_epilogue): Move * function.c (thread_prologue_and_epilogue): Move
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
on information stored in GCC's tree structure. This code implements the on information stored in GCC's tree structure. This code implements the
-aux-info option. -aux-info option.
Copyright (C) 1989, 1991, 1994, 1995, 1997, 1998, 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). Contributed by Ron Guilmette (rfg@segfault.us.com).
This file is part of GCC. This file is part of GCC.
...@@ -531,7 +531,7 @@ gen_decl (tree decl, int is_func_definition, formals_style style) ...@@ -531,7 +531,7 @@ gen_decl (tree decl, int is_func_definition, formals_style style)
ret_val = affix_data_type (ret_val); 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); ret_val = concat ("register ", ret_val, NULL);
if (TREE_PUBLIC (decl)) if (TREE_PUBLIC (decl))
ret_val = concat ("extern ", ret_val, NULL); ret_val = concat ("extern ", ret_val, NULL);
......
...@@ -488,6 +488,7 @@ objc_mark_locals_volatile (void *enclosing_blk) ...@@ -488,6 +488,7 @@ objc_mark_locals_volatile (void *enclosing_blk)
if (TREE_CODE (b->decl) == VAR_DECL if (TREE_CODE (b->decl) == VAR_DECL
|| TREE_CODE (b->decl) == PARM_DECL) || TREE_CODE (b->decl) == PARM_DECL)
{ {
C_DECL_REGISTER (b->decl) = 0;
DECL_REGISTER (b->decl) = 0; DECL_REGISTER (b->decl) = 0;
TREE_THIS_VOLATILE (b->decl) = 1; TREE_THIS_VOLATILE (b->decl) = 1;
} }
...@@ -2901,8 +2902,15 @@ finish_decl (tree decl, tree init, tree asmspec_tree) ...@@ -2901,8 +2902,15 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
/* In conjunction with an ASMSPEC, the `register' /* In conjunction with an ASMSPEC, the `register'
keyword indicates that we should place the variable keyword indicates that we should place the variable
in a particular register. */ in a particular register. */
if (DECL_REGISTER (decl)) if (C_DECL_REGISTER (decl))
DECL_C_HARD_REGISTER (decl) = 1; {
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. /* If this is not a static variable, issue a warning.
It doesn't make any sense to give an ASMSPEC for an 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) ...@@ -2910,7 +2918,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
GCC has accepted -- but ignored -- the ASMSPEC in GCC has accepted -- but ignored -- the ASMSPEC in
this case. */ this case. */
if (TREE_CODE (decl) == VAR_DECL if (TREE_CODE (decl) == VAR_DECL
&& !DECL_REGISTER (decl) && !C_DECL_REGISTER (decl)
&& !TREE_STATIC (decl)) && !TREE_STATIC (decl))
warning ("%Jignoring asm-specifier for non-static local " warning ("%Jignoring asm-specifier for non-static local "
"variable '%D'", decl, decl); "variable '%D'", decl, decl);
...@@ -4527,7 +4535,10 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4527,7 +4535,10 @@ grokdeclarator (tree declarator, tree declspecs,
and in case doing stupid register allocation. */ and in case doing stupid register allocation. */
if (specbits & (1 << (int) RID_REGISTER)) if (specbits & (1 << (int) RID_REGISTER))
DECL_REGISTER (decl) = 1; {
C_DECL_REGISTER (decl) = 1;
DECL_REGISTER (decl) = 1;
}
/* Record constancy and volatility. */ /* Record constancy and volatility. */
c_apply_type_quals_to_decl (type_quals, decl); c_apply_type_quals_to_decl (type_quals, decl);
...@@ -4536,7 +4547,16 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4536,7 +4547,16 @@ grokdeclarator (tree declarator, tree declspecs,
Otherwise, the fact that those components are volatile Otherwise, the fact that those components are volatile
will be ignored, and would even crash the compiler. */ will be ignored, and would even crash the compiler. */
if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl))) 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 #ifdef ENABLE_CHECKING
/* This is the earliest point at which we might know the assembler /* This is the earliest point at which we might know the assembler
...@@ -4684,7 +4704,7 @@ get_parm_info (bool ellipsis) ...@@ -4684,7 +4704,7 @@ get_parm_info (bool ellipsis)
{ {
if (TREE_THIS_VOLATILE (b->decl) if (TREE_THIS_VOLATILE (b->decl)
|| TREE_READONLY (b->decl) || TREE_READONLY (b->decl)
|| DECL_REGISTER (b->decl)) || C_DECL_REGISTER (b->decl))
error ("'void' as only parameter may not be qualified"); error ("'void' as only parameter may not be qualified");
/* There cannot be an ellipsis. */ /* There cannot be an ellipsis. */
......
...@@ -115,6 +115,11 @@ struct lang_type GTY(()) ...@@ -115,6 +115,11 @@ struct lang_type GTY(())
been declared. */ been declared. */
#define C_DECL_DECLARED_BUILTIN(EXP) DECL_LANG_FLAG_4 (EXP) #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. /* 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 N.B. Could be simplified if all built-in decls had complete prototypes
(but this is presently difficult because some of them need FILE*). */ (but this is presently difficult because some of them need FILE*). */
......
...@@ -1525,7 +1525,7 @@ build_array_ref (tree array, tree index) ...@@ -1525,7 +1525,7 @@ build_array_ref (tree array, tree index)
tree foo = array; tree foo = array;
while (TREE_CODE (foo) == COMPONENT_REF) while (TREE_CODE (foo) == COMPONENT_REF)
foo = TREE_OPERAND (foo, 0); 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"); pedwarn ("ISO C forbids subscripting `register' array");
else if (! flag_isoc99 && ! lvalue_p (foo)) else if (! flag_isoc99 && ! lvalue_p (foo))
pedwarn ("ISO C90 forbids subscripting non-lvalue array"); pedwarn ("ISO C90 forbids subscripting non-lvalue array");
...@@ -2495,7 +2495,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag) ...@@ -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. /* Return nonzero if REF is an lvalue valid for this language.
Lvalues can be assigned, unless their type has TYPE_READONLY. 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 int
lvalue_p (tree ref) lvalue_p (tree ref)
...@@ -2604,7 +2604,7 @@ c_mark_addressable (tree exp) ...@@ -2604,7 +2604,7 @@ c_mark_addressable (tree exp)
case CONST_DECL: case CONST_DECL:
case PARM_DECL: case PARM_DECL:
case RESULT_DECL: case RESULT_DECL:
if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x) if (C_DECL_REGISTER (x)
&& DECL_NONLOCAL (x)) && DECL_NONLOCAL (x))
{ {
if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x)) if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
...@@ -2616,7 +2616,7 @@ c_mark_addressable (tree exp) ...@@ -2616,7 +2616,7 @@ c_mark_addressable (tree exp)
pedwarn ("register variable `%s' used in nested function", pedwarn ("register variable `%s' used in nested function",
IDENTIFIER_POINTER (DECL_NAME (x))); 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)) if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
{ {
...@@ -2625,17 +2625,6 @@ c_mark_addressable (tree exp) ...@@ -2625,17 +2625,6 @@ c_mark_addressable (tree exp)
return false; 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", pedwarn ("address of register variable `%s' requested",
IDENTIFIER_POINTER (DECL_NAME (x))); IDENTIFIER_POINTER (DECL_NAME (x)));
} }
......
...@@ -1414,14 +1414,6 @@ order. Either increment might happen first. @code{func} might get the ...@@ -1414,14 +1414,6 @@ 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}. arguments @samp{2, 3}, or it might get @samp{3, 2}, or even @samp{2, 2}.
@item @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. Making certain warnings into errors by default.
Some ISO C testsuites report failure when the compiler does not produce Some ISO C testsuites report failure when the compiler does not produce
......
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> 2004-03-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/torture/builtin-wctype-1.c: New test. * gcc.dg/torture/builtin-wctype-1.c: New test.
......
/* GCC should allow struct S to be in a register, but it doesn't. This is /* GCC should allow struct S to be in a register. */
an obscure corner case, hasn't worked since 1994, and we don't expect it
to work anytime soon, hence XFAIL. */
/* { dg-do compile } */ /* { dg-do compile } */
struct S { volatile int field; }; struct S { volatile int field; };
int f (register struct S arg); /* { dg-bogus "volatile field" "with 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" { xfail *-*-* } } */ int g (register struct S); /* { dg-bogus "volatile field" "no arg" } */
/* 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" } */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment