Skip to content

Commit eab63b5

Browse files
[libc] Fix %m on CPUs with float128 but no int128 (#110053)
This bug is caused by the BigInt implementation failing to initialize from errno. Explanation below, but the fix is a static cast to int. The bug only shows up on risc-v 32 because of a chain of type-oddities: 1) Errno is provided by a struct with an implicit cast to int. 2) The printf parser uses an int128 to store the value of a conversion on systems with long double greater than double. 3) On systems without native int128 support we use our own BigInt instead. These combine such that if both long double and int128 exist (e.g. on x86) there's no issue, errno is implicitly cast to int, which is extended to int128. If long double is double (e.g. on arm32) then int64 is used in the printf parser, the implicit cast works, and there's no issue. The only way this would come up is if the target has a proper long double type, but not int128, which is the case for at least the current risc-v 32 bot.
1 parent c8365fe commit eab63b5

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

libc/src/stdio/printf_core/parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ template <typename ArgProvider> class Parser {
265265
case ('m'):
266266
// %m is an odd conversion in that it doesn't consume an argument, it
267267
// just takes the current value of errno as its argument.
268-
section.conv_val_raw = libc_errno;
268+
section.conv_val_raw = static_cast<int>(libc_errno);
269269
break;
270270
#endif // LIBC_COPT_PRINTF_DISABLE_STRERROR
271271
#ifndef LIBC_COPT_PRINTF_DISABLE_WRITE_INT

0 commit comments

Comments
 (0)