diff mbox

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

Message ID 4DD835A1.4040503@redhat.com
State New
Headers show

Commit Message

Jason Merrill May 21, 2011, 9:58 p.m. UTC
After I sent out that patch I realized that I was missing documentation 
and -Wabi bits, so this patch adds them.

Tested x86_64-pc-linux-gnu, applied to trunk.  New -Wabi warning also 
applied to 4.6.
diff mbox

Patch

commit 3cd4d2ba12597289a7c3aa2bab8a09b5c0ca82f8
Author: Jason Merrill <jason@redhat.com>
Date:   Fri May 20 18:32:32 2011 -0400

    	PR c++/48780
    	* cvt.c (type_promotes_to): Don't promote scoped enums.

diff --git a/gcc/common.opt b/gcc/common.opt
index ebc2ba7..492d25e 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -759,6 +759,9 @@  Driver Undocumented
 ;    function parameters used in other parameters and the return type.
 ;    First selectable in G++ 4.6.
 ;
+; 6: The version of the ABI that doesn't promote scoped enums to int.
+;    First selectable in G++ 4.7.
+;
 ; Additional positive integers will be assigned as new versions of
 ; the ABI become the default version of the ABI.
 fabi-version=
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index db4ea46..e5d5361 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -1616,6 +1616,10 @@  type_promotes_to (tree type)
   if (TREE_CODE (type) == BOOLEAN_TYPE)
     type = integer_type_node;
 
+  /* scoped enums don't promote.  */
+  else if (SCOPED_ENUM_P (type) && abi_version_at_least (6))
+    ;
+
   /* Normally convert enums to int, but convert wide enums to something
      wider.  */
   else if (TREE_CODE (type) == ENUMERAL_TYPE
@@ -1626,6 +1630,9 @@  type_promotes_to (tree type)
       int precision = MAX (TYPE_PRECISION (type),
 			   TYPE_PRECISION (integer_type_node));
       tree totype = c_common_type_for_size (precision, 0);
+      if (SCOPED_ENUM_P (type))
+	warning (OPT_Wabi, "scoped enum %qT will not promote to an integral "
+		 "type in a future version of GCC", type);
       if (TREE_CODE (type) == ENUMERAL_TYPE)
 	type = ENUM_UNDERLYING_TYPE (type);
       if (TYPE_UNSIGNED (type)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 46c0a70..7de8fd0 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1839,6 +1839,8 @@  Version 5 corrects the mangling of attribute const/volatile on
 function pointer types, decltype of a plain decl, and use of a
 function parameter in the declaration of another parameter.
 
+Version 6 corrects the promotion behavior of C++0x scoped enums.
+
 See also @option{-Wabi}.
 
 @item -fno-access-control
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum12.C b/gcc/testsuite/g++.dg/cpp0x/enum12.C
new file mode 100644
index 0000000..b2ec919
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/enum12.C
@@ -0,0 +1,18 @@ 
+// PR c++/48780
+// { dg-options "-std=c++0x -fabi-version=0" }
+
+typedef __builtin_va_list __gnuc_va_list;
+typedef __gnuc_va_list va_list;
+
+enum struct A : short { X };
+
+void foo(int x, ...) {
+   va_list vl;
+   __builtin_va_start(vl, x);
+   enum A t = __builtin_va_arg(vl, enum A);
+   __builtin_va_end(vl);
+}
+
+int main() {
+   foo(0, A::X);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum13.C b/gcc/testsuite/g++.dg/cpp0x/enum13.C
new file mode 100644
index 0000000..ec02d3b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/enum13.C
@@ -0,0 +1,20 @@ 
+// PR c++/48780
+// { dg-options "-std=c++0x -fabi-version=5 -Wabi" }
+
+typedef __builtin_va_list __gnuc_va_list;
+typedef __gnuc_va_list va_list;
+
+enum struct A : short { X };
+
+void foo(int x, ...) {
+   va_list vl;
+   __builtin_va_start(vl, x);
+   enum A t = __builtin_va_arg(vl, enum A); // { dg-warning "promote" }
+   __builtin_va_end(vl);
+}
+
+int main() {
+   foo(0, A::X);		// { dg-warning "will not promote" }
+}
+
+// { dg-prune-output "note" }