OSDN Git Service

2008-10-19 Manuel López-Ibáñez <manu@gcc.gnu.org>
authormanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 19 Oct 2008 13:52:10 +0000 (13:52 +0000)
committermanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 19 Oct 2008 13:52:10 +0000 (13:52 +0000)
PR c/30260
* c-decl.c (finish_enum): Convert non-integer enumerators to enum
type.
(build_enumerator): Convert enumerators that fit in integer to
integer type.
testsuite/
* gcc.dg/pr30260.c: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@141224 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr30260.c [new file with mode: 0644]

index 79aee0b..7791e3b 100644 (file)
@@ -1,3 +1,11 @@
+2008-10-19  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       PR c/30260
+       * c-decl.c (finish_enum): Convert non-integer enumerators to enum
+       type.
+       (build_enumerator): Convert enumerators that fit in integer to
+       integer type.
+
 2008-10-18  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.md (unnamed peephole2): Do not force memory
        PR ada/36554
        * dwarf2out.c (is_subrange_type): Deal with BOOLEAN_TYPE.
 
-2008-07-30  Rafael Ãvila de Espíndola  <espindola@google.com>
+2008-07-30  Rafael Ã\81vila de Espíndola  <espindola@google.com>
 
        PR 36974
        * final.c (call_from_call_insn): Handle COND_EXEC.
        * config/rs6000/rs6000.h (SLOW_UNALIGNED_ACCESS): Add clause for
        vector modes.
 
-2008-07-30  Rafael Ãvila de Espíndola  <espindola@google.com>
+2008-07-30  Rafael Ã\81vila de Espíndola  <espindola@google.com>
 
        * final.c (call_from_call_insn): New.
        (final_scan_insn): Call assemble_external on FUNCTION_DECLs.
        (TARGET_OPTION_PRINT): Ditto.
        (TARGET_CAN_INLINE_P): Ditto.
 
-2008-07-22  Rafael Ãvila de Espíndola  <espindola@google.com>
+2008-07-22  Rafael Ã\81vila de Espíndola  <espindola@google.com>
 
        * c-typeck.c (build_external_ref): Don't call assemble_external.
        * final.c (output_operand): Call assemble_external.
        highest magnitude if this is still less or equal to the true
        quotient in magnitude.
 
-2008-07-21  Rafael Ãvila de Espíndola  <espindola@google.com>
+2008-07-21  Rafael Ã\81vila de Espíndola  <espindola@google.com>
 
        * Makefile.in: Replace toplev.h with TOPLEV_H.
        * c-decl.c (merge_decls): Don't set DECL_IN_SYSTEM_HEADER.
        (m32c_legitimate_address_p): Handle "++rii" addresses created by
        m32c_legitimize_reload_address.
 
-2007-07-16  Rafael Ãvila de Espíndola  <espindola@google.com>
+2007-07-16  Rafael Ã\81vila de Espíndola  <espindola@google.com>
 
        * c-decl.c (merge_decls): Keep DECL_SOURCE_LOCATION and
        DECL_IN_SYSTEM_HEADER in sync.
 
        * emit-rtl.c (set_mem_attributes_minus_bitpos): Improve comment.
 
-2007-07-14  Rafael Ãvila de Espíndola  <espindola@google.com>
+2007-07-14  Rafael Ã\81vila de Espíndola  <espindola@google.com>
 
        * c-decl.c (diagnose_mismatched_decls): Don't warn if TREE_NO_WARNING
        is set.
index 2a6dcf2..ee8e45e 100644 (file)
@@ -5926,17 +5926,15 @@ 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.  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
-           tem = enumtype;
-         ini = convert (tem, ini);
+            integer type as an extensions.  build_enumerator()
+            converts 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. Here we
+            convert the rest to the enumerator type. */
+         if (TREE_TYPE (ini) != integer_type_node)
+           ini = convert (enumtype, ini);
 
          DECL_INITIAL (enu) = ini;
          TREE_PURPOSE (pair) = DECL_NAME (enu);
@@ -6026,6 +6024,18 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value,
     pedwarn (value_loc, OPT_pedantic, 
             "ISO C restricts enumerator values to range of %<int%>");
 
+  /* The ISO C Standard mandates enumerators to have type int, even
+     though the underlying type of an enum type is 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, we would have already warned about those that
+     don't fit. We have to do this here rather than in finish_enum
+     because this value may be used to define more enumerators.  */
+  if (int_fits_type_p (value, integer_type_node))
+    value = convert (integer_type_node, value);
+
   /* Set basis for default for next value.  */
   the_enum->enum_next_value
     = build_binary_op
index 464a9a6..a08312d 100644 (file)
@@ -1,3 +1,8 @@
+2008-10-19  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       PR c/30260
+       * gcc.dg/pr30260.c: New.
+
 2008-10-19  Paul Thomas  <pault@gcc.gnu.org>
 
         PR fortran/37723
diff --git a/gcc/testsuite/gcc.dg/pr30260.c b/gcc/testsuite/gcc.dg/pr30260.c
new file mode 100644 (file)
index 0000000..f737317
--- /dev/null
@@ -0,0 +1,32 @@
+/* PR 30260  */
+/* { dg-do link } */
+/* { dg-options "-pedantic -O" } */
+#include <limits.h>
+
+enum A {
+  A1 = 0, 
+  A2 = A1 - 1
+};
+enum B {
+  B1 = 0u, 
+  B2 = B1 - 1 /* { dg-bogus "ISO C restricts enumerator values to range of 'int'" } */
+};
+int main(void)
+{
+  enum A a = -1;
+  enum B b = -1;
+
+  if (!(a < 0))
+    link_error ();
+  if (!(A2 < 0))
+    link_error ();
+  if (!(b < 0))
+    link_error ();
+  if (!(B2 < 0))
+    link_error ();
+
+  return 0;
+}
+
+enum E1 { e10 = INT_MAX, e11 }; /* { dg-error "overflow in enumeration values" } */
+enum E2 { e20 = (unsigned) INT_MAX, e21 }; /* { dg-error "overflow in enumeration values" } */