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]

Re: c: Bitfield fixes for PRs 3325, 3326


Joseph S. Myers wrote:-

> Define ENUM_BITFIELD to use __extension__ (for GCC 2.8 or later - I think
> older versions may not have supported __extension__ in that place).

Nah, that doesn't work as the macro is used for casts as well.  I don't
fancy fixing this as it becomes intrusive; I think the patch should be
able to go in without it.  This patch addresses your other points, though,
and also makes overly-wide bitfields a hard error.  Full test cases
included.

OK to commit?

Neil.

	* c-decl.c (enum_decl_context): Remove BITFIELD.
	(grokdeclarator): Take bitfield width as an input.
	Ensure bitfields are given the correct type.  Perform
	bitfield width validation with build_bitfield_integer_type
	rather than waiting for finish_struct.
	(grok_typename, grok_typename_in_parm_context, start_decl,
	push_parmdecl, grokfield, start_function): Update calls to
	grokdeclarator.
	(build_bitfield_integer_type): New function.
	(finish_struct): Move bitfield validation to grokdeclarator
	and build_bitfield_integer_type. 
	* tree.c (build_nonstandard_integer_type): New function.
	* tree.h (build_nonstandard_integer_type): New prototype.
objc:
	* objc-act.c (objc_copy_list): Remove DECL_INITIAL kludge.
testsuite:
	* gcc.c-torture/execute/bitfld-1.c: New tests.
	* gcc.dg/bitfld-1.c: Diagnostic tests.

Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.289
diff -u -p -r1.289 c-decl.c
--- c-decl.c	2002/01/25 20:45:47	1.289
+++ c-decl.c	2002/01/26 13:02:30
@@ -53,7 +53,6 @@ enum decl_context
   FUNCDEF,			/* Function definition */
   PARM,				/* Declaration of parm before function body */
   FIELD,			/* Declaration inside struct or union */
-  BITFIELD,			/* Likewise but with specified width */
   TYPENAME};			/* Typename (inside cast or sizeof)  */
 
 
@@ -276,12 +275,13 @@ static tree lookup_tag			PARAMS ((enum t
 						 struct binding_level *, int));
 static tree lookup_tag_reverse		PARAMS ((tree));
 static tree grokdeclarator		PARAMS ((tree, tree, enum decl_context,
-						 int));
+						 int, tree));
 static tree grokparms			PARAMS ((tree, int));
 static void layout_array_type		PARAMS ((tree));
 static tree c_make_fname_decl           PARAMS ((tree, int));
 static void c_expand_body               PARAMS ((tree, int, int));
 static void warn_if_shadowing		PARAMS ((tree, tree));
+static tree build_bitfield_integer_type	PARAMS ((tree, tree, const char *));
 
 /* C-specific option variables.  */
 
@@ -319,7 +319,7 @@ int flag_noniso_default_format_attribute
    being traditional.  */
 int flag_allow_single_precision = 0;
 
-/* Nonzero means to treat bitfields as signed unless they say `unsigned'.  */
+/* Nonzero means to treat bit-fields as signed unless they say `unsigned'.  */
 
 int flag_signed_bitfields = 1;
 int explicit_flag_signed_bitfields = 0;
@@ -3390,7 +3390,8 @@ groktypename (typename)
 
   split_specs_attrs (TREE_PURPOSE (typename), &specs, &attrs);
 
-  typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0);
+  typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0,
+			     NULL_TREE);
 
   /* Apply attributes.  */
   decl_attributes (&typename, attrs, 0);
