re PR c++/48780 ([C++0x] scoped enumerations and va_arg (default argument promotions))
authorJason Merrill <jason@redhat.com>
Tue, 7 Jun 2011 15:09:29 +0000 (11:09 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 7 Jun 2011 15:09:29 +0000 (11:09 -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.

From-SVN: r174751

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cvt.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/enum19.C [new file with mode: 0644]

index c3826e5559c11964b78427ddbfa87aed4aab267b..ba3fd1a3f0c80b2f786165793ec0c6c47675f8b9 100644 (file)
@@ -1,3 +1,9 @@
+2011-06-06  Jason Merrill  <jason@redhat.com>
+
+       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.
+
 2011-06-06  Nicola Pero  <nicola.pero@meta-innovation.com>,
 
        PR obj-c++/48275
index ff3dc062b2e0e29a0d77d28d2dc44b1dfea03922..d955b63936ca812b4d6c86c3f6fa85a4ab96a916 100644 (file)
@@ -5896,7 +5896,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);
index e5d5361ac2803982f61e5b8405320237781e141a..8a23d5199f67d9f0385f811567892af00cfb3552 100644 (file)
@@ -1616,7 +1616,8 @@ type_promotes_to (tree type)
   if (TREE_CODE (type) == BOOLEAN_TYPE)
     type = integer_type_node;
 
-  /* scoped enums don't promote.  */
+  /* Scoped enums don't promote, but pretend they do for backward ABI bug
+     compatibility wrt varargs.  */
   else if (SCOPED_ENUM_P (type) && abi_version_at_least (6))
     ;
 
index 5fbb765767e915ca9426bd53d72f7eb44139e6d4..8e4fd4213c30f658a47e440cfa04032c0328b086 100644 (file)
@@ -1953,6 +1953,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);
index 05849cc82dd2a9f92013f00918723c0bedad5229..b38cd1e677036fc13015e1f45743ef1bceb63135 100644 (file)
@@ -1,3 +1,7 @@
+2011-06-06  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/enum19.C: New.
+
 2011-06-07  Sergey Grechanik  <mouseentity@ispras.ru>
 
        * gcc.target/arm/neon-reload-class.c: New test.
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum19.C b/gcc/testsuite/g++.dg/cpp0x/enum19.C
new file mode 100644 (file)
index 0000000..acdd86c
--- /dev/null
@@ -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;
+    }
+};