aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorManuel López-Ibáñez <manu@gcc.gnu.org>2008-08-13 10:19:03 +0000
committerManuel López-Ibáñez <manu@gcc.gnu.org>2008-08-13 10:19:03 +0000
commit85790e667775932ee784b9c1636dafcc66ac32d3 (patch)
tree1628ba21d162d8c904b22105327717febc42c784 /gcc
parent374035cb20b323d0e95559499fc0089aa4cedff9 (diff)
downloadgcc-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/ChangeLog12
-rw-r--r--gcc/c-decl.c30
-rw-r--r--gcc/c-parser.c7
-rw-r--r--gcc/c-tree.h2
-rw-r--r--gcc/diagnostic.c23
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/pr15236.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr25183.c10
-rw-r--r--gcc/toplev.h1
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);