+2008-08-13 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c/15236
+ * diagnostic.c (pedwarn_at): New.
+ * toplev.h (pedwarn_at): Declare.
+ * c-tree.h (build_enumerator): Update declaration.
+ * c-decl.c (finish_enum): Update comment.
+ (build_enumerator): Take a location parameter. Give a pedwarn but do
+ not perform any conversion.
+ * c-parser.c (c_parser_enum_specifier): Set correct location for
+ enumerator.
+
2008-08-13 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR 35635
/* The ISO C Standard mandates enumerators to have type int,
even though the underlying type of an enum type is
- unspecified. Here we convert any enumerators that fit in
- an int to type int, to avoid promotions to unsigned types
- when comparing integers with enumerators that fit in the
- int range. When -pedantic is given, build_enumerator()
- would have already taken care of those that don't fit. */
+ unspecified. However, GCC allows enumerators of any
+ integer type as an extensions. Here we convert any
+ enumerators that fit in an int to type int, to avoid
+ promotions to unsigned types when comparing integers with
+ enumerators that fit in the int range. When -pedantic is
+ given, build_enumerator() would have already warned about
+ those that don't fit. */
if (int_fits_type_p (ini, integer_type_node))
tem = integer_type_node;
else
Assignment of sequential values by default is handled here. */
tree
-build_enumerator (struct c_enum_contents *the_enum, tree name, tree value)
+build_enumerator (struct c_enum_contents *the_enum, tree name, tree value,
+ location_t value_loc)
{
tree decl, type;
if (the_enum->enum_overflow)
error ("overflow in enumeration values");
}
-
- if (pedantic && !int_fits_type_p (value, integer_type_node))
- {
- pedwarn (OPT_pedantic, "ISO C restricts enumerator values to range of %<int%>");
- /* XXX This causes -pedantic to change the meaning of the program.
- Remove? -zw 2004-03-15 */
- value = convert (integer_type_node, value);
- }
+ /* Even though the underlying type of an enum is unspecified, the
+ type of enumeration constants is explicitly defined as int
+ (6.4.4.3/2 in the C99 Standard). GCC allows any integer type as
+ an extension. */
+ else if (!int_fits_type_p (value, integer_type_node))
+ pedwarn_at (value_loc, OPT_pedantic,
+ "ISO C restricts enumerator values to range of %<int%>");
/* Set basis for default for next value. */
the_enum->enum_next_value = build_binary_op (PLUS_EXPR, value,
bool seen_comma;
c_token *token;
location_t comma_loc;
+ location_t value_loc;
if (c_parser_next_token_is_not (parser, CPP_NAME))
{
c_parser_error (parser, "expected identifier");
enum_id = token->value;
/* Set the location in case we create a decl now. */
c_parser_set_source_position_from_token (token);
+ value_loc = token->location;
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_EQ))
{
c_parser_consume_token (parser);
+ value_loc = c_parser_peek_token (parser)->location;
+ /* This may call cb_line_change and alter the input_location. */
enum_value = c_parser_expr_no_commas (parser, NULL).value;
}
else
enum_value = NULL_TREE;
- enum_decl = build_enumerator (&the_enum, enum_id, enum_value);
+ enum_decl = build_enumerator (&the_enum, enum_id, enum_value,
+ value_loc);
TREE_CHAIN (enum_decl) = values;
values = enum_decl;
seen_comma = false;
extern int quals_from_declspecs (const struct c_declspecs *);
extern struct c_declarator *build_array_declarator (tree, struct c_declspecs *,
bool, bool);
-extern tree build_enumerator (struct c_enum_contents *, tree, tree);
+extern tree build_enumerator (struct c_enum_contents *, tree, tree, location_t);
extern tree check_for_loop_decls (void);
extern void mark_forward_parm_decls (void);
extern void declare_parm_level (void);
return report_diagnostic (&diagnostic);
}
-/* A "pedantic" warning: issues a warning unless -pedantic-errors was
- given on the command line, in which case it issues an error. Use
- this for diagnostics required by the relevant language standard,
- if you have chosen not to make them errors.
+/* A "pedantic" warning at LOCATION: issues a warning unless
+ -pedantic-errors was given on the command line, in which case it
+ issues an error. Use this for diagnostics required by the relevant
+ language standard, if you have chosen not to make them errors.
Note that these diagnostics are issued independent of the setting
of the -pedantic command-line switch. To get a warning enabled
Returns true if the warning was printed, false if it was inhibited. */
+bool
+pedwarn_at (location_t location, int opt, const char *gmsgid, ...)
+{
+ diagnostic_info diagnostic;
+ va_list ap;
+
+ va_start (ap, gmsgid);
+ diagnostic_set_info (&diagnostic, gmsgid, &ap, location, DK_PEDWARN);
+ diagnostic.option_index = opt;
+ va_end (ap);
+ return report_diagnostic (&diagnostic);
+}
+
+/* Equivalent to pedwarn_at using INPUT_LOCATION. */
+
bool
pedwarn (int opt, const char *gmsgid, ...)
{
+2008-08-13 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR c/15236
+ * gcc.dg/pr15236.c: New.
+ * gcc.dg/torture/pr25183.c: Update.
+
2008-08-13 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR 35635
--- /dev/null
+/* PR 15236: pedantic switch modifies treatment of non-ISO compliant
+ enumerations. */
+/* { dg-do compile } */
+/* { dg-options "-Wall -Wextra -pedantic-errors -Wconversion" } */
+typedef enum OMX_ERRORTYPE
+{
+ OMX_ErrorNone = 0,
+ OMX_ErrorInsufficientResources = 0x80001000 /* { dg-error "ISO C restricts enumerator values to range of .int." } */
+} OMX_ERRORTYPE;
int error()
{
switch (E_) {
- case err_IO : break; /* { dg-warning "overflow" } */
- case err_NM : break; /* { dg-warning "overflow" } */
- case err_EOF : break; /* { dg-warning "overflow" } */
- case err_SE : break; /* { dg-warning "overflow" } */
- case err_PT : break; /* { dg-warning "overflow" } */
+ case err_IO : break;
+ case err_NM : break;
+ case err_EOF : break;
+ case err_SE : break;
+ case err_PT : break;
default : return 0;
}
}
ATTRIBUTE_NORETURN;
/* Pass one of the OPT_W* from options.h as the first parameter. */
extern bool pedwarn (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
+extern bool pedwarn_at (location_t, int, const char *, ...)
extern bool permerror (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
extern bool permerror_at (location_t, const char *, ...)
ATTRIBUTE_GCC_DIAG(2,3);