OSDN Git Service

* c-tree.h (C_DECL_REGISTER): New.
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 28 Mar 2004 00:31:41 +0000 (00:31 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 28 Mar 2004 00:31:41 +0000 (00:31 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@80037 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-aux-info.c
gcc/c-decl.c
gcc/c-tree.h
gcc/c-typeck.c
gcc/doc/trouble.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/940409-1.c
gcc/testsuite/gcc.dg/reg-vol-struct-1.c [new file with mode: 0644]

index 15a79c9..7a874bd 100644 (file)
@@ -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
index e785ade..2ef7324 100644 (file)
@@ -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);
index e743479..b2a0bf5 100644 (file)
@@ -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.  */
index bd53dbc..eb167ca 100644 (file)
@@ -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*).  */
index 59bccab..64b568c 100644 (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)));
          }
index b578536..b2112d3 100644 (file)
@@ -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
index 2d35d02..0b19b8c 100644 (file)
@@ -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.
index e5049d9..2d20b89 100644 (file)
@@ -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 (file)
index 0000000..7751bb4
--- /dev/null
@@ -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" } */
+}