]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c/15236 (pedantic switch modifies treatment of non-ISO compliant enumerations)
authorManuel López-Ibáñez <manu@gcc.gnu.org>
Wed, 13 Aug 2008 10:19:03 +0000 (10:19 +0000)
committerManuel López-Ibáñez <manu@gcc.gnu.org>
Wed, 13 Aug 2008 10:19:03 +0000 (10:19 +0000)
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

gcc/ChangeLog
gcc/c-decl.c
gcc/c-parser.c
gcc/c-tree.h
gcc/diagnostic.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr15236.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr25183.c
gcc/toplev.h

index 4e03620f40d2fa59a8eb4d66c9ec1423af0feeb0..2ab8c8052c6491d679b6b45f27ceea8d13849262 100644 (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
index e30defdd0e8102dd367fcb0a85b0599d48e5550b..e55e809b1f478c05e15cba4a8c9507f7442de29d 100644 (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,
index 02fc7853fce0becdcb842af667619b35af46bc64..6617145a6cbc4625f7603359130bfd2a7ced52d2 100644 (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;
index d3e3695341cca9f10b70772c380dceaae8481d53..fc76ee32b351151c1a89067fdf7185176945400f 100644 (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);
index cb4c67adca2ad2ae9300b12dfb2022ea827e7402..54c2da7437457b8ef15c14b5412cc4defcc24e99 100644 (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, ...)
 {
index 50096c9bbc71c9db80f4fc7d4358239dc479d50a..7fb2c7d4ed256c279ce5afc4c4eb80ae994025d2 100644 (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
diff --git a/gcc/testsuite/gcc.dg/pr15236.c b/gcc/testsuite/gcc.dg/pr15236.c
new file mode 100644 (file)
index 0000000..b01a4e8
--- /dev/null
@@ -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;
index a6c624cf4722d1344adc8c906fee07793af8ac44..0157b806c7dc8fa2628703b8960c812405ff1682 100644 (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;
   }
 }
index 76718a1eeeff75ac112835f6142f096d8a3675ee..ae61767035cb0b3e0777448db4a5fd91b9d0efaa 100644 (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);