Hi,

This patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82307.
For an unscoped enum with a fixed underlying type, the function type_promotes_to() does not always return the same type as the underlying type. The fix is to use the underlying type of the enum instead of creating a new one by calling c_common_type_for_size().

Bootstrapped and tested with 'make check' on x86_64-linux. New test case added.

Mukesh

Index: gcc/cp/cvt.c
===================================================================
--- gcc/cp/cvt.c        (revision 253551)
+++ gcc/cp/cvt.c        (working copy)
@@ -1854,11 +1854,16 @@
       tree prom = type;
       if (TREE_CODE (prom) == ENUMERAL_TYPE)
        prom = ENUM_UNDERLYING_TYPE (prom);
-      if (TYPE_UNSIGNED (prom)
-         && ! int_fits_type_p (TYPE_MAX_VALUE (prom), totype))
-       prom = c_common_type_for_size (precision, 1);
-      else
-       prom = totype;
+      // If an unscoped enum has fixed underlying type,
+      // use that type (bug 82307)
+      if (!ENUM_FIXED_UNDERLYING_TYPE_P (type) || SCOPED_ENUM_P (type))
+       {
+         if (TYPE_UNSIGNED (prom)
+             && ! int_fits_type_p (TYPE_MAX_VALUE (prom), totype))
+           prom = c_common_type_for_size (precision, 1);
+         else
+           prom = totype;
+       }
       if (SCOPED_ENUM_P (type))
        {
          if (abi_version_crosses (6)
Index: gcc/testsuite/g++.dg/cpp0x/pr_82307.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/pr_82307.C       (revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/pr_82307.C       (working copy)
@@ -0,0 +1,24 @@
+// PR c++/82307
+// { dg-do compile { target c++11 } }
+
+#include <cstdlib>
+#include <cstring>
+
+enum : unsigned long long { VAL };
+
+const char* foo( unsigned long long )
+{
+  return "unsigned long long";
+}
+
+const char* foo( int )
+{
+  return "int";
+}
+
+int main( void )
+{
+  if (strcmp(foo(VAL), "unsigned long long") != 0)
+    abort();
+}
+

Reply via email to