From 967444bbf8f78f46dd5df5c924a7650e4ad323ac Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 21 May 2011 18:01:29 -0400 Subject: [PATCH] re PR c++/48780 ([C++0x] scoped enumerations and va_arg (default argument promotions)) PR c++/48780 * cvt.c (type_promotes_to): Don't promote scoped enums. From-SVN: r174005 --- gcc/common.opt | 3 +++ gcc/cp/ChangeLog | 3 +++ gcc/cp/cvt.c | 7 +++++++ gcc/doc/invoke.texi | 2 ++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp0x/enum12.C | 18 ++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/enum13.C | 20 ++++++++++++++++++++ 7 files changed, 58 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum12.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum13.C diff --git a/gcc/common.opt b/gcc/common.opt index ebc2ba7dbf8..492d25e4646 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/ChangeLog b/gcc/cp/ChangeLog index 0d1968f5a5e..83c43e0243e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2011-05-20 Jason Merrill + PR c++/48780 + * cvt.c (type_promotes_to): Don't promote scoped enums. + PR c++/49066 * decl.c (duplicate_decls): Preserve DECL_DELETED_FN. diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index db4ea46e46a..e5d5361ac28 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 46c0a7006b8..7de8fd096a8 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/ChangeLog b/gcc/testsuite/ChangeLog index fa4549c7441..9cb673b143e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-05-20 Jason Merrill + + * g++.dg/cpp0x/enum12.C: New. + * g++.dg/cpp0x/enum13.C: New. + 2011-05-21 Janus Weil 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 index 00000000000..b2ec91990e2 --- /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 00000000000..ec02d3bf607 --- /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" } -- 2.30.2