public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/96496] New: Conversion to enum with underlying type bool produces wrong result
@ 2020-08-06 13:36 fw at gcc dot gnu.org
  2020-08-06 13:40 ` [Bug c++/96496] " redi at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: fw at gcc dot gnu.org @ 2020-08-06 13:36 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96496

            Bug ID: 96496
           Summary: Conversion to enum with underlying type bool produces
                    wrong result
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: fw at gcc dot gnu.org
  Target Milestone: ---

enum E : bool { One, Two };

int
f1 (int x)
{
  return (E) x;
}

The conversion must first be to type bool, according to:

“If the enumeration type has a fixed underlying type, the value is first
converted to that type by integral conversion, if necessary, and then to the
enumeration type.”

<http://eel.is/c++draft/expr.static.cast#10>

And that must produce a comparison against zero:

“A zero value, null pointer value, or null member pointer value is converted to
false; any other value is converted to true.”

<http://eel.is/c++draft/conv.bool#1>

Currently, GCC performs a bit mask (at -O2):

_Z2f1i:
        movl    %edi, %eax
        andl    $1, %eax
        ret

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

* [Bug c++/96496] Conversion to enum with underlying type bool produces wrong result
  2020-08-06 13:36 [Bug c++/96496] New: Conversion to enum with underlying type bool produces wrong result fw at gcc dot gnu.org
@ 2020-08-06 13:40 ` redi at gcc dot gnu.org
  2020-08-06 13:56 ` mpolacek at gcc dot gnu.org
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2020-08-06 13:40 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96496

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2020-08-06
             Status|UNCONFIRMED                 |NEW

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

* [Bug c++/96496] Conversion to enum with underlying type bool produces wrong result
  2020-08-06 13:36 [Bug c++/96496] New: Conversion to enum with underlying type bool produces wrong result fw at gcc dot gnu.org
  2020-08-06 13:40 ` [Bug c++/96496] " redi at gcc dot gnu.org
@ 2020-08-06 13:56 ` mpolacek at gcc dot gnu.org
  2020-08-25  9:22 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2020-08-06 13:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96496

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mpolacek at gcc dot gnu.org

--- Comment #1 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
As a consequence of the
andl    $1, %eax
we produce 1 for odd numbers only:

enum E : bool { One, Two };

int
f1 (int x)
{
  return (E) x;
}

int
main ()
{
  if (f1 (6) != 1)
    __builtin_abort ();
  if (f1 (7) != 1)
    __builtin_abort ();
}

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

* [Bug c++/96496] Conversion to enum with underlying type bool produces wrong result
  2020-08-06 13:36 [Bug c++/96496] New: Conversion to enum with underlying type bool produces wrong result fw at gcc dot gnu.org
  2020-08-06 13:40 ` [Bug c++/96496] " redi at gcc dot gnu.org
  2020-08-06 13:56 ` mpolacek at gcc dot gnu.org
@ 2020-08-25  9:22 ` redi at gcc dot gnu.org
  2021-08-01  0:17 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2020-08-25  9:22 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96496

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |fujii.hironori at gmail dot com

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
*** Bug 96778 has been marked as a duplicate of this bug. ***

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

* [Bug c++/96496] Conversion to enum with underlying type bool produces wrong result
  2020-08-06 13:36 [Bug c++/96496] New: Conversion to enum with underlying type bool produces wrong result fw at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2020-08-25  9:22 ` redi at gcc dot gnu.org
@ 2021-08-01  0:17 ` pinskia at gcc dot gnu.org
  2022-10-28  0:38 ` cvs-commit at gcc dot gnu.org
  2024-02-17 15:49 ` mpolacek at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-08-01  0:17 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96496

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Confirmed (again with a compile time test):
enum E : bool { One, Two };
constexpr int f1 (int x) { return (E) x; }
static_assert(f1(6), "");
static_assert(f1(7), "");

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

