diff options
author | Joseph Myers <jsm@polyomino.org.uk> | 2004-03-28 00:31:41 +0000 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2004-03-28 00:31:41 +0000 |
commit | 5baeaac0676b282f9ac9815f245e60e1d2f9b31f (patch) | |
tree | 3acc8edeeba4106c03dff66761ed088a39992358 /gcc | |
parent | 4c24abdce41dacb7cceffefa2bc2fd5edea24c43 (diff) | |
download | gcc-5baeaac0676b282f9ac9815f245e60e1d2f9b31f.zip gcc-5baeaac0676b282f9ac9815f245e60e1d2f9b31f.tar.gz gcc-5baeaac0676b282f9ac9815f245e60e1d2f9b31f.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/c-aux-info.c | 4 | ||||
-rw-r--r-- | gcc/c-decl.c | 32 | ||||
-rw-r--r-- | gcc/c-tree.h | 5 | ||||
-rw-r--r-- | gcc/c-typeck.c | 19 | ||||
-rw-r--r-- | gcc/doc/trouble.texi | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/940409-1.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/reg-vol-struct-1.c | 18 |
9 files changed, 78 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 15a79c9..7a874bd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/c-aux-info.c b/gcc/c-aux-info.c index e785ade..2ef7324 100644 --- a/gcc/c-aux-info.c +++ b/gcc/c-aux-info.c @@ -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); diff --git a/gcc/c-decl.c b/gcc/c-decl.c index e743479..b2a0bf5 100644 --- a/gcc/c-decl.c +++ b/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. */ diff --git a/gcc/c-tree.h b/gcc/c-tree.h index bd53dbc..eb167ca 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -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*). */ diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 59bccab..64b568c 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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))); } diff --git a/gcc/doc/trouble.texi b/gcc/doc/trouble.texi index b578536..b2112d3 100644 --- a/gcc/doc/trouble.texi +++ b/gcc/doc/trouble.texi @@ -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}. @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. Some ISO C testsuites report failure when the compiler does not produce diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2d35d02..0b19b8c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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. diff --git a/gcc/testsuite/gcc.dg/940409-1.c b/gcc/testsuite/gcc.dg/940409-1.c index e5049d9..2d20b891 100644 --- a/gcc/testsuite/gcc.dg/940409-1.c +++ b/gcc/testsuite/gcc.dg/940409-1.c @@ -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" } */ diff --git a/gcc/testsuite/gcc.dg/reg-vol-struct-1.c b/gcc/testsuite/gcc.dg/reg-vol-struct-1.c new file mode 100644 index 0000000..7751bb4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/reg-vol-struct-1.c @@ -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" } */ +} |