+/* Performs sanity checks on the TYPE and WIDTH of the bit-field NAME,
+ replacing with appropriate values if they are invalid. */
+static void
+check_bitfield_type_and_width (tree *type, tree *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 != boolean_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 == boolean_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;
+ *width = build_int_2 (w, 0);
+ }
+ 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);
+}
+\f