@@ -3408,7 +3409,7 @@ groktypename_in_parm_context (typename)
     return typename;
   return grokdeclarator (TREE_VALUE (typename),
 			 TREE_PURPOSE (typename),
-			 PARM, 0);
+			 PARM, 0, NULL_TREE);
 }
 
 /* Decode a declarator in an ordinary declaration or data definition.
@@ -3441,7 +3442,7 @@ start_decl (declarator, declspecs, initi
     deprecated_state = DEPRECATED_SUPPRESS;
 
   decl = grokdeclarator (declarator, declspecs,
-			 NORMAL, initialized);
+			 NORMAL, initialized, NULL_TREE);
   
   deprecated_state = DEPRECATED_NORMAL;
 
@@ -3819,7 +3820,8 @@ push_parm_decl (parm)
   immediate_size_expand = 0;
 
   decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)),
-			 TREE_PURPOSE (TREE_PURPOSE (parm)), PARM, 0);
+			 TREE_PURPOSE (TREE_PURPOSE (parm)),
+			 PARM, 0, NULL_TREE);
   decl_attributes (&decl, TREE_VALUE (parm), 0);
 
 #if 0
@@ -3979,6 +3981,92 @@ complete_array_type (type, initial_value
   return value;
 }
 
+/* A bit-field NAME should have an integer type whose precision
+   accurately reflects its WIDTH.  If TYPE is good for that, return
+   it, otherwise create and return the appropriate type.
+
+   This routine also performs sanity checks on the bit-field's type
+   and width, and uses appropriate values if they are invalid.  */
+static tree
+build_bitfield_integer_type (type, width, orig_name)
+     tree type, width;
+     const char *orig_name;
+{
+  tree type_mv;
+  unsigned int max_width;
+  unsigned HOST_WIDE_INT w;
+  const char *name = orig_name ? orig_name: _("<anonymous>");
+
+  /* Necessary?  */
+  STRIP_NOPS (width);
+
+  /* Detect and ignore out of range field width and process valid
+     field widths.  */
+  if (TREE_CODE (width) != INTEGER_CST)
+    {
+      error ("bit-field `%s' width not an integer constant", name);
+      width = integer_one_node;
+    }
+  else
+    {
+      constant_expression_warning (width);
+      if (tree_int_cst_sgn (width) < 0)
+	{
+	  error ("negative width in bit-field `%s'", name);
+	  width = integer_one_node;
+	}
+      else if (integer_zerop (width) && orig_name)
+	{
+	  error ("zero width for bit-field `%s'", name);
+	  width = integer_one_node;
+	}
+    }
+
+  /* Detect invalid bit-field type.  */
+  if (TREE_CODE (type) != INTEGER_TYPE
+      && TREE_CODE (type) != BOOLEAN_TYPE
+      && TREE_CODE (type) != ENUMERAL_TYPE)
+    {
+      error ("bit-field `%s' has invalid type", name);
+      type = unsigned_type_node;
+    }
+
+  type_mv = TYPE_MAIN_VARIANT (type);
+  if (pedantic
+      && type_mv != integer_type_node
+      && type_mv != unsigned_type_node
+      && type_mv != c_bool_type_node
+      /* Accept an enum that's equivalent to int or unsigned int.  */
+      && (TREE_CODE (type) != ENUMERAL_TYPE
+	  || TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)))
+    pedwarn ("type of bit-field `%s' is a GCC extension", name);
+
+  if (type_mv == c_bool_type_node)
+    max_width = CHAR_TYPE_SIZE;
+  else
+    max_width = TYPE_PRECISION (type);
+
+  if (0 < compare_tree_int (width, max_width))
+    {
+      error ("width of `%s' exceeds its type", name);
+      w = max_width;
+    }
+  else
+    w = tree_low_cst (width, 1);
+
+  if (TREE_CODE (type) == ENUMERAL_TYPE
+      && (w < min_precision (TYPE_MIN_VALUE (type), TREE_UNSIGNED (type))
+	  || w < min_precision (TYPE_MAX_VALUE (type), TREE_UNSIGNED (type))))
+    warning ("`%s' is narrower than values of its type", name);
+
+  /* The type of a bit-field should have precision the same as the
+     bit-field's width.  */
+  if (w != TYPE_PRECISION (type))
+    type = build_nonstandard_integer_type (w, TREE_UNSIGNED (type));
+
+  return type;
+}
+
 /* Given declspecs and a declarator,
    determine the name and type of the object declared
    and construct a ..._DECL node for it.
@@ -3998,8 +4086,9 @@ complete_array_type (type, initial_value
      TYPENAME if for a typename (in a cast or sizeof).
       Don't make a DECL node; just return the ..._TYPE node.
      FIELD for a struct or union field; make a FIELD_DECL.
-     BITFIELD for a field with specified width.
    INITIALIZED is 1 if the decl has an initializer.
+   WIDTH is non-NULL for bit-fields, and is an INTEGER_CST node representing
+   the width of the bit-field.
 
    In the TYPENAME case, DECLARATOR is really an absolute declarator.
    It may also be so in the PARM case, for a prototype where the
@@ -4009,11 +4098,12 @@ complete_array_type (type, initial_value
    and `extern' are interpreted.  */
 
 static tree
