public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCH for c++/48780 (non-promotion of scoped enums)
@ 2011-05-21 12:22 Jason Merrill
  2011-05-22 13:24 ` Jason Merrill
  0 siblings, 1 reply; 3+ messages in thread
From: Jason Merrill @ 2011-05-21 12:22 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 284 bytes --]

As the bug submitter correctly points out, C++0x scoped enums are not 
subject to integral promotion like unscoped enums are.  Unfortunately, 
this represents an ABI change (at least for varargs), so it's 
conditional on -fabi-version.

Tested x86_64-pc-linux-gnu, applying to trunk.

[-- Attachment #2: 48780.patch --]
[-- Type: text/x-patch, Size: 1761 bytes --]

commit e2aa4734d644e2c0d658d6d9a42cc36ef2b0087c
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..e89ce29 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
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);
+}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C++ PATCH for c++/48780 (non-promotion of scoped enums)
  2011-05-21 12:22 C++ PATCH for c++/48780 (non-promotion of scoped enums) Jason Merrill
@ 2011-05-22 13:24 ` Jason Merrill
  2011-06-07 15:12   ` Jason Merrill
  0 siblings, 1 reply; 3+ messages in thread
From: Jason Merrill @ 2011-05-22 13:24 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 202 bytes --]

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.

[-- Attachment #2: 48780.patch --]
[-- Type: text/x-patch, Size: 3374 bytes --]

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" }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C++ PATCH for c++/48780 (non-promotion of scoped enums)
  2011-05-22 13:24 ` Jason Merrill
@ 2011-06-07 15:12   ` Jason Merrill
  0 siblings, 0 replies; 3+ messages in thread
From: Jason Merrill @ 2011-06-07 15:12 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 408 bytes --]

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.


[-- Attachment #2: 48780-2.patch --]
[-- Type: text/x-patch, Size: 1991 bytes --]

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-06-07 15:12 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-21 12:22 C++ PATCH for c++/48780 (non-promotion of scoped enums) Jason Merrill
2011-05-22 13:24 ` Jason Merrill
2011-06-07 15:12   ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).