// Copyright (c) 2020 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include #include #include #if defined(__has_builtin) #if __has_builtin(__builtin_add_overflow) #define HAVE_BUILTIN_ADD_OVERFLOW #endif #elif defined(__GNUC__) #define HAVE_BUILTIN_ADD_OVERFLOW #endif namespace { template void TestAdditionOverflow(FuzzedDataProvider& fuzzed_data_provider) { const T i = fuzzed_data_provider.ConsumeIntegral(); const T j = fuzzed_data_provider.ConsumeIntegral(); const bool is_addition_overflow_custom = AdditionOverflow(i, j); const auto maybe_add{CheckedAdd(i, j)}; const auto sat_add{SaturatingAdd(i, j)}; assert(is_addition_overflow_custom == !maybe_add.has_value()); assert(is_addition_overflow_custom == AdditionOverflow(j, i)); assert(maybe_add == CheckedAdd(j, i)); assert(sat_add == SaturatingAdd(j, i)); #if defined(HAVE_BUILTIN_ADD_OVERFLOW) T result_builtin; const bool is_addition_overflow_builtin = __builtin_add_overflow(i, j, &result_builtin); assert(is_addition_overflow_custom == is_addition_overflow_builtin); if (!is_addition_overflow_custom) { assert(i + j == result_builtin); } #endif if (is_addition_overflow_custom) { assert(sat_add == std::numeric_limits::min() || sat_add == std::numeric_limits::max()); } else { const auto add{i + j}; assert(add == maybe_add.value()); assert(add == sat_add); } } } // namespace FUZZ_TARGET(addition_overflow) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); TestAdditionOverflow(fuzzed_data_provider); TestAdditionOverflow(fuzzed_data_provider); TestAdditionOverflow(fuzzed_data_provider); TestAdditionOverflow(fuzzed_data_provider); TestAdditionOverflow(fuzzed_data_provider); TestAdditionOverflow(fuzzed_data_provider); TestAdditionOverflow(fuzzed_data_provider); TestAdditionOverflow(fuzzed_data_provider); TestAdditionOverflow(fuzzed_data_provider); }