-grokdeclarator (declarator, declspecs, decl_context, initialized)
+grokdeclarator (declarator, declspecs, decl_context, initialized, width)
      tree declspecs;
      tree declarator;
      enum decl_context decl_context;
      int initialized;
+     tree width;
 {
   int specbits = 0;
   tree spec;
@@ -4028,20 +4118,17 @@ grokdeclarator (declarator, declspecs, d
   int explicit_char = 0;
   int defaulted_int = 0;
   tree typedef_decl = 0;
-  const char *name;
+  const char *name, *orig_name;
   tree typedef_type = 0;
   int funcdef_flag = 0;
   enum tree_code innermost_code = ERROR_MARK;
-  int bitfield = 0;
   int size_varies = 0;
   tree decl_attr = NULL_TREE;
   tree array_ptr_quals = NULL_TREE;
   int array_parm_static = 0;
   tree returned_attrs = NULL_TREE;
+  bool bitfield = width != NULL_TREE;
 
-  if (decl_context == BITFIELD)
-    bitfield = 1, decl_context = FIELD;
-
   if (decl_context == FUNCDEF)
     funcdef_flag = 1, decl_context = NORMAL;
 
@@ -4073,6 +4160,7 @@ grokdeclarator (declarator, declspecs, d
 	default:
 	  abort ();
 	}
+    orig_name = name;
     if (name == 0)
       name = "type name";
   }
@@ -4284,9 +4372,9 @@ grokdeclarator (declarator, declspecs, d
     }
 
   /* Decide whether an integer type is signed or not.
-     Optionally treat bitfields as signed by default.  */
+     Optionally treat bit-fields as signed by default.  */
   if (specbits & 1 << (int) RID_UNSIGNED
-      /* Traditionally, all bitfields are unsigned.  */
+      /* Traditionally, all bit-fields are unsigned.  */
       || (bitfield && flag_traditional
 	  && (! explicit_flag_signed_bitfields || !flag_signed_bitfields))
       || (bitfield && ! flag_signed_bitfields
@@ -4359,6 +4447,11 @@ grokdeclarator (declarator, declspecs, d
 	}
     }
 
+  /* A bit-field needs its type to have precision equal to its width,
+     rather than the precision of the specified standard type.  */
+  if (bitfield)
+    type = build_bitfield_integer_type (type, width, orig_name);
+
   /* Figure out the type qualifiers for the declaration.  There are
      two ways a declaration can become qualified.  One is something
      like `const int i' where the `const' is explicit.  Another is
@@ -5008,7 +5101,6 @@ grokdeclarator (declarator, declspecs, d
     else if (decl_context == FIELD)
       {
 	/* Structure field.  It may not be a function.  */
-
 	if (TREE_CODE (type) == FUNCTION_TYPE)
 	  {
 	    error ("field `%s' declared as a function", name);
@@ -5032,6 +5124,29 @@ grokdeclarator (declarator, declspecs, d
 #endif
 	  }
 	decl = build_decl (FIELD_DECL, declarator, type);
+	if (bitfield)
+	  {
+	    DECL_SIZE (decl) = bitsize_int (TYPE_PRECISION (type));
+	    DECL_BIT_FIELD (decl) = 1;
+	    SET_DECL_C_BIT_FIELD (decl);
+
+	    /* Bit-field width 0 => force desired amount of alignment.  */
+	    if (TYPE_PRECISION (type) == 0)
+	      {
+#ifdef EMPTY_FIELD_BOUNDARY
+		DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl),
+					 EMPTY_FIELD_BOUNDARY);
+#endif
+#ifdef PCC_BITFIELD_TYPE_MATTERS
+		if (PCC_BITFIELD_TYPE_MATTERS)
+		  {
+		    DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl),
+					     TYPE_ALIGN (type));
+		    DECL_USER_ALIGN (decl) |= TYPE_USER_ALIGN (type);
+		  }
+#endif
+	      }
+	  }
 	DECL_NONADDRESSABLE_P (decl) = bitfield;
 
 	if (size_varies)
