aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/c-aux-info.c4
-rw-r--r--gcc/c-decl.c32
-rw-r--r--gcc/c-tree.h5
-rw-r--r--gcc/c-typeck.c19
-rw-r--r--gcc/doc/trouble.texi8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/940409-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/reg-vol-struct-1.c18
9 files changed, 78 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 15a79c9319c..7a874bdc8d0 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 e785ade2239..2ef7324dd14 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 e74347997c5..b2a0bf5c87c 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 bd53dbc56e9..eb167ca050e 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 59bccab3930..64b568cc218 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 b5785360fef..b2112d36732 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 2d35d02bd77..0b19b8c6049 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 e5049d9030e..2d20b891f3f 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 00000000000..7751bb4a117
--- /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" } */
+}