This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch to fix gcc.dg/940409-1.c (register structs with volatilefields)


This patch gets rid of one gratuitous documented nonconformance, an
error for structures with volatile fields declared register.  The
manual seemed under the obsolete impression that declaring something
"register" has more significance than "diagnose any attempt to take
the address of this".  Since however DECL_REGISTER does get used in
code generation in some places, and the comments suggest crashes might
arise if this were set for structures with volatile fields, this patch
separates it from the front end flag that purely indicates whether
something was declared register and should have the associated
diagnostics.

Bootstrapped with no regressions on i686-pc-linux-gnu.  Applied to
mainline.

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-28  Joseph S. Myers  <jsm@polyomino.org.uk>

	* gcc.dg/940409-1.c: Remove XFAIL.
	* gcc.dg/reg-vol-struct-1.c: New test.

diff -rupN GCC.orig/gcc/c-aux-info.c GCC/gcc/c-aux-info.c
--- GCC.orig/gcc/c-aux-info.c	2003-10-04 07:28:47.000000000 +0000
+++ GCC/gcc/c-aux-info.c	2004-03-27 16:24:51.000000000 +0000
@@ -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_definit
 
   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 -rupN GCC.orig/gcc/c-decl.c GCC/gcc/c-decl.c
--- GCC.orig/gcc/c-decl.c	2004-03-24 10:50:33.000000000 +0000
+++ GCC/gcc/c-decl.c	2004-03-27 16:43:52.000000000 +0000
@@ -488,6 +488,7 @@ objc_mark_locals_volatile (void *enclosi
 	  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 
 	      /* 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 
 		 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 de
        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 de
        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 -rupN GCC.orig/gcc/c-tree.h GCC/gcc/c-tree.h
--- GCC.orig/gcc/c-tree.h	2004-03-24 10:50:33.000000000 +0000
+++ GCC/gcc/c-tree.h	2004-03-27 16:24:27.000000000 +0000
@@ -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 -rupN GCC.orig/gcc/c-typeck.c GCC/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c	2004-03-27 16:17:07.000000000 +0000
+++ GCC/gcc/c-typeck.c	2004-03-27 20:48:43.000000000 +0000
@@ -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, tre
 
 /* 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 -rupN GCC.orig/gcc/doc/trouble.texi GCC/gcc/doc/trouble.texi
--- GCC.orig/gcc/doc/trouble.texi	2004-03-14 22:25:10.000000000 +0000
+++ GCC/gcc/doc/trouble.texi	2004-03-27 16:18:30.000000000 +0000
@@ -1414,14 +1414,6 @@ order.  Either increment might happen fi
 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 -rupN GCC.orig/gcc/testsuite/gcc.dg/940409-1.c GCC/gcc/testsuite/gcc.dg/940409-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/940409-1.c	2000-06-29 03:10:01.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/940409-1.c	2004-03-27 16:19:08.000000000 +0000
@@ -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 -rupN GCC.orig/gcc/testsuite/gcc.dg/reg-vol-struct-1.c GCC/gcc/testsuite/gcc.dg/reg-vol-struct-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/reg-vol-struct-1.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/reg-vol-struct-1.c	2004-03-28 00:23:26.000000000 +0000
@@ -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" } */
+}

-- 
Joseph S. Myers
jsm@polyomino.org.uk


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]