@@ -5534,7 +5649,7 @@ start_struct (code, name)
 
 /* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)
    of a structure component, returning a FIELD_DECL node.
-   WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node.
+   WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node.
 
    This is done during the parsing of the struct declaration.
    The FIELD_DECL nodes are chained together and the lot of them
@@ -5560,10 +5675,9 @@ grokfield (filename, line, declarator, d
 	}
     }
 
-  value = grokdeclarator (declarator, declspecs, width ? BITFIELD : FIELD, 0);
+  value = grokdeclarator (declarator, declspecs, FIELD, 0, width);
 
   finish_decl (value, NULL_TREE, NULL_TREE);
-  DECL_INITIAL (value) = width;
 
   maybe_objc_check_decl (value);
   return value;
@@ -5615,10 +5729,7 @@ finish_struct (t, fieldlist, attributes)
 		 fieldlist ? _("named members") : _("members"));
     }
 
-  /* Install struct as DECL_CONTEXT of each field decl.
-     Also process specified field sizes,m which is found in the DECL_INITIAL.
-     Store 0 there, except for ": 0" fields (so we can find them
-     and delete them, below).  */
+  /* Install struct as DECL_CONTEXT of each field decl.  */
 
   saw_named_field = 0;
   for (x = fieldlist; x; x = TREE_CHAIN (x))
@@ -5653,94 +5764,8 @@ finish_struct (t, fieldlist, attributes)
       if (TREE_TYPE (x) == t)
 	error ("nested redefinition of `%s'",
 	       IDENTIFIER_POINTER (TYPE_NAME (t)));
-
-      /* Detect invalid bit-field size.  */
-      if (DECL_INITIAL (x))
-	STRIP_NOPS (DECL_INITIAL (x));
-      if (DECL_INITIAL (x))
-	{
-	  if (TREE_CODE (DECL_INITIAL (x)) == INTEGER_CST)
-	    constant_expression_warning (DECL_INITIAL (x));
-	  else
-	    {
-	      error_with_decl (x,
-			       "bit-field `%s' width not an integer constant");
-	      DECL_INITIAL (x) = NULL;
-	    }
-	}
 
-      /* Detect invalid bit-field type.  */
-      if (DECL_INITIAL (x)
-	  && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
-	  && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
-	  && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
-	{
-	  error_with_decl (x, "bit-field `%s' has invalid type");
-	  DECL_INITIAL (x) = NULL;
-	}
-
-      if (DECL_INITIAL (x) && pedantic
-	  && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
-	  && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
-	  && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node
-	  /* Accept an enum that's equivalent to int or unsigned int.  */
-	  && !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
-	       && (TYPE_PRECISION (TREE_TYPE (x))
-		   == TYPE_PRECISION (integer_type_node))))
-	pedwarn_with_decl (x, "bit-field `%s' type invalid in ISO C");
-
-      /* Detect and ignore out of range field width and process valid
-	 field widths.  */
-      if (DECL_INITIAL (x))
-	{
-	  int max_width
-	    = (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node
-	       ? CHAR_TYPE_SIZE : TYPE_PRECISION (TREE_TYPE (x)));
-
-	  if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
-	    error_with_decl (x, "negative width in bit-field `%s'");
-	  else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
-	    pedwarn_with_decl (x, "width of `%s' exceeds its type");
-	  else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
-	    error_with_decl (x, "zero width for bit-field `%s'");
-	  else
-	    {
-	      /* The test above has assured us that TREE_INT_CST_HIGH is 0.  */
-	      unsigned HOST_WIDE_INT width
-		= tree_low_cst (DECL_INITIAL (x), 1);
-
-	      if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
-		  && (width < min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)),
-					     TREE_UNSIGNED (TREE_TYPE (x)))
-		      || (width
-			  < min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
-					   TREE_UNSIGNED (TREE_TYPE (x))))))
-		warning_with_decl (x,
-				   "`%s' is narrower than values of its type");
-
-	      DECL_SIZE (x) = bitsize_int (width);
-	      DECL_BIT_FIELD (x) = 1;
-	      SET_DECL_C_BIT_FIELD (x);
-
-	      if (width == 0)
-		{
-		  /* field size 0 => force desired amount of alignment.  */
-#ifdef EMPTY_FIELD_BOUNDARY
-		  DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
-#endif
-#ifdef PCC_BITFIELD_TYPE_MATTERS
-		  if (PCC_BITFIELD_TYPE_MATTERS)
-		    {
-		      DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
-					    TYPE_ALIGN (TREE_TYPE (x)));
-		      DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
-		    }
-#endif
-		}
-	    }
-	}
-
-      else if (TREE_TYPE (x) != error_mark_node)
+      if (TREE_TYPE (x) != error_mark_node && !DECL_BIT_FIELD (x))
 	{
 	  unsigned int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT
 				    : TYPE_ALIGN (TREE_TYPE (x)));
