From ae516276684aeb3b7886013ff8a00a5367e530fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Holz?= Date: Thu, 19 Mar 2026 11:14:13 +0100 Subject: [PATCH] AK: Format `char` as `unsigned char` on non-x86 `char` isn't signed in the AArch64 and RISC-V ABIs. --- AK/Format.cpp | 9 +++++++-- Tests/AK/TestFormat.cpp | 11 +++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/AK/Format.cpp b/AK/Format.cpp index 8fc79b3cd9c..bd70ac76ded 100644 --- a/AK/Format.cpp +++ b/AK/Format.cpp @@ -949,8 +949,13 @@ ErrorOr Formatter::format(FormatBuilder& builder, char value) { if (m_mode == Mode::Binary || m_mode == Mode::BinaryUppercase || m_mode == Mode::Decimal || m_mode == Mode::Octal || m_mode == Mode::Hexadecimal || m_mode == Mode::HexadecimalUppercase) { // Trick: signed char != char. (Sometimes weird features are actually helpful.) - Formatter formatter { *this }; - return formatter.format(builder, static_cast(value)); + if constexpr (IsSigned) { + Formatter formatter { *this }; + return formatter.format(builder, static_cast(value)); + } else { + Formatter formatter { *this }; + return formatter.format(builder, static_cast(value)); + } } else { Formatter formatter { *this }; return formatter.format(builder, { &value, 1 }); diff --git a/Tests/AK/TestFormat.cpp b/Tests/AK/TestFormat.cpp index f96de7c2078..0797893b2c8 100644 --- a/Tests/AK/TestFormat.cpp +++ b/Tests/AK/TestFormat.cpp @@ -223,6 +223,17 @@ struct AK::Formatter : Formatter { } }; +TEST_CASE(format_character_as_integer) +{ + EXPECT_EQ(ByteString::formatted("{:x}", 'A'), "41"); + + if constexpr (IsSigned) { + EXPECT_EQ(ByteString::formatted("{:x}", '\x86'), "-7a"); + } else { + EXPECT_EQ(ByteString::formatted("{:x}", '\x86'), "86"); + } +} + TEST_CASE(format_if_supported) { EXPECT_EQ(ByteString::formatted("{}", FormatIfSupported { A {} }), "?");