re PR c++/48780 ([C++0x] scoped enumerations and va_arg (default argument promotions))
authorJason Merrill <jason@redhat.com>
Sat, 21 May 2011 22:01:29 +0000 (18:01 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 21 May 2011 22:01:29 +0000 (18:01 -0400)
PR c++/48780
* cvt.c (type_promotes_to): Don't promote scoped enums.

From-SVN: r174005

gcc/common.opt
gcc/cp/ChangeLog
gcc/cp/cvt.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/enum12.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/enum13.C [new file with mode: 0644]

index ebc2ba7dbf8723f4b98fa860ba693eb72f032eb8..492d25e4646c80163aef44f536cd03830f5feb12 100644 (file)
@@ -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=
index 0d1968f5a5ebb645d18459ad00d397829e22ee1b..83c43e0243e2d84099f6f960a8d52ff6ca557d45 100644 (file)
@@ -1,5 +1,8 @@
 2011-05-20  Jason Merrill  <jason@redhat.com>
 
+       PR c++/48780
+       * cvt.c (type_promotes_to): Don't promote scoped enums.
+
        PR c++/49066
        * decl.c (duplicate_decls): Preserve DECL_DELETED_FN.
 
index db4ea46e46aba7620fd034bfa73305a830d68a7e..e5d5361ac2803982f61e5b8405320237781e141a 100644 (file)
@@ -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)
index 46c0a7006b84b04e494f775503b124b1af02da92..7de8fd096a8946d9d5f7feb2452f1cbe17ab6f75 100644 (file)
@@ -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
index fa4549c744170df8686f871cc29fccb60c878fd7..9cb673b143eb536c31fce546fdecb234bb988577 100644 (file)
@@ -1,3 +1,8 @@
+2011-05-20  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/enum12.C: New.
+       * g++.dg/cpp0x/enum13.C: New.
+
 2011-05-21  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/48699
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum12.C b/gcc/testsuite/g++.dg/cpp0x/enum12.C
new file mode 100644 (file)
index 0000000..b2ec919
--- /dev/null
@@ -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 (file)
index 0000000..ec02d3b
--- /dev/null
@@ -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" }