re PR c/15236 (pedantic switch modifies treatment of non-ISO compliant enumerations)

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.
testsuite/
	* gcc.dg/pr15236.c: New.
	* gcc.dg/torture/pr25183.c: Update.

From-SVN: r139050
This commit is contained in:
Manuel López-Ibáñez 2008-08-13 10:19:03 +00:00
parent 374035cb20
commit 85790e6677
9 changed files with 75 additions and 25 deletions

View File

@ -1,3 +1,15 @@
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

View File

@ -5877,11 +5877,13 @@ finish_enum (tree enumtype, tree values, tree attributes)
/* 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
@ -5933,7 +5935,8 @@ finish_enum (tree enumtype, tree values, tree attributes)
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;
@ -5967,14 +5970,13 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value)
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,

View File

@ -1630,6 +1630,7 @@ c_parser_enum_specifier (c_parser *parser)
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");
@ -1641,15 +1642,19 @@ c_parser_enum_specifier (c_parser *parser)
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;

View File

@ -462,7 +462,7 @@ extern void c_print_identifier (FILE *, tree, int);
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);

View File

@ -537,10 +537,10 @@ warning_at (location_t location, int opt, const char *gmsgid, ...)
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
@ -550,6 +550,21 @@ warning_at (location_t location, int opt, const char *gmsgid, ...)
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, ...)
{

View File

@ -1,3 +1,9 @@
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

View File

@ -0,0 +1,9 @@
/* 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;

View File

@ -12,11 +12,11 @@ static enum err E_;
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;
}
}

View File

@ -65,6 +65,7 @@ extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
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);