Bug 30423 - Build failures with clang 16
Summary: Build failures with clang 16
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: 13.1
: P2 normal
Target Milestone: 13.2
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-05-05 14:28 UTC by Simon Marchi
Modified: 2023-05-05 19:33 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Marchi 2023-05-05 14:28:12 UTC
Building GDB 13.1 with clang 16, I get these warnings:

  CXX    gdb.o
In file included from /home/smarchi/src/binutils-gdb/gdb/gdb.c:19:
In file included from /home/smarchi/src/binutils-gdb/gdb/defs.h:66:
/home/smarchi/src/binutils-gdb/gdb/../gdbsupport/enum-flags.h:95:52: error: integer value -1 is outside the valid range of values [0, 15] for this enumeration type [-Wenum-constexpr-conversion]
    integer_for_size<sizeof (T), static_cast<bool>(T (-1) < T (0))>::type
                                                   ^
This breaks the build, since clang makes -Wenum-constexpr-conversion an error by default (without -Werror).

Then, we have a few of these warnings:

  CXX    z80-tdep.o
/home/smarchi/src/binutils-gdb/gdb/z80-tdep.c:338:32: warning: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Wsingle-bit-bitfield-constant-conversion]
        info->prologue_type.load_args = 1;
                                      ^ ~

We have patches for these issues in master:

https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=ae61525fcf456ab395d55c45492a106d1275873a
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=07f285934886016ddd82cac99a3873e68b499d5c

We can consider cherry-picking them in gdb-13-branch.
Comment 1 Tom Tromey 2023-05-05 15:05:26 UTC
Setting the target milestone.
Comment 2 Sourceware Commits 2023-05-05 19:27:27 UTC
The gdb-13-branch branch has been updated by Simon Marchi <simark@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=12e3f3bc6ec74eb50e04675f5bcf962482d3ff25