@@ -5752,8 +5777,6 @@ finish_struct (t, fieldlist, attributes)
 	    DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
 	}
 
-      DECL_INITIAL (x) = 0;
-
       /* Detect flexible array member in an invalid context.  */
       if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
 	  && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE
@@ -6178,7 +6201,7 @@ start_function (declspecs, declarator, a
   /* Don't expand any sizes in the return type of the function.  */
   immediate_size_expand = 0;
 
-  decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1);
+  decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL_TREE);
 
   /* If the declarator is not suitable for a function definition,
      cause a syntax error.  */
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.233
diff -u -p -r1.233 tree.c
--- tree.c	2002/01/25 20:45:47	1.233
+++ tree.c	2002/01/26 13:02:42
@@ -3758,6 +3758,29 @@ build_index_type (maxval)
     return itype;
 }
 
+/* Builds a signed or unsigned integer type of precision PRECISION.
+   Used for C bitfields whose precision does not match that of
+   built-in target types.  */
+tree
+build_nonstandard_integer_type (precision, unsignedp)
+     unsigned HOST_WIDE_INT precision;
+     int unsignedp;
+{
+  tree itype = make_node (INTEGER_TYPE);
+
+  TYPE_PRECISION (itype) = precision;
+
+  if (unsignedp)
+    fixup_unsigned_type (itype);
+  else
+    fixup_signed_type (itype);
+
+  if (host_integerp (TYPE_MAX_VALUE (itype), 1))
+    return type_hash_canon (tree_low_cst (TYPE_MAX_VALUE (itype), 1), itype);
+
+  return itype;
+}
+
 /* Create a range of some discrete type TYPE (an INTEGER_TYPE,
    ENUMERAL_TYPE, BOOLEAN_TYPE, or CHAR_TYPE), with
    low bound LOWVAL and high bound HIGHVAL.
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.300
diff -u -p -r1.300 tree.h
--- tree.h	2002/01/25 20:45:48	1.300
+++ tree.h	2002/01/26 13:02:50
@@ -2860,6 +2860,7 @@ extern tree getdecls				PARAMS ((void));
 /* Function to return the chain of structure tags in the current scope level.  */
 extern tree gettags				PARAMS ((void));
 
+extern tree build_nonstandard_integer_type	PARAMS ((unsigned int, int));
 extern tree build_range_type PARAMS ((tree, tree, tree));
 
 /* In alias.c */
Index: objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.123
diff -u -p -r1.123 objc-act.c
--- objc-act.c	2002/01/08 18:03:11	1.123
+++ objc-act.c	2002/01/26 13:03:10
@@ -2393,13 +2393,6 @@ objc_copy_list (list, head)
   while (list)
     {
       tail = copy_node (list);
-
-      /* The following statement fixes a bug when inheriting instance
-	 variables that are declared to be bitfields. finish_struct
-	 expects to find the width of the bitfield in DECL_INITIAL.  */
-      if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0)
-	DECL_INITIAL (tail) = DECL_SIZE (tail);
-
       newlist = chainon (newlist, tail);
       list = TREE_CHAIN (list);
     }
