boostorg / lexical_cast

General literal text conversions, such as an int represented as a string, or vice versa
https://boost.org/libs/lexical_cast
34 stars 58 forks source link

clang -fsanitize=undefined,integer error #45

Closed jzmaddock closed 8 months ago

jzmaddock commented 3 years ago

When parsing a negative integer, clang triggers an USAN error, test case is simply:


#include <boost/lexical_cast.hpp>

int main()
{
   return boost::lexical_cast<int>("-6575543");
}

Compile with clang++ -fsanitize=undefined,integer and you get:

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior boost/lexical_cast/detail/converter_lexical_streams.hpp:554:51 in 

This one looks like a real error to me - the code is subtracting two unsigned values, the first of which is zero. A better solution might be to assign the unsigned value to the signed result and then negate, though this would have to account for the INT_MIN special case.

Found while investigating https://github.com/boostorg/multiprecision/issues/313

pdimov commented 2 years ago

Subtracting unsigned values is well defined. -fsanitize=integer diagnoses unsigned integer overflows, which is not undefined behavior per standard. Unsigned integers use modular arithmetic.

apolukhin commented 8 months ago

Double checked the issue. The docs for the sanitizer option say that it is not an undefined behavior, and the sanitizer option is meant to draw attention to a place with potential issue.

Fortunately there is a way to tell sanitizer "yes, I know that therecs no issue here" via __attribute__((no_sanitize("unsigned-integer-overflow"))). I'll add those workarounds soon