diff options
author | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2008-08-13 10:19:03 +0000 |
---|---|---|
committer | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2008-08-13 10:19:03 +0000 |
commit | 85790e667775932ee784b9c1636dafcc66ac32d3 (patch) | |
tree | 1628ba21d162d8c904b22105327717febc42c784 /gcc | |
parent | 374035cb20b323d0e95559499fc0089aa4cedff9 (diff) | |
download | gcc-85790e667775932ee784b9c1636dafcc66ac32d3.zip gcc-85790e667775932ee784b9c1636dafcc66ac32d3.tar.gz gcc-85790e667775932ee784b9c1636dafcc66ac32d3.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/c-decl.c | 30 | ||||
-rw-r--r-- | gcc/c-parser.c | 7 | ||||
-rw-r--r-- | gcc/c-tree.h | 2 | ||||
-rw-r--r-- | gcc/diagnostic.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr15236.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr25183.c | 10 | ||||
-rw-r--r-- | gcc/toplev.h | 1 |
9 files changed, 75 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4e03620..2ab8c80 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,17 @@ 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 * c-common.c (conversion_warning): Use a switch. Ignore boolean expressions except for conversions to signed:1 bitfields. Handle diff --git a/gcc/c-decl.c b/gcc/c-decl.c index e30defd..e55e809 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -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, diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 02fc785..6617145 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -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; diff --git a/gcc/c-tree.h b/gcc/c-tree.h index d3e3695..fc76ee3 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -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); diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index cb4c67a..54c2da7 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -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 @@ -551,6 +551,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, ...) { diagnostic_info diagnostic; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 50096c9..7fb2c7d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 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 * gcc.dg/pr35635.c: New. * gcc.dg/Wconversion-integer.c: Update. diff --git a/gcc/testsuite/gcc.dg/pr15236.c b/gcc/testsuite/gcc.dg/pr15236.c new file mode 100644 index 0000000..b01a4e8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr15236.c @@ -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; diff --git a/gcc/testsuite/gcc.dg/torture/pr25183.c b/gcc/testsuite/gcc.dg/torture/pr25183.c index a6c624c..0157b80 100644 --- a/gcc/testsuite/gcc.dg/torture/pr25183.c +++ b/gcc/testsuite/gcc.dg/torture/pr25183.c @@ -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; } } diff --git a/gcc/toplev.h b/gcc/toplev.h index 76718a1..ae61767 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -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); |