Index: testsuite/gcc.c-torture/execute/bitfld-1.c
===================================================================
RCS file: bitfld-1.c
diff -N bitfld-1.c
--- /dev/null	Tue May  5 13:32:27 1998
+++ bitfld-1.c	Sat Jan 26 05:03:23 2002
@@ -0,0 +1,54 @@
+/* Copyright 2002 Free Software Foundation, Inc.
+
+   Tests correct signedness of operations on bitfields; in particular
+   that integer promotions are done correctly, including the case when
+   casts are present.
+
+   The C front end was eliding the cast of an unsigned bitfield to
+   unsigned as a no-op, when in fact it forces a conversion to a
+   full-width unsigned int. (At the time of writing, the C++ front end
+   has a different bug; it erroneously promotes the uncast unsigned
+   bitfield to an unsigned int).
+
+   Source: Neil Booth, 25 Jan 2001, based on PR 3325 (and 3326, which
+   is a different manifestation of the same bug).
+*/
+
+extern void abort ();
+
+int
+main(int argc, char *argv[])
+{
+  struct x { signed int i : 7; unsigned int u : 7; } bit;
+
+  unsigned int u;
+  int i;
+  unsigned int unsigned_result = -13U % 61;
+  int signed_result = -13 % 61;
+
+  bit.u = 61, u = 61; 
+  bit.i = -13, i = -13;
+
+  if (i % u != unsigned_result)
+    abort ();
+  if (i % (unsigned int) u != unsigned_result)
+    abort ();
+
+  /* Somewhat counter-intuitively, bit.u is promoted to an int, making
+     the operands and result an int.  */
+  if (i % bit.u != signed_result)
+    abort ();
+
+  if (bit.i % bit.u != signed_result)
+    abort ();
+
+  /* But with a cast to unsigned int, the unsigned int is promoted to
+     itself as a no-op, and the operands and result are unsigned.  */
+  if (i % (unsigned int) bit.u != unsigned_result)
+    abort ();
+
+  if (bit.i % (unsigned int) bit.u != unsigned_result)
+    abort ();
+
+  return 0;
+}
Index: testsuite/gcc.dg/bitfld-1.c
===================================================================
RCS file: bitfld-1.c
diff -N bitfld-1.c
--- /dev/null	Tue May  5 13:32:27 1998
+++ bitfld-1.c	Sat Jan 26 05:03:23 2002
@@ -0,0 +1,30 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+
+   Tests various diagnostics about a bit-field's type and width.
+
+   Source: Neil Booth, 26 Jan 2001.
+*/
+
+/* { dg-options -pedantic } */
+
+enum foo {e1 = 0, e2, e3, e4, e5};
+
+int x;
+typedef unsigned int ui;
+
+struct bf1
+{
+  unsigned int a: 3.5;		/* { dg-error "integer constant" } */
+  unsigned int b: x;		/* { dg-error "integer constant" } */
+  unsigned int c: -1;		/* { dg-error "negative width" } */
+  unsigned int d: 0;		/* { dg-error "zero width" } */
+  unsigned int : 0;		/* { dg-bogus "zero width" } */
+  unsigned int : 5;
+  double e: 1;			/* { dg-error "invalid type" } */
+  float f: 1;			/* { dg-error "invalid type" } */
+  unsigned long g: 5;		/* { dg-warning "GCC extension" } */
+  ui h: 5;
+  enum foo i: 2;		/* { dg-error "narrower" } */
+  enum foo j: 3;
+  unsigned int k: 256;		/* { dg-error "exceeds its type" } */
+};
Index: testsuite/gcc.dg/uninit-A.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/uninit-A.c,v
retrieving revision 1.2
diff -u -p -r1.2 uninit-A.c
--- uninit-A.c	1999/09/04 15:09:14	1.2
+++ uninit-A.c	2002/01/26 13:03:23
@@ -8,7 +8,9 @@ struct tree
 {
     struct tree *car, *cdr, *wfl;
     int code;
-    struct { int renp:1; int rtnp:1; int rpnp:1; } flags;
+    struct { unsigned int renp:1;
+      unsigned int rtnp:1;
+      unsigned int rpnp:1; } flags;
 };
 typedef struct tree *tree;
 #define NULL_TREE ((tree)0)


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