fuzz coverage

Coverage Report

Created: 2025-06-01 19:34

/Users/eugenesiegel/btc/bitcoin/src/util/overflow.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2021-2022 The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5
#ifndef BITCOIN_UTIL_OVERFLOW_H
6
#define BITCOIN_UTIL_OVERFLOW_H
7
8
#include <climits>
9
#include <concepts>
10
#include <limits>
11
#include <optional>
12
#include <type_traits>
13
14
template <class T>
15
[[nodiscard]] bool AdditionOverflow(const T i, const T j) noexcept
16
20.3M
{
17
20.3M
    static_assert(std::is_integral_v<T>, "Integral required.");
18
20.3M
    if constexpr (std::numeric_limits<T>::is_signed) {
19
0
        return (i > 0 && j > std::numeric_limits<T>::max() - i) ||
20
0
               (i < 0 && j < std::numeric_limits<T>::min() - i);
21
0
    }
22
0
    return std::numeric_limits<T>::max() - i < j;
23
20.3M
}
Unexecuted instantiation: _Z16AdditionOverflowIxEbT_S0_
Unexecuted instantiation: _Z16AdditionOverflowIyEbT_S0_
Unexecuted instantiation: _Z16AdditionOverflowIiEbT_S0_
Unexecuted instantiation: _Z16AdditionOverflowIjEbT_S0_
Unexecuted instantiation: _Z16AdditionOverflowIsEbT_S0_
Unexecuted instantiation: _Z16AdditionOverflowItEbT_S0_
Unexecuted instantiation: _Z16AdditionOverflowIcEbT_S0_
Unexecuted instantiation: _Z16AdditionOverflowIhEbT_S0_
Unexecuted instantiation: _Z16AdditionOverflowIaEbT_S0_
_Z16AdditionOverflowImEbT_S0_
Line
Count
Source
16
20.3M
{
17
20.3M
    static_assert(std::is_integral_v<T>, "Integral required.");
18
    if constexpr (std::numeric_limits<T>::is_signed) {
19
        return (i > 0 && j > std::numeric_limits<T>::max() - i) ||
20
               (i < 0 && j < std::numeric_limits<T>::min() - i);
21
    }
22
20.3M
    return std::numeric_limits<T>::max() - i < j;
23
20.3M
}
24
25
template <class T>
26
[[nodiscard]] std::optional<T> CheckedAdd(const T i, const T j) noexcept
27
20.3M
{
28
20.3M
    if (AdditionOverflow(i, j)) {
29
0
        return std::nullopt;
30
0
    }
31
20.3M
    return i + j;
32
20.3M
}
Unexecuted instantiation: _Z10CheckedAddIxENSt3__18optionalIT_EES2_S2_
Unexecuted instantiation: _Z10CheckedAddIyENSt3__18optionalIT_EES2_S2_
Unexecuted instantiation: _Z10CheckedAddIiENSt3__18optionalIT_EES2_S2_
Unexecuted instantiation: _Z10CheckedAddIjENSt3__18optionalIT_EES2_S2_
Unexecuted instantiation: _Z10CheckedAddIsENSt3__18optionalIT_EES2_S2_
Unexecuted instantiation: _Z10CheckedAddItENSt3__18optionalIT_EES2_S2_
Unexecuted instantiation: _Z10CheckedAddIcENSt3__18optionalIT_EES2_S2_
Unexecuted instantiation: _Z10CheckedAddIhENSt3__18optionalIT_EES2_S2_
Unexecuted instantiation: _Z10CheckedAddIaENSt3__18optionalIT_EES2_S2_
_Z10CheckedAddImENSt3__18optionalIT_EES2_S2_
Line
Count
Source
27
20.3M
{
28
20.3M
    if (AdditionOverflow(i, j)) {
29
0
        return std::nullopt;
30
0
    }
31
20.3M
    return i + j;
32
20.3M
}
33
34
template <class T>
35
[[nodiscard]] T SaturatingAdd(const T i, const T j) noexcept
36
0
{
37
0
    if constexpr (std::numeric_limits<T>::is_signed) {
38
0
        if (i > 0 && j > std::numeric_limits<T>::max() - i) {
39
0
            return std::numeric_limits<T>::max();
40
0
        }
41
0
        if (i < 0 && j < std::numeric_limits<T>::min() - i) {
42
0
            return std::numeric_limits<T>::min();
43
0
        }
44
0
    } else {
45
0
        if (std::numeric_limits<T>::max() - i < j) {
46
0
            return std::numeric_limits<T>::max();
47
0
        }
48
0
    }
49
0
    return i + j;
50
0
}
Unexecuted instantiation: _Z13SaturatingAddIxET_S0_S0_
Unexecuted instantiation: _Z13SaturatingAddIyET_S0_S0_
Unexecuted instantiation: _Z13SaturatingAddIiET_S0_S0_
Unexecuted instantiation: _Z13SaturatingAddIjET_S0_S0_
Unexecuted instantiation: _Z13SaturatingAddIsET_S0_S0_
Unexecuted instantiation: _Z13SaturatingAddItET_S0_S0_
Unexecuted instantiation: _Z13SaturatingAddIcET_S0_S0_
Unexecuted instantiation: _Z13SaturatingAddIhET_S0_S0_
Unexecuted instantiation: _Z13SaturatingAddIaET_S0_S0_
51
52
/**
53
 * @brief Left bit shift with overflow checking.
54
 * @param input The input value to be left shifted.
55
 * @param shift The number of bits to left shift.
56
 * @return (input * 2^shift) or nullopt if it would not fit in the return type.
57
 */
