Bug 92032 - DR 1601 - Promotion of enumeration with fixed underlying type
Summary: DR 1601 - Promotion of enumeration with fixed underlying type
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: ---
Assignee: Marek Polacek
URL:
Keywords: rejects-valid
: 68957 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-10-08 17:24 UTC by Marek Polacek
Modified: 2021-07-27 16:23 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-10-08 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marek Polacek 2019-10-08 17:24:13 UTC
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."
Comment 1 Marek Polacek 2019-10-08 17:26:14 UTC
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).
Comment 2 Marek Polacek 2019-10-08 21:25:05 UTC
Testing a patch.
Comment 3 Jonathan Wakely 2019-10-09 09:22:47 UTC
*** Bug 68957 has been marked as a duplicate of this bug. ***
Comment 4 Marek Polacek 2019-10-09 17:49:58 UTC
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
Comment 5 Marek Polacek 2019-10-09 17:50:53 UTC
Resolved in GCC 10.
Comment 6 Charlie 2021-07-27 16:23:56 UTC
It's worth noting that `std::cout << e` will now emit a null char ('\0') rather than a zero character ('0').