-
Notifications
You must be signed in to change notification settings - Fork 190
Pretty: fix Undefined Behavior with NaN floats #282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pretty: fix Undefined Behavior with NaN floats #282
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
convertToUint64
does 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.