58
template <std::integral T>
59
constexpr std::optional<T> CheckedLeftShift(T input, unsigned shift) noexcept
60
0
{
61
0
    if (shift == 0 || input == 0) return input;
62
    // Avoid undefined c++ behaviour if shift is >= number of bits in T.
63
0
    if (shift >= sizeof(T) * CHAR_BIT) return std::nullopt;
64
    // If input << shift is too big to fit in T, return nullopt.
65
0
    if (input > (std::numeric_limits<T>::max() >> shift)) return std::nullopt;
66
0
    if (input < (std::numeric_limits<T>::min() >> shift)) return std::nullopt;
67
0
    return input << shift;
68
0
}
Unexecuted instantiation: _Z16CheckedLeftShiftITkNSt3__18integralEyENS0_8optionalIT_EES2_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkNSt3__18integralEaENS0_8optionalIT_EES2_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkNSt3__18integralEsENS0_8optionalIT_EES2_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkNSt3__18integralEiENS0_8optionalIT_EES2_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkNSt3__18integralEhENS0_8optionalIT_EES2_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkNSt3__18integralEtENS0_8optionalIT_EES2_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkNSt3__18integralEjENS0_8optionalIT_EES2_j
69
70
/**
71
 * @brief Left bit shift with safe minimum and maximum values.
72
 * @param input The input value to be left shifted.
73
 * @param shift The number of bits to left shift.
74
 * @return (input * 2^shift) clamped to fit between the lowest and highest
75
 *         representable values of the type T.
76
 */
77
template <std::integral T>
78
constexpr T SaturatingLeftShift(T input, unsigned shift) noexcept
79
0
{
80
0
    if (auto result{CheckedLeftShift(input, shift)}) return *result;
81
    // If input << shift is too big to fit in T, return biggest positive or negative
82
    // number that fits.
83
0
    return input < 0 ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
84
0
}
Unexecuted instantiation: _Z19SaturatingLeftShiftITkNSt3__18integralEaET_S1_j
Unexecuted instantiation: _Z19SaturatingLeftShiftITkNSt3__18integralEsET_S1_j
Unexecuted instantiation: _Z19SaturatingLeftShiftITkNSt3__18integralEiET_S1_j
Unexecuted instantiation: _Z19SaturatingLeftShiftITkNSt3__18integralEhET_S1_j
Unexecuted instantiation: _Z19SaturatingLeftShiftITkNSt3__18integralEtET_S1_j
Unexecuted instantiation: _Z19SaturatingLeftShiftITkNSt3__18integralEjET_S1_j
Unexecuted instantiation: _Z19SaturatingLeftShiftITkNSt3__18integralEyET_S1_j
85
86
#endif // BITCOIN_UTIL_OVERFLOW_H