diff mbox

C++ PATCH for c++/48780 (non-promotion of scoped enums)

Message ID 4DEE3FE0.2010603@redhat.com
State New
Headers show

Commit Message

Jason Merrill June 7, 2011, 3:12 p.m. UTC
A bug report on IRC pointed out that we were giving the -Wabi warning in 
cases that don't affect the ABI at all, namely use of scoped enums in 
switch.  So this patch limits the warning to the varargs case by 
catching scoped enums in perform_integral_promotions so that only 
callers that use the type_promotes_to hook directly will get the warning.

Tested x86_64-pc-linux-gnu, applied to trunk and 4.6.
diff mbox

Patch

commit 7ceaa2bef7e4e9599fc7cd67b58b39736dd35d85
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Jun 6 17:35:18 2011 -0400

    	PR c++/48780
    	* typeck.c (perform_integral_promotions): Don't promote scoped enums.
    	* call.c (convert_arg_to_ellipsis): Promote them here in old ABI.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 246fb6d..7019da9 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5724,7 +5724,15 @@  convert_arg_to_ellipsis (tree arg)
   else if (NULLPTR_TYPE_P (arg_type))
     arg = null_pointer_node;
   else if (INTEGRAL_OR_ENUMERATION_TYPE_P (arg_type))
-    arg = perform_integral_promotions (arg);
+    {
+      if (SCOPED_ENUM_P (arg_type) && !abi_version_at_least (6))
+	{
+	  warning (OPT_Wabi, "scoped enum %qT will not promote to an "
+		   "integral type in a future version of GCC", arg_type);
+	  arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg);
+	}
+      arg = perform_integral_promotions (arg);
+    }
 
   arg = require_complete_type (arg);
   arg_type = TREE_TYPE (arg);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 2022f0f..6214452 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1946,6 +1946,9 @@  perform_integral_promotions (tree expr)
   if (!type || TREE_CODE (type) != ENUMERAL_TYPE)
     type = TREE_TYPE (expr);
   gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
+  /* Scoped enums don't promote.  */
+  if (SCOPED_ENUM_P (type))
+    return expr;
   promoted_type = type_promotes_to (type);
   if (type != promoted_type)
     expr = cp_convert (promoted_type, expr);
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum19.C b/gcc/testsuite/g++.dg/cpp0x/enum19.C
new file mode 100644
index 0000000..acdd86c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/enum19.C
@@ -0,0 +1,12 @@ 
+// We shouldn't give an ABI warning about promotion in switch.
+// { dg-options "-std=c++0x -fabi-version=5 -Wabi" }
+
+enum class Foo { X };
+void test(Foo val)
+{
+    switch(val)
+    {
+    case Foo::X:
+        break;
+    }
+};