Coverage Report

Created: 2026-07-14 18:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/bitcoin/src/util/overflow.h
Line
Count
Source
1
// Copyright (c) 2021-present 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 <util/check.h>
9
10
#include <climits>
11
#include <concepts>
12
#include <limits>
13
#include <optional>
14
#include <type_traits>
15
16
template <std::integral T>
17
[[nodiscard]] bool AdditionOverflow(const T i, const T j) noexcept
18
139M
{
19
139M
    if constexpr (std::numeric_limits<T>::is_signed) {
20
0
        return (i > 0 && j > std::numeric_limits<T>::max() - i) ||
  Branch (20:17): [True: 0, False: 0]
  Branch (20:26): [True: 0, False: 0]
21
0
               (i < 0 && j < std::numeric_limits<T>::min() - i);
  Branch (21:17): [True: 0, False: 0]
  Branch (21:26): [True: 0, False: 0]
22
0
    }
23
0
    return std::numeric_limits<T>::max() - i < j;
24
139M
}
_Z16AdditionOverflowITkSt8integralmEbT_S0_
Line
Count
Source
18
139M
{
19
    if constexpr (std::numeric_limits<T>::is_signed) {
20
        return (i > 0 && j > std::numeric_limits<T>::max() - i) ||
21
               (i < 0 && j < std::numeric_limits<T>::min() - i);
22
    }
23
139M
    return std::numeric_limits<T>::max() - i < j;
24
139M
}
Unexecuted instantiation: _Z16AdditionOverflowITkSt8integrallEbT_S0_
25
26
template <class T>
27
[[nodiscard]] std::optional<T> CheckedAdd(const T i, const T j) noexcept
28
139M
{
29
139M
    if (AdditionOverflow(i, j)) {
  Branch (29:9): [True: 0, False: 139M]
  Branch (29:9): [True: 0, False: 0]
30
0
        return std::nullopt;
31
0
    }
32
139M
    return i + j;
33
139M
}
std::optional<unsigned long> CheckedAdd<unsigned long>(unsigned long, unsigned long)
Line
Count
Source
28
139M
{
29
139M
    if (AdditionOverflow(i, j)) {
  Branch (29:9): [True: 0, False: 139M]
30
0
        return std::nullopt;
31
0
    }
32
139M
    return i + j;
33
139M
}
Unexecuted instantiation: std::optional<long> CheckedAdd<long>(long, long)
34
35
template <std::unsigned_integral T, std::unsigned_integral U>
36
[[nodiscard]] constexpr bool TrySub(T& i, const U j) noexcept
37
60.3M
{
38
60.3M
    if (i < T{j}) return false;
  Branch (38:9): [True: 0, False: 45.0M]
  Branch (38:9): [True: 0, False: 15.3M]
39
60.3M
    i -= T{j};
40
60.3M
    return true;
41
60.3M
}
_Z6TrySubITkSt17unsigned_integralmTkSt17unsigned_integralbEbRT_T0_
Line
Count
Source
37
45.0M
{
38
45.0M
    if (i < T{j}) return false;
  Branch (38:9): [True: 0, False: 45.0M]
39
45.0M
    i -= T{j};
40
45.0M
    return true;
41
45.0M
}
_Z6TrySubITkSt17unsigned_integralmTkSt17unsigned_integralmEbRT_T0_
Line
Count
Source
37
15.3M
{
38
15.3M
    if (i < T{j}) return false;
  Branch (38:9): [True: 0, False: 15.3M]
39
15.3M
    i -= T{j};
40
15.3M
    return true;
41
15.3M
}
42
43
template <std::integral T>
44
[[nodiscard]] T SaturatingAdd(const T i, const T j) noexcept
45
0
{
46
0
    if constexpr (std::numeric_limits<T>::is_signed) {
47
0
        if (i > 0 && j > std::numeric_limits<T>::max() - i) {
  Branch (47:13): [True: 0, False: 0]
  Branch (47:22): [True: 0, False: 0]
  Branch (47:13): [True: 0, False: 0]
  Branch (47:22): [True: 0, False: 0]
48
0
            return std::numeric_limits<T>::max();
49
0
        }
50
0
        if (i < 0 && j < std::numeric_limits<T>::min() - i) {
  Branch (50:13): [True: 0, False: 0]
  Branch (50:22): [True: 0, False: 0]
  Branch (50:13): [True: 0, False: 0]
  Branch (50:22): [True: 0, False: 0]
51
0
            return std::numeric_limits<T>::min();
52
0
        }
53
0
    } else {
54
0
        if (std::numeric_limits<T>::max() - i < j) {
  Branch (54:13): [True: 0, False: 0]
55
0
            return std::numeric_limits<T>::max();
56
0
        }
57
0
    }
58
0
    return i + j;
59
0
}
Unexecuted instantiation: _Z13SaturatingAddITkSt8integrallET_S0_S0_
Unexecuted instantiation: _Z13SaturatingAddITkSt8integraliET_S0_S0_
Unexecuted instantiation: _Z13SaturatingAddITkSt8integralmET_S0_S0_
60
61
/**
62
 * @brief Integer ceiling division (for unsigned values).
63
 *
64
 * Computes the smallest integer q such that q * divisor >= dividend.
65
 * Both dividend and divisor must be unsigned, and divisor must be non-zero.
66
 *
67
 * The implementation avoids overflow that can occur with `(dividend + divisor - 1) / divisor`.
68
 */
