Skip to content

Commit

Permalink
Suppress the unsigned-integer-overflow sanitizer warnings and do not …
Browse files Browse the repository at this point in the history
…recover from the integer sanitizer errors (fixes #45) (#73)
  • Loading branch information
apolukhin authored Feb 15, 2024
1 parent 518e28f commit 3433c34
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
compiler: clang++-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
cxxflags: "cxxflags=-fsanitize=address,undefined,integer -fno-sanitize-recover=undefined"
cxxflags: "cxxflags=-fsanitize=address,undefined,integer -fno-sanitize-recover=undefined,integer"
linkflags: "linkflags=-fsanitize=address,undefined,integer"
- toolset: clang
compiler: clang++-14
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,9 @@ namespace boost { namespace detail { namespace lcast {

private:
template <typename Type>
#if defined(__clang__) && (__clang_major__ > 3 || __clang_minor__ > 6)
__attribute__((no_sanitize("unsigned-integer-overflow")))
#endif
bool shr_unsigned(Type& output) {
if (start == finish) return false;
CharT const minus = lcast_char_constants<CharT>::minus;
Expand All @@ -511,6 +514,9 @@ namespace boost { namespace detail { namespace lcast {
}

template <typename Type>
#if defined(__clang__) && (__clang_major__ > 3 || __clang_minor__ > 6)
__attribute__((no_sanitize("unsigned-integer-overflow")))
#endif
bool shr_signed(Type& output) {
if (start == finish) return false;
CharT const minus = lcast_char_constants<CharT>::minus;
Expand Down
9 changes: 7 additions & 2 deletions include/boost/lexical_cast/detail/converter_numeric.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ struct lexical_cast_dynamic_num_not_ignoring_minus
struct lexical_cast_dynamic_num_ignoring_minus
{
template <typename Target, typename Source>
#if defined(__clang__) && (__clang_major__ > 3 || __clang_minor__ > 6)
__attribute__((no_sanitize("unsigned-integer-overflow")))
#endif
static inline bool try_convert(Source arg, Target& result) noexcept {
typedef typename boost::conditional<
boost::is_float<Source>::value,
Expand All @@ -129,8 +132,10 @@ struct lexical_cast_dynamic_num_ignoring_minus
typedef typename usource_lazy_t::type usource_t;

if (arg < 0) {
const bool res = boost::detail::noexcept_numeric_convert<Target, usource_t>(0u - arg, result);
result = static_cast<Target>(0u) - static_cast<Target>(result);
const bool res = boost::detail::noexcept_numeric_convert<Target, usource_t>(
static_cast<usource_t>(0u - static_cast<usource_t>(arg)), result
);
result = static_cast<Target>(0u - result);
return res;
} else {
return boost::detail::noexcept_numeric_convert<Target, usource_t>(arg, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ namespace boost
namespace detail // lcast_to_unsigned
{
template<class T>
#if defined(__clang__) && (__clang_major__ > 3 || __clang_minor__ > 6)
__attribute__((no_sanitize("unsigned-integer-overflow")))
#endif
inline
typename boost::make_unsigned<T>::type lcast_to_unsigned(const T value) noexcept {
typedef typename boost::make_unsigned<T>::type result_type;
Expand Down Expand Up @@ -251,6 +254,9 @@ namespace boost
private:
// Iteration that does not care about grouping/separators and assumes that all
// input characters are digits
#if defined(__clang__) && (__clang_major__ > 3 || __clang_minor__ > 6)
__attribute__((no_sanitize("unsigned-integer-overflow")))
#endif
inline bool main_convert_iteration() noexcept {
CharT const czero = lcast_char_constants<CharT>::zero;
T const maxv = (std::numeric_limits<T>::max)();
Expand Down
8 changes: 4 additions & 4 deletions test/integral_types_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ void test_conversion_from_integral_to_string(CharT)
T const max_val = (limits::max)();
T const half_max_val = max_val / 2;
T const cnt = lcast_integral_test_counter; // to suppress warnings
unsigned int const counter = cnt < half_max_val ? cnt : half_max_val;
T const counter = cnt < half_max_val ? cnt : half_max_val;

unsigned int i;
T i = 0;

// Test values around min:
t = min_val;
Expand Down Expand Up @@ -267,10 +267,10 @@ void test_conversion_from_string_to_integral(CharT)
{
T const half_max_val = max_val / 2;
T const cnt = lcast_integral_test_counter; // to suppress warnings
unsigned int const counter = cnt < half_max_val ? cnt : half_max_val;
T const counter = cnt < half_max_val ? cnt : half_max_val;

T t;
unsigned int i;
T i;

// Test values around min:
t = min_val;
Expand Down

0 comments on commit 3433c34

Please sign in to comment.