* [Bug c++/96496] Conversion to enum with underlying type bool produces wrong result
  2020-08-06 13:36 [Bug c++/96496] New: Conversion to enum with underlying type bool produces wrong result fw at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2021-08-01  0:17 ` pinskia at gcc dot gnu.org
@ 2022-10-28  0:38 ` cvs-commit at gcc dot gnu.org
  2024-02-17 15:49 ` mpolacek at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-10-28  0:38 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96496

--- Comment #4 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Joseph Myers <jsm28@gcc.gnu.org>:

https://gcc.gnu.org/g:e0997c14af5e8bc4d26e28549cbce99364a1601f

commit r13-3534-ge0997c14af5e8bc4d26e28549cbce99364a1601f
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Fri Oct 28 00:37:28 2022 +0000

    c: C2x enums with fixed underlying type [PR61469]

    C2x adds support for enums with a fixed underlying type specified
    ("enum e : long long;" and similar).  Implement this in the C front
    end.  The same representation is used for these types as in C++, with
    two macros moved from cp-tree.h to c-common.h.

    Such enums can have bool as the underlying type, and various C
    front-end code checking for boolean types is adjusted to use a new
    C_BOOLEAN_TYPE_P to handle such enums the same way as bool.  (Note
    that for C++ we have bug 96496 that enums with underlying type bool
    don't work correctly there.)

    There are various issues with the wording for such enums in the
    current C2x working draft (including but not limited to wording in the
    accepted paper that failed to make it into the working draft), which I
    intend to raise in NB comments.  I think what I've implemented and
    added tests for matches the intent.

    Bootstrapped with no regressions for x86_64-pc-linux-gnu.

            PR c/61469

    gcc/c-family/
            * c-common.h (ENUM_UNDERLYING_TYPE, ENUM_FIXED_UNDERLYING_TYPE_P):
            New.  Moved from cp/cp-tree.h.
            * c-warn.cc (warnings_for_convert_and_check): Do not consider
            conversions to enum with underlying type bool to overflow.

    gcc/c/
            * c-convert.cc (c_convert): Handle enums with underlying boolean
            type like bool.
            * c-decl.cc (shadow_tag_warned): Allow shadowing declarations for
            enums with enum type specifier, but give errors for storage class
            specifiers, qualifiers or alignment specifiers in non-definition
            declarations of such enums.
            (grokdeclarator): Give error for non-definition use of type
            specifier with an enum type specifier.
            (parser_xref_tag): Add argument has_enum_type_specifier.  Pass it
            to lookup_tag and use it to set ENUM_FIXED_UNDERLYING_TYPE_P.
            (xref_tag): Update call to parser_xref_tag.
            (start_enum): Add argument fixed_underlying_type.  Complete enum
            type with a fixed underlying type given in the definition.  Give
            error for defining without a fixed underlying type in the
            definition if one was given in a prior declaration.  Do not mark
            enums with fixed underlying type as packed for -fshort-enums.
            Store the enum type in the_enum.
            (finish_enum): Do not adjust types of values or check their range
            for an enum with a fixed underlying type.  Set underlying type of
            enum and variants.
            (build_enumerator): Check enumeration constants for enum with
            fixed underlying type against that type and convert to that type.
            Increment in the underlying integer type, with handling for bool.
            (c_simulate_enum_decl): Update call to start_enum.
            (declspecs_add_type): Set specs->enum_type_specifier_ref_p.
            * c-objc-common.cc (c_get_alias_set): Use ENUM_UNDERLYING_TYPE
            rather than recomputing an underlying type based on size.
            * c-parser.cc (c_parser_declspecs)
            (c_parser_struct_or_union_specifier, c_parser_typeof_specifier):
            Set has_enum_type_specifier for type specifiers.
            (c_parser_enum_specifier): Handle enum type specifiers.
            (c_parser_struct_or_union_specifier): Update call to
            parser_xref_tag.
            (c_parser_omp_atomic): Check for boolean increment or decrement
            using C_BOOLEAN_TYPE_P.
            * c-tree.h (C_BOOLEAN_TYPE_P): New.
            (struct c_typespec): Add has_enum_type_specifier.
            (struct c_declspecs): Add enum_type_specifier_ref_p.
            (struct c_enum_contents): Add enum_type.
            (start_enum, parser_xref_tag): Update prototypes.
            * c-typeck.cc (composite_type): Allow for enumerated types
            compatible with bool.
            (common_type, comptypes_internal, perform_integral_promotions):
            Use ENUM_UNDERLYING_TYPE.
            (parser_build_binary_op, build_unary_op, convert_for_assignment)
            (c_finish_return, c_start_switch, build_binary_op): Check for
            boolean types using C_BOOLEAN_TYPE_P.

    gcc/cp/
            * cp-tree.h (ENUM_FIXED_UNDERLYING_TYPE_P, ENUM_UNDERLYING_TYPE):
            Remove.  Moved to c-common.h.

    gcc/testsuite/
            * gcc.dg/c11-enum-4.c, gcc.dg/c11-enum-5.c, gcc.dg/c11-enum-6.c,
            gcc.dg/c2x-enum-6.c, gcc.dg/c2x-enum-7.c, gcc.dg/c2x-enum-8.c,
            gcc.dg/gnu2x-enum-1.c: New tests.

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

* [Bug c++/96496] Conversion to enum with underlying type bool produces wrong result
  2020-08-06 13:36 [Bug c++/96496] New: Conversion to enum with underlying type bool produces wrong result fw at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2022-10-28  0:38 ` cvs-commit at gcc dot gnu.org
@ 2024-02-17 15:49 ` mpolacek at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2024-02-17 15:49 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96496

Marek Polacek <mpolacek at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|2020-08-06 00:00:00         |2024-2-17

--- Comment #5 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Comment 3 test still doesn't work.

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

end of thread, other threads:[~2024-02-17 15:49 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-06 13:36 [Bug c++/96496] New: Conversion to enum with underlying type bool produces wrong result fw at gcc dot gnu.org
2020-08-06 13:40 ` [Bug c++/96496] " redi at gcc dot gnu.org
2020-08-06 13:56 ` mpolacek at gcc dot gnu.org
2020-08-25  9:22 ` redi at gcc dot gnu.org
2021-08-01  0:17 ` pinskia at gcc dot gnu.org
2022-10-28  0:38 ` cvs-commit at gcc dot gnu.org
2024-02-17 15:49 ` mpolacek at gcc dot gnu.org

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).