Bitcoin Core Fuzz Coverage Report

Coverage Report

Created: 2026-03-24 13:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/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 <cassert>
9
#include <climits>
10
#include <concepts>
11
#include <limits>
12
#include <optional>
13
#include <type_traits>
14
15
template <class T>
16
[[nodiscard]] bool AdditionOverflow(const T i, const T j) noexcept
17
0
{
18
0
    static_assert(std::is_integral_v<T>, "Integral required.");
19
0
    if constexpr (std::numeric_limits<T>::is_signed) {
20
0
        return (i > 0 && j > std::numeric_limits<T>::max() - i) ||
21
0
               (i < 0 && j < std::numeric_limits<T>::min() - i);
22
0
    }
23
0
    return std::numeric_limits<T>::max() - i < j;
24
0
}
Unexecuted instantiation: bool AdditionOverflow<long>(long, long)
Unexecuted instantiation: bool AdditionOverflow<unsigned long>(unsigned long, unsigned long)
Unexecuted instantiation: bool AdditionOverflow<int>(int, int)
Unexecuted instantiation: bool AdditionOverflow<unsigned int>(unsigned int, unsigned int)
Unexecuted instantiation: bool AdditionOverflow<short>(short, short)
Unexecuted instantiation: bool AdditionOverflow<unsigned short>(unsigned short, unsigned short)
Unexecuted instantiation: bool AdditionOverflow<char>(char, char)
Unexecuted instantiation: bool AdditionOverflow<unsigned char>(unsigned char, unsigned char)
Unexecuted instantiation: bool AdditionOverflow<signed char>(signed char, signed char)
25
26
template <class T>
27
[[nodiscard]] std::optional<T> CheckedAdd(const T i, const T j) noexcept
28
0
{
29
0
    if (AdditionOverflow(i, j)) {
30
0
        return std::nullopt;
31
0
    }
32
0
    return i + j;
33
0
}
Unexecuted instantiation: std::optional<long> CheckedAdd<long>(long, long)
Unexecuted instantiation: std::optional<unsigned long> CheckedAdd<unsigned long>(unsigned long, unsigned long)
Unexecuted instantiation: std::optional<int> CheckedAdd<int>(int, int)
Unexecuted instantiation: std::optional<unsigned int> CheckedAdd<unsigned int>(unsigned int, unsigned int)
Unexecuted instantiation: std::optional<short> CheckedAdd<short>(short, short)
Unexecuted instantiation: std::optional<unsigned short> CheckedAdd<unsigned short>(unsigned short, unsigned short)
Unexecuted instantiation: std::optional<char> CheckedAdd<char>(char, char)
Unexecuted instantiation: std::optional<unsigned char> CheckedAdd<unsigned char>(unsigned char, unsigned char)
Unexecuted instantiation: std::optional<signed char> CheckedAdd<signed char>(signed char, signed char)
34
35
template <std::unsigned_integral T, std::unsigned_integral U>
36
[[nodiscard]] constexpr bool TrySub(T& i, const U j) noexcept
37
0
{
38
0
    if (i < T{j}) return false;
39
0
    i -= T{j};
40
0
    return true;
41
0
}
Unexecuted instantiation: _Z6TrySubITkSt17unsigned_integralmTkSt17unsigned_integralbEbRT_T0_
Unexecuted instantiation: _Z6TrySubITkSt17unsigned_integralmTkSt17unsigned_integralmEbRT_T0_
42
43
template <class 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) {
48
0
            return std::numeric_limits<T>::max();
49
0
        }
50
0
        if (i < 0 && j < std::numeric_limits<T>::min() - i) {
51
0
            return std::numeric_limits<T>::min();
52
0
        }
53
0
    } else {
54
0
        if (std::numeric_limits<T>::max() - i < j) {
55
0
            return std::numeric_limits<T>::max();
56
0
        }
57
0
    }
58
0
    return i + j;
59
0
}
Unexecuted instantiation: long SaturatingAdd<long>(long, long)
Unexecuted instantiation: unsigned long SaturatingAdd<unsigned long>(unsigned long, unsigned long)
Unexecuted instantiation: int SaturatingAdd<int>(int, int)
Unexecuted instantiation: unsigned int SaturatingAdd<unsigned int>(unsigned int, unsigned int)
Unexecuted instantiation: short SaturatingAdd<short>(short, short)
Unexecuted instantiation: unsigned short SaturatingAdd<unsigned short>(unsigned short, unsigned short)
Unexecuted instantiation: char SaturatingAdd<char>(char, char)
Unexecuted instantiation: unsigned char SaturatingAdd<unsigned char>(unsigned char, unsigned char)
Unexecuted instantiation: signed char SaturatingAdd<signed char>(signed char, signed char)
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
0
{
72
0
    assert(divisor > 0);
73
0
    return dividend / divisor + (dividend % divisor != 0);
74
0
}
Unexecuted instantiation: _Z7CeilDivITkSt17unsigned_integralmTkSt17unsigned_integraljEDaT_T0_
Unexecuted instantiation: _Z7CeilDivITkSt17unsigned_integralmTkSt17unsigned_integralmEDaT_T0_
Unexecuted instantiation: _Z7CeilDivITkSt17unsigned_integraljTkSt17unsigned_integralmEDaT_T0_
Unexecuted instantiation: _Z7CeilDivITkSt17unsigned_integraljTkSt17unsigned_integraljEDaT_T0_
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
0
{
85
0
    if (shift == 0 || input == 0) return input;
86
    // Avoid undefined c++ behaviour if shift is >= number of bits in T.
87
0
    if (shift >= sizeof(T) * CHAR_BIT) return std::nullopt;
88
    // If input << shift is too big to fit in T, return nullopt.
89
0
    if (input > (std::numeric_limits<T>::max() >> shift)) return std::nullopt;
90
0
    if (input < (std::numeric_limits<T>::min() >> shift)) return std::nullopt;
91
0
    return input << shift;
92
0
}
Unexecuted instantiation: _Z16CheckedLeftShiftITkSt8integralyESt8optionalIT_ES1_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkSt8integralaESt8optionalIT_ES1_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkSt8integralsESt8optionalIT_ES1_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkSt8integraliESt8optionalIT_ES1_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkSt8integralhESt8optionalIT_ES1_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkSt8integraltESt8optionalIT_ES1_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkSt8integraljESt8optionalIT_ES1_j
Unexecuted instantiation: _Z16CheckedLeftShiftITkSt8integralmESt8optionalIT_ES1_j
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
0
{
104
0
    if (auto result{CheckedLeftShift(input, shift)}) return *result;
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();
108
0
}
Unexecuted instantiation: _Z19SaturatingLeftShiftITkSt8integralaET_S0_j
Unexecuted instantiation: _Z19SaturatingLeftShiftITkSt8integralsET_S0_j
Unexecuted instantiation: _Z19SaturatingLeftShiftITkSt8integraliET_S0_j
Unexecuted instantiation: _Z19SaturatingLeftShiftITkSt8integralhET_S0_j
Unexecuted instantiation: _Z19SaturatingLeftShiftITkSt8integraltET_S0_j
Unexecuted instantiation: _Z19SaturatingLeftShiftITkSt8integraljET_S0_j
Unexecuted instantiation: _Z19SaturatingLeftShiftITkSt8integralmET_S0_j
109
110
#endif // BITCOIN_UTIL_OVERFLOW_H