Pretty: fix Undefined Behavior with NaN floats#282
Conversation
thiagomacieira
left a comment
There was a problem hiding this comment.
Also looks ok, but a simpler change is to invert the comparison below:
supremum = -2.0 * INT64_MIN; /* -2 * (- 2^63) == 2^64 */
if (!(v < supremum))
return false; /* out of range or NaN */5b0e304 to
e6640b4
Compare
When printing CBOR data containing NaN, function convertToUint64 does an
undefined behavior. This can be reproduced using test cases from
tests/parser/data.cpp:
$ make CC='clang -fsanitize=undefined'
$ printf "\xfb\x7f\xf8\0\0\0\0\0\0" | ./bin/cbordump
src/cborpretty.c:171:17: runtime error: nan is outside the range of
representable values of type 'unsigned long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/cborpretty.c:171:17 in
nan
$ printf "\xf9\x7e\x00" | ./bin/cbordump
src/cborpretty.c:171:17: runtime error: nan is outside the range of
representable values of type 'unsigned long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/cborpretty.c:171:17 in
nan
Fix this by checking whether the value to convert is not NaN.
e6640b4 to
ee3b987
Compare
|
In my humble opinion, both |
Done. Since this is tiny CBOR, I'd prefer the one that generates less code, even if slightly less expressive. Compilers ought to have been able to tell that an isnan and range comparison can be implemented in a single go... but most don't. Meanwhile, in https://gcc.godbolt.org/z/qPK8oehhW with the code I suggested, all four compilers generated optimal code. The "B" (or "C") condition is if CF = 1... wait, that doesn't look right. Testing in https://gcc.godbolt.org/z/da3KqbbWr: the three compilers that inlined the function say "NaN" is in range. Ok, this didn't work. Please change back to your original code. Sorry about the noise! Time to file a missed optimisation report with GCC. |
thiagomacieira
left a comment
There was a problem hiding this comment.
Sorry, this didn't work. Please change back to your original idea.
Oops, we do want an out of range. Or, more specifically, what we actually want: |
When printing CBOR data containing NaN, function
convertToUint64does an undefined behavior. This can be reproduced using test cases fromtests/parser/data.cpp:Fix this by checking whether the value to convert is not NaN.