The following should compile with this DR: enum E : char { e }; int f(char); void f(int); void g () { int k = f(e); } because [over.ics.rank]/4.2: "A conversion that promotes an enumeration whose underlying type is fixed to its underlying type is better than one that promotes to the promoted underlying type, if the two are different."
We give f(int) cr_promotion: 1487 /* Give this a better rank if it's a promotion. */ 1488 if (same_type_p (to, type_promotes_to (from)) 1489 && next_conversion (conv)->rank <= cr_promotion) 1490 conv->rank = cr_promotion; while f(char) has cr_std, which is worse than cr_promotion, so we pick f(int).
Testing a patch.
*** Bug 68957 has been marked as a duplicate of this bug. ***
Author: mpolacek Date: Wed Oct 9 17:49:26 2019 New Revision: 276766 URL: https://gcc.gnu.org/viewcvs?rev=276766&root=gcc&view=rev Log: PR c++/92032 - DR 1601: Promotion of enum with fixed underlying type. I've been messing with compare_ics recently and noticed that we don't implement CWG 1601, which should be fairly easy. Thus this patch. The motivating example is enum E : char { e }; void f(char); void f(int); void g() { f(e); } where the call to f was ambiguous but we should choose f(char). Currently we give f(int) cr_promotion in standard_conversion, while f(char) remains cr_std, which is worse than cr_promotion. So I thought I'd give it cr_promotion also and then add a tiebreaker to compare_ics. * call.c (standard_conversion): When converting an enumeration with a fixed underlying type to the underlying type, give it the cr_promotion rank. (compare_ics): Implement a tiebreaker as per CWG 1601. * g++.dg/cpp0x/scoped_enum10.C: New test. * g++.dg/cpp0x/scoped_enum11.C: New test. Added: trunk/gcc/testsuite/g++.dg/cpp0x/scoped_enum10.C trunk/gcc/testsuite/g++.dg/cpp0x/scoped_enum11.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/testsuite/ChangeLog
Resolved in GCC 10.
It's worth noting that `std::cout << e` will now emit a null char ('\0') rather than a zero character ('0').