commit 12e3f3bc6ec74eb50e04675f5bcf962482d3ff25
Author: Simon Marchi <simon.marchi@efficios.com>
Date:   Thu Feb 23 12:35:40 2023 -0500

    gdbsupport: ignore -Wenum-constexpr-conversion in enum-flags.h
    
    When building with clang 16, we get:
    
          CXX    gdb.o
        In file included from /home/smarchi/src/binutils-gdb/gdb/gdb.c:19:
        In file included from /home/smarchi/src/binutils-gdb/gdb/defs.h:65:
        /home/smarchi/src/binutils-gdb/gdb/../gdbsupport/enum-flags.h:95:52: error: integer value -1 is outside the valid range of values [0, 15] for this enumeration type [-Wenum-constexpr-conversion]
            integer_for_size<sizeof (T), static_cast<bool>(T (-1) < T (0))>::type
                                                           ^
    
    The error message does not make it clear in the context of which enum
    flag this fails (i.e. what is T in this context), but it doesn't really
    matter, we have similar warning/errors for many of them, if we let the
    build go through.
    
    clang is right that the value -1 is invalid for the enum type we cast -1
    to.  However, we do need this expression in order to select an integer
    type with the appropriate signedness.  That is, with the same signedness
    as the underlying type of the enum.
    
    I first wondered if that was really needed, if we couldn't use
    std::underlying_type for that.  It turns out that the comment just above
    says:
    
        /* Note that std::underlying_type<enum_type> is not what we want here,
           since that returns unsigned int even when the enum decays to signed
           int.  */
    
    I was surprised, because std::is_signed<std::underlying_type<enum_type>>
    returns the right thing.  So I tried replacing all this with
    std::underlying_type, see if that would work.  Doing so causes some
    build failures in unittests/enum-flags-selftests.c:
    
          CXX    unittests/enum-flags-selftests.o
        /home/smarchi/src/binutils-gdb/gdb/unittests/enum-flags-selftests.c:254:1: error: static assertion failed due to requirement 'gdb::is_same<selftests::enum_flags_tests::check_valid_expr254::archetype<enum_flags<s
        elftests::enum_flags_tests::RE>, selftests::enum_flags_tests::RE, enum_flags<selftests::enum_flags_tests::RE2>, selftests::enum_flags_tests::RE2, enum_flags<selftests::enum_flags_tests::URE>, selftests::enum_fla
        gs_tests::URE, int>, selftests::enum_flags_tests::check_valid_expr254::archetype<enum_flags<selftests::enum_flags_tests::RE>, selftests::enum_flags_tests::RE, enum_flags<selftests::enum_flags_tests::RE2>, selfte
        sts::enum_flags_tests::RE2, enum_flags<selftests::enum_flags_tests::URE>, selftests::enum_flags_tests::URE, unsigned int>>::value == true':
        CHECK_VALID (true,  int,  true ? EF () : EF2 ())
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        /home/smarchi/src/binutils-gdb/gdb/unittests/enum-flags-selftests.c:91:3: note: expanded from macro 'CHECK_VALID'
          CHECK_VALID_EXPR_6 (EF, RE, EF2, RE2, UEF, URE, VALID, EXPR_TYPE, EXPR)
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        /home/smarchi/src/binutils-gdb/gdb/../gdbsupport/valid-expr.h:105:3: note: expanded from macro 'CHECK_VALID_EXPR_6'
          CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1, typename T2,           \
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        /home/smarchi/src/binutils-gdb/gdb/../gdbsupport/valid-expr.h:66:3: note: expanded from macro 'CHECK_VALID_EXPR_INT'
          static_assert (gdb::is_detected_exact<archetype<TYPES, EXPR_TYPE>,    \
          ^              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    This is a bit hard to decode, but basically enumerations have the
    following funny property that they decay into a signed int, even if
    their implicit underlying type is unsigned.  This code:
    
        enum A {};
        enum B {};
    
        int main() {
          std::cout << std::is_signed<std::underlying_type<A>::type>::value
                    << std::endl;
          std::cout << std::is_signed<std::underlying_type<B>::type>::value
                    << std::endl;
          auto result = true ? A() : B();
          std::cout << std::is_signed<decltype(result)>::value << std::endl;
        }
    
    produces:
    
        0
        0
        1
    
    So, the "CHECK_VALID" above checks that this property works for enum flags the
    same way as it would if you were using their underlying enum types.  And
    somehow, changing integer_for_size to use std::underlying_type breaks that.
    
    Since the current code does what we want, and I don't see any way of doing it
    differently, ignore -Wenum-constexpr-conversion around it.
    
    (cherry picked from commit ae61525fcf456ab395d55c45492a106d1275873a)
    
    Change-Id: Ibc82ae7bbdb812102ae3f1dd099fc859dc6f3cc2
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30423
    Approved-By: Tom Tromey <tom@tromey.com>
Comment 3 Sourceware Commits 2023-05-05 19:27:32 UTC
The gdb-13-branch branch has been updated by Simon Marchi <simark@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=caaf38247f0c5e9a7d20d5aaa4ece0b3482f65f9

commit caaf38247f0c5e9a7d20d5aaa4ece0b3482f65f9
Author: Simon Marchi <simon.marchi@efficios.com>
Date:   Thu Feb 23 12:35:41 2023 -0500

    gdb: fix -Wsingle-bit-bitfield-constant-conversion warning in z80-tdep.c
    
    When building with clang 16, I see:
    
        /home/smarchi/src/binutils-gdb/gdb/z80-tdep.c:338:32: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bit-bitfield-constant-conversion]
                info->prologue_type.load_args = 1;
                                              ^ ~
        /home/smarchi/src/binutils-gdb/gdb/z80-tdep.c:345:36: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bit-bitfield-constant-conversion]
              info->prologue_type.critical = 1;
                                           ^ ~
        /home/smarchi/src/binutils-gdb/gdb/z80-tdep.c:351:37: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bit-bitfield-constant-conversion]
              info->prologue_type.interrupt = 1;
                                            ^ ~
        /home/smarchi/src/binutils-gdb/gdb/z80-tdep.c:367:36: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bit-bitfield-constant-conversion]
                      info->prologue_type.fp_sdcc = 1;
                                                  ^ ~
        /home/smarchi/src/binutils-gdb/gdb/z80-tdep.c:375:35: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bit-bitfield-constant-conversion]
              info->prologue_type.fp_sdcc = 1;
                                          ^ ~
        /home/smarchi/src/binutils-gdb/gdb/z80-tdep.c:380:35: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bit-bitfield-constant-conversion]
              info->prologue_type.fp_sdcc = 1;
                                          ^ ~
    
    Fix that by using "unsigned int" as the bitfield's underlying type.
    
    (cherry picked from commit 07f285934886016ddd82cac99a3873e68b499d5c)
    
    Change-Id: I3550a0112f993865dc70b18f02ab11bb5012693d
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30423
    Approved-By: Tom Tromey <tom@tromey.com>
Comment 4 Simon Marchi 2023-05-05 19:33:10 UTC
Fixed by those patches.