[C++] PR 82307

Message ID 906899ba-66bc-a8c7-1554-5c3b1a330098@oracle.com
State New
Headers show
Series
  • [C++] PR 82307
Related show

Commit Message

Mukesh Kapoor Oct. 9, 2017, 7:20 p.m.
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

Patch

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();
+}
+