69
template <std::unsigned_integral Dividend, std::unsigned_integral Divisor>
70
[[nodiscard]] constexpr auto CeilDiv(const Dividend dividend, const Divisor divisor)
71
87.9M
{
72
87.9M
    assert(divisor > 0);
  Branch (72:5): [True: 4.45M, False: 0]
  Branch (72:5): [True: 183k, False: 0]
  Branch (72:5): [True: 83.1M, False: 0]
  Branch (72:5): [True: 147k, False: 0]
73
87.9M
    return dividend / divisor + (dividend % divisor != 0);
74
87.9M
}
_Z7CeilDivITkSt17unsigned_integralmTkSt17unsigned_integraljEDaT_T0_
Line
Count
Source
71
4.45M
{
72
4.45M
    assert(divisor > 0);
  Branch (72:5): [True: 4.45M, False: 0]
73
4.45M
    return dividend / divisor + (dividend % divisor != 0);
74
4.45M
}
_Z7CeilDivITkSt17unsigned_integraljTkSt17unsigned_integraljEDaT_T0_
Line
Count
Source
71
183k
{
72
183k
    assert(divisor > 0);
  Branch (72:5): [True: 183k, False: 0]
73
183k
    return dividend / divisor + (dividend % divisor != 0);
74
183k
}
_Z7CeilDivITkSt17unsigned_integralmTkSt17unsigned_integralmEDaT_T0_
Line
Count
Source
71
83.1M
{
72
83.1M
    assert(divisor > 0);
  Branch (72:5): [True: 83.1M, False: 0]
73
83.1M
    return dividend / divisor + (dividend % divisor != 0);
74
83.1M
}
_Z7CeilDivITkSt17unsigned_integraljTkSt17unsigned_integralmEDaT_T0_
Line
Count
Source
71
147k
{
72
147k
    assert(divisor > 0);
  Branch (72:5): [True: 147k, False: 0]
73
147k
    return dividend / divisor + (dividend % divisor != 0);
74
147k
}
75
76
/**
77
 * @brief Left bit shift with overflow checking.
78
 * @param input The input value to be left shifted.
79
 * @param shift The number of bits to left shift.
80
 * @return (input * 2^shift) or nullopt if it would not fit in the return type.
81
 */
82
template <std::integral T>
83
constexpr std::optional<T> CheckedLeftShift(T input, unsigned shift) noexcept
84
54
{
85
54
    if (shift == 0 || input == 0) return input;
  Branch (85:9): [True: 0, False: 54]
  Branch (85:23): [True: 0, False: 54]
86
    // Avoid undefined c++ behaviour if shift is >= number of bits in T.
87
54
    if (shift >= sizeof(T) * CHAR_BIT) return std::nullopt;
  Branch (87:9): [True: 0, False: 54]
88
    // If input << shift is too big to fit in T, return nullopt.
89
54
    if (input > (std::numeric_limits<T>::max() >> shift)) return std::nullopt;
  Branch (89:9): [True: 0, False: 54]
90
54
    if (input < (std::numeric_limits<T>::min() >> shift)) return std::nullopt;
  Branch (90:9): [True: 0, False: 54]
91
54
    return input << shift;
92
54
}
Unexecuted instantiation: _Z16CheckedLeftShiftITkSt8integralyESt8optionalIT_ES1_j
_Z16CheckedLeftShiftITkSt8integralmESt8optionalIT_ES1_j
Line
Count
Source
84
54
{
85
54
    if (shift == 0 || input == 0) return input;
  Branch (85:9): [True: 0, False: 54]
  Branch (85:23): [True: 0, False: 54]
86
    // Avoid undefined c++ behaviour if shift is >= number of bits in T.
87
54
    if (shift >= sizeof(T) * CHAR_BIT) return std::nullopt;
  Branch (87:9): [True: 0, False: 54]
88
    // If input << shift is too big to fit in T, return nullopt.
89
54
    if (input > (std::numeric_limits<T>::max() >> shift)) return std::nullopt;
  Branch (89:9): [True: 0, False: 54]
90
54
    if (input < (std::numeric_limits<T>::min() >> shift)) return std::nullopt;
  Branch (90:9): [True: 0, False: 54]
91
54
    return input << shift;
92
54
}
93
94
/**
95
 * @brief Left bit shift with safe minimum and maximum values.
96
 * @param input The input value to be left shifted.
97
 * @param shift The number of bits to left shift.
98
 * @return (input * 2^shift) clamped to fit between the lowest and highest
99
 *         representable values of the type T.
100
 */
101
template <std::integral T>
102
constexpr T SaturatingLeftShift(T input, unsigned shift) noexcept
103
54
{
104
54
    if (auto result{CheckedLeftShift(input, shift)}) return *result;
  Branch (104:14): [True: 54, False: 0]
105
    // If input << shift is too big to fit in T, return biggest positive or negative
106
    // number that fits.
107
0
    return input < 0 ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
  Branch (107:12): [True: 0, False: 0]
108
54
}
109
110
#endif // BITCOIN_UTIL_OVERFLOW_H