Bug 38064 - [c++0x] operator== doesn't work for enum classes
Summary: [c++0x] operator== doesn't work for enum classes
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: 4.5.1
Assignee: Jason Merrill
URL:
Keywords:
: 40193 41030 (view as bug list)
Depends on:
Blocks:
 
Reported: 2008-11-09 04:02 UTC by René Bürgel
Modified: 2014-02-16 10:02 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-05-25 16:45:17


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description René Bürgel 2008-11-09 04:02:55 UTC
enum class E { elem };

int main()
{
        E e = E::elem;
        if (e == E::elem);
        return 1;
}
g++ -std=c++0x tc1.cpp
tc1.cpp: In function 'int main()':
tc1.cpp:6: error: invalid operands of types 'E' and 'E' to binary 'operator=='
Comment 1 René Bürgel 2008-11-09 04:11:01 UTC
extended testcase, this fails for other operators, too

enum class E { elem };

int main()
{
        E::elem == E::elem;
        E::elem != E::elem;
        E::elem <  E::elem;
        E::elem <= E::elem;
        E::elem >  E::elem;
        E::elem >= E::elem;
        return 1;
}

Or am i missing something from the proposal? Maybe i have to define every operator i want to use for every enum?
Comment 2 René Bürgel 2008-11-09 04:22:19 UTC
ok, even for the case i misunderstood the proposal: there are still some problems with it, making it unuseable.

enum class E { elem };
inline bool operator== (E c1, E c2)
{
        return (int) c1 == (int) c2;
}

int main()
{
        E::elem == E::elem; //works now
        static_assert(E::elem == E::elem, ""); //fails
        return 1;
}

tc2.cpp: In function 'int main()':
tc2.cpp:10: error: calls to overloaded operators cannot appear in a constant-expression

... which leads to the conclusion, that strongly-typed enums can't be used in constant-expression. That's definitely not intended by the proposal.
Comment 3 Piotr Wyderski 2009-01-26 10:48:31 UTC
The bug is definitely confirmed and it still happens on GCC-4.4.0 trunk (revision 143673).
Comment 4 Paolo Carlini 2009-05-18 22:12:37 UTC
*** Bug 40193 has been marked as a duplicate of this bug. ***
Comment 5 Paolo Carlini 2009-05-25 16:11:50 UTC
CC-ing Jason...
Comment 6 Ian Lance Taylor 2009-05-25 18:32:46 UTC
With unscoped enums the similar code works because cp_build_binary_op applies the default integral promotions to the enums, and winds up comparing two int values.  The promotions are not applied to scoped enums because default_conversion checks INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P.  I would guess that this would work if several checks in cp_build_binary_op also checked for ENUMERAL_TYPE in cases where they currently check for INTEGER_TYPE.  But I haven't tried to read the standard to understand where the right fix is.
Comment 7 Jason Merrill 2009-05-25 23:01:19 UTC
Subject: Bug 38064

Author: jason
Date: Mon May 25 23:01:02 2009
New Revision: 147854

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147854
Log:
	PR c++/38064
	* typeck.c (cp_build_binary_op): Allow ENUMERAL_TYPE in
	arithmetic comparisons.
	(cp_common_type): Handle scoped enums.

	* call.c (promoted_arithmetic_type_p): Don't use INTEGRAL_TYPE_P.
	(add_builtin_candidate, add_builtin_candidates): Likewise.
	(convert_like_real): Likewise.
	* class.c (check_bitfield_decl): Likewise.
	* decl.c (check_static_variable_definition): Likewise.
	(compute_array_index_type): Likewise.
	* decl2.c (grokbitfield): Likewise.
	* init.c (build_new_1): Likewise.
	* pt.c (convert_nontype_argument): Likewise.
	(current_instantiation): Likewise.
	* tree.c (pod_type_p): Likewise.
	* typeck.c (build_static_cast_1): Likewise.
	(build_reinterpret_cast_1): Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/enum3.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/call.c
    trunk/gcc/cp/class.c
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/decl2.c
    trunk/gcc/cp/init.c
    trunk/gcc/cp/pt.c
    trunk/gcc/cp/tree.c
    trunk/gcc/cp/typeck.c
    trunk/gcc/testsuite/ChangeLog

Comment 8 Jason Merrill 2009-05-25 23:07:18 UTC
Subject: Bug 38064

Author: jason
Date: Mon May 25 23:07:05 2009
New Revision: 147855

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147855
Log:
        PR c++/38064
        * typeck.c (cp_build_binary_op): Allow ENUMERAL_TYPE in
        arithmetic comparisons.
        (cp_common_type): Handle scoped enums.

Added:
    branches/gcc-4_4-branch/gcc/testsuite/g++.dg/cpp0x/enum3.C
      - copied unchanged from r147854, trunk/gcc/testsuite/g++.dg/cpp0x/enum3.C
Modified:
    branches/gcc-4_4-branch/gcc/cp/ChangeLog
    branches/gcc-4_4-branch/gcc/cp/typeck.c
    branches/gcc-4_4-branch/gcc/testsuite/ChangeLog

Comment 9 Jason Merrill 2009-05-25 23:12:38 UTC
Fixed for 4.4.1.
Comment 10 Andrew Pinski 2009-08-10 21:37:56 UTC
*** Bug 41030 has been marked as a duplicate of this bug. ***
Comment 11 Jonathan Wakely 2010-04-26 11:23:13 UTC
This is fixed for equality operators but not relational operators

enum class E { Foo, Bar };
bool b2 = E::Foo < E::Bar;
Comment 12 Andrew Pinski 2010-04-26 17:50:00 UTC
(In reply to comment #11)
> This is fixed for equality operators but not relational operators
> 
> enum class E { Foo, Bar };
> bool b2 = E::Foo < E::Bar;

Is that even allowed for normal enums?
Comment 13 Jonathan Wakely 2010-04-26 23:07:33 UTC
(In reply to comment #12)
> Is that even allowed for normal enums?

yes, unscoped enums will be promoted to int
Comment 14 Jason Merrill 2010-05-04 19:01:31 UTC
Subject: Bug 38064

Author: jason
Date: Tue May  4 19:01:13 2010
New Revision: 159042

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=159042
Log:
	PR c++/38064
	* typeck.c (cp_build_binary_op): Allow enums for <> as well.

Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/typeck.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/cpp0x/enum3.C

Comment 15 Jason Merrill 2010-05-04 19:03:17 UTC
Subject: Bug 38064

Author: jason
Date: Tue May  4 19:03:00 2010
New Revision: 159043

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=159043
Log:
	PR c++/38064
	* typeck.c (cp_build_binary_op): Allow enums for <> as well.

Modified:
    branches/gcc-4_5-branch/gcc/cp/ChangeLog
    branches/gcc-4_5-branch/gcc/cp/typeck.c
    branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_5-branch/gcc/testsuite/g++.dg/cpp0x/enum3.C

Comment 16 Jason Merrill 2010-05-04 19:04:19 UTC
Other comparisons fixed for 4.5.1.
Comment 17 Jackie Rosen 2014-02-16 10:02:31 UTC Comment hidden (spam)