From nobody Thu Mar 12 23:46:29 2026 X-Original-To: dev-commits-ports-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4fX45K3PYQz6WBW8 for ; Thu, 12 Mar 2026 23:46:29 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R12" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4fX45K2nVRz48BS for ; Thu, 12 Mar 2026 23:46:29 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1773359189; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=4DmwT4QsHUZfr4eFMWwE03/REF4FiC+yXWd4fOQ765I=; b=rAfHifzZIqUEoLDlcKmBmPkmIBmUV8R7+7SeuPX6TZaFtWpz0VmoBkhdD2o/aRVnyos+vL QXnAG4WvaEdT6lczCejIiaVrsyt+q0WX0Vu4OpNmajYlxl+JvXt+YgF176mDf0t4w4cDwX 7FwXmiFbVPkzFtyIjbE5FsvjbSBLv5brM67M/h6F/CdyPYo8tLFvBe+uUwgEWSKvxWxpIy Fak4zNrp9RT8ezbi3VOYoGgcq1gyJP91QQTp4sIVsTtG4U0HXSQQZk/2BLCkF9Z52S5ZEr oH4XtYN/Twab6a2/YUMnguEd9Q86WseisE5OEWr6Hr7bbYbEHevWLLoOTJcFSQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1773359189; a=rsa-sha256; cv=none; b=j399SREcaiYFR74Am5m8WNNa4NLPz6mvZgMlE5V/IqAh5RMAR6Cv+NB2O5Kf/Lq24pV8Nl rG1TeVJQiJU9rhTbVG0wBDUnE8sPJ4AXi4CD3lMc7HfITxFihSqusdFaDHHXILRdUo6Kkw 89q0V9D6SBoGRS3OPCEmYlJn2DiAWv2lNi5YQ6g2xlm7Fj5z26kKo4QNqDOdFl6+VR7mNc gC6UuzLuRwnZWnmiTv0+tlgms2Cv3rNX3+yO2AAQGtQlymnluQiEhQ0gsAVnCqWkhL/5EJ lRDQyjsxX7qGIwH1zc16GhmzrDYV/y0BBzUH35wWeUSpjr32rjiRyo/oL8eWpg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1773359189; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=4DmwT4QsHUZfr4eFMWwE03/REF4FiC+yXWd4fOQ765I=; b=cmmUUUuBdcnAfcgCcobJwKGUqIEtLnQmOOrJEAf6YX8DgGLUcJHKfXk2cN83tF/ASg3T/S u83XYYlyzG7rN5eCCMu2J5ap6AD26avXBLyQasIVocvC+j4+qFpu9eYdzytSroZ7br7qeE UVBzEcSXbrwWUIGF69faotCrhaCQoIruVCpmW2x+ZJeMxk7yW0DeUrg7aadNO3M0yuuegT nPwgjGF2SqlFsqMcMC/NxKz3J+sdPtODyTXMryfL4KLvkdfSic54MUEr1e6XsSnaPyMFF9 DGs+8/qP+fSyblmHB6BdRidXEjFSXUE0on1VfLzfYU6qeNcfpQS3OiDQOi0rDQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4fX45K2ChCz16jP for ; Thu, 12 Mar 2026 23:46:29 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 22cc6 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 12 Mar 2026 23:46:29 +0000 To: ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org From: Dimitry Andric Subject: git: 37ed2bf6371b - main - devel/gcc-arm-embedded: fix build with clang 21 List-Id: Commits to the main branch of the FreeBSD ports repository List-Archive: https://lists.freebsd.org/archives/dev-commits-ports-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-ports-main@freebsd.org Sender: owner-dev-commits-ports-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: dim X-Git-Repository: ports X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 37ed2bf6371b0b273013a710ee32f6addf768a62 Auto-Submitted: auto-generated Date: Thu, 12 Mar 2026 23:46:29 +0000 Message-Id: <69b35055.22cc6.74ea6c82@gitrepo.freebsd.org> The branch main has been updated by dim: URL: https://cgit.FreeBSD.org/ports/commit/?id=37ed2bf6371b0b273013a710ee32f6addf768a62 commit 37ed2bf6371b0b273013a710ee32f6addf768a62 Author: Dimitry Andric AuthorDate: 2026-02-13 21:28:34 +0000 Commit: Dimitry Andric CommitDate: 2026-03-12 23:46:18 +0000 devel/gcc-arm-embedded: fix build with clang 21 With clang 21 devel/gcc-arm-embedded fails to build, with errors similar to: /wrkdirs/usr/ports/devel/gcc-arm-embedded/work-default/src/binutils-gdb/binutils/readelf.c:23278:37: error: pointer comparison always evaluates to false [-Werror,-Wtautological-compare] 23278 | || inote.namedata + inote.namesz < inote.namedata) | ^ and later many instances of: In file included from :1: In file included from /wrkdirs/usr/ports/devel/gcc-arm-embedded/work-default/src/binutils-gdb--gdb/gdb/defs.h:63: /wrkdirs/usr/ports/devel/gcc-arm-embedded/work-default/src/binutils-gdb--gdb/gdb/../gdbsupport/enum-flags.h:97:34: error: non-type template argument is not a constant expression 97 | integer_for_size(T (-1) < T (0))>::type | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /wrkdirs/usr/ports/devel/gcc-arm-embedded/work-default/src/binutils-gdb--gdb/gdb/../gdbsupport/enum-flags.h:134:20: note: in instantiation of template class 'enum_underlying_type' requested here 134 | typedef typename enum_underlying_type::type underlying_type; | ^ /wrkdirs/usr/ports/devel/gcc-arm-embedded/work-default/src/binutils-gdb--gdb/gdb/ui-out.h:385:16: note: in instantiation of template class 'enum_flags' requested here 385 | ui_out_flags m_flags; | ^ /wrkdirs/usr/ports/devel/gcc-arm-embedded/work-default/src/binutils-gdb--gdb/gdb/../gdbsupport/enum-flags.h:97:52: note: integer value -1 is outside the valid range of values [0, 15] for the enumeration type 'ui_out_flag' 97 | integer_for_size(T (-1) < T (0))>::type | ^ The readelf error is due to it assuming pointer wrapping, which is undefined behavior. This can be worked around by casting the pointers to uintptr_t, or by adding -fno-strict-overflow to the CFLAGS (but if you are messing with the CFLAGS, you might as well disable -Werror). The enum errors are because it is no longer allowed to cast integer values to enum values, if they fall outside of the valid range. Upstream fixed this in , which applies with a small bit of editing. PR: 293168 Approved by: maintainer timeout (2 weeks) MFH: 2026Q1 --- ...s-gdb--gdb_gdb_unittests_enum-flags-selftests.c | 36 +++++ ...patch-binutils-gdb--gdb_gdbsupport_enum-flags.h | 156 +++++++++++++++++++++ .../patch-binutils-gdb--gdb_include_diagnostics.h | 25 ++++ .../files/patch-binutils-gdb_binutils_readelf.c | 11 ++ ...nutils-gdb_gdb_unittests_enum-flags-selftests.c | 36 +++++ .../patch-binutils-gdb_gdbsupport_enum-flags.h | 156 +++++++++++++++++++++ .../files/patch-binutils-gdb_include_diagnostics.h | 25 ++++ 7 files changed, 445 insertions(+) diff --git a/devel/gcc-arm-embedded/files/patch-binutils-gdb--gdb_gdb_unittests_enum-flags-selftests.c b/devel/gcc-arm-embedded/files/patch-binutils-gdb--gdb_gdb_unittests_enum-flags-selftests.c new file mode 100644 index 000000000000..3819039c420b --- /dev/null +++ b/devel/gcc-arm-embedded/files/patch-binutils-gdb--gdb_gdb_unittests_enum-flags-selftests.c @@ -0,0 +1,36 @@ +--- binutils-gdb--gdb/gdb/unittests/enum-flags-selftests.c.orig 2024-11-30 00:01:16 UTC ++++ binutils-gdb--gdb/gdb/unittests/enum-flags-selftests.c +@@ -233,33 +233,6 @@ CHECK_VALID (true, EF, true ? RE () : EF ()) + CHECK_VALID (true, EF, true ? EF () : RE ()) + CHECK_VALID (true, EF, true ? RE () : EF ()) + +-/* These are valid, but it's not a big deal since you won't be able to +- assign the resulting integer to an enum or an enum_flags without a +- cast. +- +- The latter two tests are disabled on older GCCs because they +- incorrectly fail with gcc 4.8 and 4.9 at least. Running the test +- outside a SFINAE context shows: +- +- invalid user-defined conversion from ‘EF’ to ‘RE2’ +- +- They've been confirmed to compile/pass with gcc 5.3, gcc 7.1 and +- clang 3.7. */ +- +-CHECK_VALID (true, int, true ? EF () : EF2 ()) +-CHECK_VALID (true, int, true ? EF2 () : EF ()) +-CHECK_VALID (true, int, true ? EF () : RE2 ()) +-CHECK_VALID (true, int, true ? RE2 () : EF ()) +- +-/* Same, but with an unsigned enum. */ +- +-typedef unsigned int uns; +- +-CHECK_VALID (true, uns, true ? EF () : UEF ()) +-CHECK_VALID (true, uns, true ? UEF () : EF ()) +-CHECK_VALID (true, uns, true ? EF () : URE ()) +-CHECK_VALID (true, uns, true ? URE () : EF ()) +- + /* Unfortunately this can't work due to the way C++ computes the + return type of the ternary conditional operator. int isn't + implicitly convertible to the raw enum type, so the type of the diff --git a/devel/gcc-arm-embedded/files/patch-binutils-gdb--gdb_gdbsupport_enum-flags.h b/devel/gcc-arm-embedded/files/patch-binutils-gdb--gdb_gdbsupport_enum-flags.h new file mode 100644 index 000000000000..de82593c10f0 --- /dev/null +++ b/devel/gcc-arm-embedded/files/patch-binutils-gdb--gdb_gdbsupport_enum-flags.h @@ -0,0 +1,156 @@ +--- binutils-gdb--gdb/gdbsupport/enum-flags.h.orig 2024-11-30 00:01:16 UTC ++++ binutils-gdb--gdb/gdbsupport/enum-flags.h +@@ -75,30 +75,6 @@ + namespace. The compiler finds the corresponding + is_enum_flags_enum_type function via ADL. */ + +-/* Note that std::underlying_type is not what we want here, +- since that returns unsigned int even when the enum decays to signed +- int. */ +-template class integer_for_size { typedef void type; }; +-template<> struct integer_for_size<1, 0> { typedef uint8_t type; }; +-template<> struct integer_for_size<2, 0> { typedef uint16_t type; }; +-template<> struct integer_for_size<4, 0> { typedef uint32_t type; }; +-template<> struct integer_for_size<8, 0> { typedef uint64_t type; }; +-template<> struct integer_for_size<1, 1> { typedef int8_t type; }; +-template<> struct integer_for_size<2, 1> { typedef int16_t type; }; +-template<> struct integer_for_size<4, 1> { typedef int32_t type; }; +-template<> struct integer_for_size<8, 1> { typedef int64_t type; }; +- +-template +-struct enum_underlying_type +-{ +- DIAGNOSTIC_PUSH +- DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION +- typedef typename +- integer_for_size(T (-1) < T (0))>::type +- type; +- DIAGNOSTIC_POP +-}; +- + namespace enum_flags_detail + { + +@@ -119,11 +95,62 @@ using EnumIsUnsigned + /* gdb::Requires trait helpers. */ + template + using EnumIsUnsigned +- = std::is_unsigned::type>; ++ = std::is_unsigned::type>; ++ ++/* Helper to detect whether an enum has a fixed underlying type. This can be ++ achieved by using a scoped enum (in which case the type is "int") or ++ an explicit underlying type. C-style enums that are unscoped or do not ++ have an explicit underlying type have an implementation-defined underlying ++ type. ++ ++ https://timsong-cpp.github.io/cppwp/n4659/dcl.enum#5 ++ ++ We need this trait in order to ensure that operator~ below does NOT ++ operate on old-style enums. This is because we apply operator~ on ++ the value and then cast the result to the enum_type. This is however ++ Undefined Behavior if the result does not fit in the range of possible ++ values for the enum. For enums with fixed underlying type, the entire ++ range of the integer is available. However, for old-style enums, the range ++ is only the smallest bit-field that can hold all the values of the ++ enumeration, typically much smaller than the underlying integer: ++ ++ https://timsong-cpp.github.io/cppwp/n4659/expr.static.cast#10 ++ https://timsong-cpp.github.io/cppwp/n4659/dcl.enum#8 ++ ++ To implement this, we leverage the fact that, since C++17, enums with ++ fixed underlying type can be list-initialized from an integer: ++ https://timsong-cpp.github.io/cppwp/n4659/dcl.init.list#3.7 ++ ++ Old-style enums cannot be initialized like that, leading to ill-formed ++ code. ++ ++ We then use this together with SFINAE to create the desired trait. ++ ++*/ ++template ++struct EnumHasFixedUnderlyingType : std::false_type ++{ ++ static_assert(std::is_enum::value); ++}; ++ ++/* Specialization that is active only if enum_type can be ++ list-initialized from an integer (0). Only enums with fixed ++ underlying type satisfy this property in C++17. */ + template +-using EnumIsSigned +- = std::is_signed::type>; ++struct EnumHasFixedUnderlyingType> : std::true_type ++{ ++ static_assert(std::is_enum::value); ++}; + ++template ++using EnumIsSafeForBitwiseComplement = std::conjunction< ++ EnumIsUnsigned, ++ EnumHasFixedUnderlyingType ++>; ++ ++template ++using EnumIsUnsafeForBitwiseComplement = std::negation>; ++ + } + + template +@@ -131,7 +158,7 @@ class enum_flags (public) + { + public: + typedef E enum_type; +- typedef typename enum_underlying_type::type underlying_type; ++ typedef typename std::underlying_type::type underlying_type; + + /* For to_string. Maps one enumerator of E to a string. */ + struct string_mapping +@@ -394,33 +421,41 @@ template , + typename +- = gdb::Requires>> ++ = gdb::Requires>> + constexpr enum_type + operator~ (enum_type e) + { + using underlying = typename enum_flags::underlying_type; +- return (enum_type) ~underlying (e); ++ /* Cast to ULONGEST first, to prevent integer promotions from enums ++ with fixed underlying type std::uint8_t or std::uint16_t to ++ signed int. This ensures we apply the bitwise complement on an ++ unsigned type. */ ++ return (enum_type)(underlying) ~ULONGEST (e); + } + + template , +- typename = gdb::Requires>> ++ typename = gdb::Requires>> + constexpr void operator~ (enum_type e) = delete; + + template , + typename +- = gdb::Requires>> ++ = gdb::Requires>> + constexpr enum_flags + operator~ (enum_flags e) + { + using underlying = typename enum_flags::underlying_type; +- return (enum_type) ~underlying (e); ++ /* Cast to ULONGEST first, to prevent integer promotions from enums ++ with fixed underlying type std::uint8_t or std::uint16_t to ++ signed int. This ensures we apply the bitwise complement on an ++ unsigned type. */ ++ return (enum_type)(underlying) ~ULONGEST (e); + } + + template , +- typename = gdb::Requires>> ++ typename = gdb::Requires>> + constexpr void operator~ (enum_flags e) = delete; + + /* Delete operator<< and operator>>. */ diff --git a/devel/gcc-arm-embedded/files/patch-binutils-gdb--gdb_include_diagnostics.h b/devel/gcc-arm-embedded/files/patch-binutils-gdb--gdb_include_diagnostics.h new file mode 100644 index 000000000000..109e6c4fe8c5 --- /dev/null +++ b/devel/gcc-arm-embedded/files/patch-binutils-gdb--gdb_include_diagnostics.h @@ -0,0 +1,25 @@ +--- binutils-gdb--gdb/include/diagnostics.h.orig 2024-11-30 00:01:16 UTC ++++ binutils-gdb--gdb/include/diagnostics.h +@@ -76,11 +76,6 @@ + # define DIAGNOSTIC_ERROR_SWITCH \ + DIAGNOSTIC_ERROR ("-Wswitch") + +-# if __has_warning ("-Wenum-constexpr-conversion") +-# define DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION \ +- DIAGNOSTIC_IGNORE ("-Wenum-constexpr-conversion") +-# endif +- + #elif defined (__GNUC__) /* GCC */ + + # define DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS \ +@@ -157,10 +152,6 @@ + + #ifndef DIAGNOSTIC_ERROR_SWITCH + # define DIAGNOSTIC_ERROR_SWITCH +-#endif +- +-#ifndef DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION +-# define DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION + #endif + + #endif /* DIAGNOSTICS_H */ diff --git a/devel/gcc-arm-embedded/files/patch-binutils-gdb_binutils_readelf.c b/devel/gcc-arm-embedded/files/patch-binutils-gdb_binutils_readelf.c new file mode 100644 index 000000000000..15329156a357 --- /dev/null +++ b/devel/gcc-arm-embedded/files/patch-binutils-gdb_binutils_readelf.c @@ -0,0 +1,11 @@ +--- binutils-gdb/binutils/readelf.c.orig 2024-11-20 17:30:17 UTC ++++ binutils-gdb/binutils/readelf.c +@@ -23275,7 +23275,7 @@ process_v850_notes (Filedata * filedata, uint64_t offs + + /* Prevent out-of-bounds indexing. */ + if ( inote.namedata + inote.namesz > end +- || inote.namedata + inote.namesz < inote.namedata) ++ || (uintptr_t)inote.namedata + inote.namesz < (uintptr_t)inote.namedata) + { + warn (_("corrupt namesz found in note at offset %#zx\n"), + (char *) external - (char *) pnotes); diff --git a/devel/gcc-arm-embedded/files/patch-binutils-gdb_gdb_unittests_enum-flags-selftests.c b/devel/gcc-arm-embedded/files/patch-binutils-gdb_gdb_unittests_enum-flags-selftests.c new file mode 100644 index 000000000000..d402a5ebbf08 --- /dev/null +++ b/devel/gcc-arm-embedded/files/patch-binutils-gdb_gdb_unittests_enum-flags-selftests.c @@ -0,0 +1,36 @@ +--- binutils-gdb/gdb/unittests/enum-flags-selftests.c.orig 2024-11-20 17:30:17 UTC ++++ binutils-gdb/gdb/unittests/enum-flags-selftests.c +@@ -233,33 +233,6 @@ CHECK_VALID (true, EF, true ? RE () : EF ()) + CHECK_VALID (true, EF, true ? EF () : RE ()) + CHECK_VALID (true, EF, true ? RE () : EF ()) + +-/* These are valid, but it's not a big deal since you won't be able to +- assign the resulting integer to an enum or an enum_flags without a +- cast. +- +- The latter two tests are disabled on older GCCs because they +- incorrectly fail with gcc 4.8 and 4.9 at least. Running the test +- outside a SFINAE context shows: +- +- invalid user-defined conversion from ‘EF’ to ‘RE2’ +- +- They've been confirmed to compile/pass with gcc 5.3, gcc 7.1 and +- clang 3.7. */ +- +-CHECK_VALID (true, int, true ? EF () : EF2 ()) +-CHECK_VALID (true, int, true ? EF2 () : EF ()) +-CHECK_VALID (true, int, true ? EF () : RE2 ()) +-CHECK_VALID (true, int, true ? RE2 () : EF ()) +- +-/* Same, but with an unsigned enum. */ +- +-typedef unsigned int uns; +- +-CHECK_VALID (true, uns, true ? EF () : UEF ()) +-CHECK_VALID (true, uns, true ? UEF () : EF ()) +-CHECK_VALID (true, uns, true ? EF () : URE ()) +-CHECK_VALID (true, uns, true ? URE () : EF ()) +- + /* Unfortunately this can't work due to the way C++ computes the + return type of the ternary conditional operator. int isn't + implicitly convertible to the raw enum type, so the type of the diff --git a/devel/gcc-arm-embedded/files/patch-binutils-gdb_gdbsupport_enum-flags.h b/devel/gcc-arm-embedded/files/patch-binutils-gdb_gdbsupport_enum-flags.h new file mode 100644 index 000000000000..8608c93cea35 --- /dev/null +++ b/devel/gcc-arm-embedded/files/patch-binutils-gdb_gdbsupport_enum-flags.h @@ -0,0 +1,156 @@ +--- binutils-gdb/gdbsupport/enum-flags.h.orig 2024-11-20 17:30:17 UTC ++++ binutils-gdb/gdbsupport/enum-flags.h +@@ -75,30 +75,6 @@ + namespace. The compiler finds the corresponding + is_enum_flags_enum_type function via ADL. */ + +-/* Note that std::underlying_type is not what we want here, +- since that returns unsigned int even when the enum decays to signed +- int. */ +-template class integer_for_size { typedef void type; }; +-template<> struct integer_for_size<1, 0> { typedef uint8_t type; }; +-template<> struct integer_for_size<2, 0> { typedef uint16_t type; }; +-template<> struct integer_for_size<4, 0> { typedef uint32_t type; }; +-template<> struct integer_for_size<8, 0> { typedef uint64_t type; }; +-template<> struct integer_for_size<1, 1> { typedef int8_t type; }; +-template<> struct integer_for_size<2, 1> { typedef int16_t type; }; +-template<> struct integer_for_size<4, 1> { typedef int32_t type; }; +-template<> struct integer_for_size<8, 1> { typedef int64_t type; }; +- +-template +-struct enum_underlying_type +-{ +- DIAGNOSTIC_PUSH +- DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION +- typedef typename +- integer_for_size(T (-1) < T (0))>::type +- type; +- DIAGNOSTIC_POP +-}; +- + namespace enum_flags_detail + { + +@@ -119,11 +95,62 @@ using EnumIsUnsigned + /* gdb::Requires trait helpers. */ + template + using EnumIsUnsigned +- = std::is_unsigned::type>; ++ = std::is_unsigned::type>; ++ ++/* Helper to detect whether an enum has a fixed underlying type. This can be ++ achieved by using a scoped enum (in which case the type is "int") or ++ an explicit underlying type. C-style enums that are unscoped or do not ++ have an explicit underlying type have an implementation-defined underlying ++ type. ++ ++ https://timsong-cpp.github.io/cppwp/n4659/dcl.enum#5 ++ ++ We need this trait in order to ensure that operator~ below does NOT ++ operate on old-style enums. This is because we apply operator~ on ++ the value and then cast the result to the enum_type. This is however ++ Undefined Behavior if the result does not fit in the range of possible ++ values for the enum. For enums with fixed underlying type, the entire ++ range of the integer is available. However, for old-style enums, the range ++ is only the smallest bit-field that can hold all the values of the ++ enumeration, typically much smaller than the underlying integer: ++ ++ https://timsong-cpp.github.io/cppwp/n4659/expr.static.cast#10 ++ https://timsong-cpp.github.io/cppwp/n4659/dcl.enum#8 ++ ++ To implement this, we leverage the fact that, since C++17, enums with ++ fixed underlying type can be list-initialized from an integer: ++ https://timsong-cpp.github.io/cppwp/n4659/dcl.init.list#3.7 ++ ++ Old-style enums cannot be initialized like that, leading to ill-formed ++ code. ++ ++ We then use this together with SFINAE to create the desired trait. ++ ++*/ ++template ++struct EnumHasFixedUnderlyingType : std::false_type ++{ ++ static_assert(std::is_enum::value); ++}; ++ ++/* Specialization that is active only if enum_type can be ++ list-initialized from an integer (0). Only enums with fixed ++ underlying type satisfy this property in C++17. */ + template +-using EnumIsSigned +- = std::is_signed::type>; ++struct EnumHasFixedUnderlyingType> : std::true_type ++{ ++ static_assert(std::is_enum::value); ++}; + ++template ++using EnumIsSafeForBitwiseComplement = std::conjunction< ++ EnumIsUnsigned, ++ EnumHasFixedUnderlyingType ++>; ++ ++template ++using EnumIsUnsafeForBitwiseComplement = std::negation>; ++ + } + + template +@@ -131,7 +158,7 @@ class enum_flags (public) + { + public: + typedef E enum_type; +- typedef typename enum_underlying_type::type underlying_type; ++ typedef typename std::underlying_type::type underlying_type; + + /* For to_string. Maps one enumerator of E to a string. */ + struct string_mapping +@@ -394,33 +421,41 @@ template , + typename +- = gdb::Requires>> ++ = gdb::Requires>> + constexpr enum_type + operator~ (enum_type e) + { + using underlying = typename enum_flags::underlying_type; +- return (enum_type) ~underlying (e); ++ /* Cast to ULONGEST first, to prevent integer promotions from enums ++ with fixed underlying type std::uint8_t or std::uint16_t to ++ signed int. This ensures we apply the bitwise complement on an ++ unsigned type. */ ++ return (enum_type)(underlying) ~ULONGEST (e); + } + + template , +- typename = gdb::Requires>> ++ typename = gdb::Requires>> + constexpr void operator~ (enum_type e) = delete; + + template , + typename +- = gdb::Requires>> ++ = gdb::Requires>> + constexpr enum_flags + operator~ (enum_flags e) + { + using underlying = typename enum_flags::underlying_type; +- return (enum_type) ~underlying (e); ++ /* Cast to ULONGEST first, to prevent integer promotions from enums ++ with fixed underlying type std::uint8_t or std::uint16_t to ++ signed int. This ensures we apply the bitwise complement on an ++ unsigned type. */ ++ return (enum_type)(underlying) ~ULONGEST (e); + } + + template , +- typename = gdb::Requires>> ++ typename = gdb::Requires>> + constexpr void operator~ (enum_flags e) = delete; + + /* Delete operator<< and operator>>. */ diff --git a/devel/gcc-arm-embedded/files/patch-binutils-gdb_include_diagnostics.h b/devel/gcc-arm-embedded/files/patch-binutils-gdb_include_diagnostics.h new file mode 100644 index 000000000000..6176e26fc03c --- /dev/null +++ b/devel/gcc-arm-embedded/files/patch-binutils-gdb_include_diagnostics.h @@ -0,0 +1,25 @@ +--- binutils-gdb/include/diagnostics.h.orig 2024-11-20 17:30:17 UTC ++++ binutils-gdb/include/diagnostics.h +@@ -76,11 +76,6 @@ + # define DIAGNOSTIC_ERROR_SWITCH \ + DIAGNOSTIC_ERROR ("-Wswitch") + +-# if __has_warning ("-Wenum-constexpr-conversion") +-# define DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION \ +- DIAGNOSTIC_IGNORE ("-Wenum-constexpr-conversion") +-# endif +- + #elif defined (__GNUC__) /* GCC */ + + # define DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS \ +@@ -157,10 +152,6 @@ + + #ifndef DIAGNOSTIC_ERROR_SWITCH + # define DIAGNOSTIC_ERROR_SWITCH +-#endif +- +-#ifndef DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION +-# define DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION + #endif + + #endif /* DIAGNOSTICS_H */