[libc][printf] Fix out-of-range shift in float320 printf #144542
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
If you enable
LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_FLOAT320
and use a%f
style printf format directive to print a nonzero number too small to show up in the output digits, e.g.printf("%.2f", 0.001)
, then the output would be intermittently incorrect, becauseDyadicFloat::as_mantissa_type_rounded
would try to shift the 320-bit mantissa right by more than 320 bits, invoking the 'undefined behavior' clause commented in theshift()
function inbig_int.h
.There were already tests in the libc test suite exercising this case, e.g. the subnormal tests in
LlvmLibcSPrintfTest.FloatDecimalConv
use%f
at the default precision of 6 decimal places on tiny numbers such as 2^-1027. But because the behavior is undefined, they don't visibly fail all the time, and in all previous test runs we'd tried with USE_FLOAT320, they had got lucky.The fix is simply to detect an out-of-range right shift before doing it, and instead just set the output value to zero.