fuzz coverage

Coverage Report

Created: 2025-09-17 22:41

/Users/eugenesiegel/btc/bitcoin/src/span.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2018-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_SPAN_H
6
#define BITCOIN_SPAN_H
7
8
#include <cassert>
9
#include <cstddef>
10
#include <span>
11
#include <type_traits>
12
#include <utility>
13
14
/** A span is an object that can refer to a contiguous sequence of objects.
15
 *
16
 * Things to be aware of when writing code that deals with spans:
17
 *
18
 * - Similar to references themselves, spans are subject to reference lifetime
19
 *   issues. The user is responsible for making sure the objects pointed to by
20
 *   a span live as long as the span is used. For example:
21
 *
22
 *       std::vector<int> vec{1,2,3,4};
23
 *       std::span<int> sp(vec);
24
 *       vec.push_back(5);
25
 *       printf("%i\n", sp.front()); // UB!
26
 *
27
 *   may exhibit undefined behavior, as increasing the size of a vector may
28
 *   invalidate references.
29
 *
30
 * - One particular pitfall is that spans can be constructed from temporaries,
31
 *   but this is unsafe when the span is stored in a variable, outliving the
32
 *   temporary. For example, this will compile, but exhibits undefined behavior:
33
 *
34
 *       std::span<const int> sp(std::vector<int>{1, 2, 3});
35
 *       printf("%i\n", sp.front()); // UB!
36
 *
37
 *   The lifetime of the vector ends when the statement it is created in ends.
38
 *   Thus the span is left with a dangling reference, and using it is undefined.
39
 *
40
 * - Due to spans automatic creation from range-like objects (arrays, and data
41
 *   types that expose a data() and size() member function), functions that
42
 *   accept a span as input parameter can be called with any compatible
43
 *   range-like object. For example, this works:
44
 *
45
 *       void Foo(std::span<const int> arg);
46
 *
47
 *       Foo(std::vector<int>{1, 2, 3}); // Works
48
 *
49
 *   This is very useful in cases where a function truly does not care about the
50
 *   container, and only about having exactly a range of elements. However it
51
 *   may also be surprising to see automatic conversions in this case.
52
 *
53
 *   When a function accepts a span with a mutable element type, it will not
54
 *   accept temporaries; only variables or other references. For example:
55
 *
56
 *       void FooMut(std::span<int> arg);
57
 *
58
 *       FooMut(std::vector<int>{1, 2, 3}); // Does not compile
59
 *       std::vector<int> baz{1, 2, 3};
60
 *       FooMut(baz); // Works
61
 *
62
 *   This is similar to how functions that take (non-const) lvalue references
63
 *   as input cannot accept temporaries. This does not work either:
64
 *
65
 *       void FooVec(std::vector<int>& arg);
66
 *       FooVec(std::vector<int>{1, 2, 3}); // Does not compile
67
 *
68
 *   The idea is that if a function accepts a mutable reference, a meaningful
69
 *   result will be present in that variable after the call. Passing a temporary
70
 *   is useless in that context.
71
 */
72
73
/** Pop the last element off a span, and return a reference to that element. */
74
template <typename T>
75
T& SpanPopBack(std::span<T>& span)
76
597k
{
77
597k
    size_t size = span.size();
78
597k
    T& back = span.back();
79
597k
    span = span.first(size - 1);
80
597k
    return back;
81
597k
}
_Z11SpanPopBackIKNSt3__16vectorIhNS0_9allocatorIhEEEEERT_RNS0_4spanIS6_Lm18446744073709551615EEE
Line
Count
Source
76
597k
{
77
597k
    size_t size = span.size();
78
597k
    T& back = span.back();
79
597k
    span = span.first(size - 1);
80
597k
    return back;
81
597k
}
Unexecuted instantiation: _Z11SpanPopBackIKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEERT_RNS0_4spanIS8_Lm18446744073709551615EEE
Unexecuted instantiation: _Z11SpanPopBackIKhERT_RNSt3__14spanIS1_Lm18446744073709551615EEE
82
83
template <typename V>
84
auto MakeByteSpan(const V& v) noexcept
85
127M
{
86
127M
    return std::as_bytes(std::span{v});
87
127M
}
_Z12MakeByteSpanINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEEDaRKT_
Line
Count
Source
85
870k
{
86
870k
    return std::as_bytes(std::span{v});
87
870k
}
_Z12MakeByteSpanI9prevectorILj36EhjiEEDaRKT_
Line
Count
Source
85
62.9M
{
86
62.9M
    return std::as_bytes(std::span{v});
87
62.9M
}
_Z12MakeByteSpanINSt3__16vectorIhNS0_9allocatorIhEEEEEDaRKT_
Line
Count
Source
85
15.1M
{
86
15.1M
    return std::as_bytes(std::span{v});
87
15.1M
}
_Z12MakeByteSpanIA4_hEDaRKT_
Line
Count
Source
85
7.32M
{
86
7.32M
    return std::as_bytes(std::span{v});
87
7.32M
}
Unexecuted instantiation: _Z12MakeByteSpanIA5_hEDaRKT_
Unexecuted instantiation: _Z12MakeByteSpanIA78_hEDaRKT_
Unexecuted instantiation: _Z12MakeByteSpanI9prevectorILj16EhjiEEDaRKT_
_Z12MakeByteSpanIA16_hEDaRKT_
Line
Count
Source
85
464k
{
86
464k
    return std::as_bytes(std::span{v});
87
464k
}
_Z12MakeByteSpanINSt3__15arrayIhLm4EEEEDaRKT_
Line
Count
Source
85
7.55M
{
86
7.55M
    return std::as_bytes(std::span{v});
87
7.55M
}
_Z12MakeByteSpanIA12_cEDaRKT_
Line
Count
Source
85
7.32M
{
86
7.32M
    return std::as_bytes(std::span{v});
87
7.32M
}
Unexecuted instantiation: _Z12MakeByteSpanINSt3__15arrayIhLm5EEEEDaRKT_
_Z12MakeByteSpanI7uint256EDaRKT_
Line
Count
Source
85
9.73M
{
86
9.73M
    return std::as_bytes(std::span{v});
87
9.73M
}
Unexecuted instantiation: _Z12MakeByteSpanINSt3__16vectorIh16secure_allocatorIhEEEEDaRKT_
_Z12MakeByteSpanIN7leveldb5SliceEEDaRKT_
Line
Count
Source
85
15.6M
{
86
15.6M
    return std::as_bytes(std::span{v});
87
15.6M
}
Unexecuted instantiation: _Z12MakeByteSpanINSt3__16vectorISt4byteNS0_9allocatorIS2_EEEEEDaRKT_
_Z12MakeByteSpanINSt3__15arrayISt4byteLm168EEEEDaRKT_
Line
Count
Source
85
6.81k
{
86
6.81k
    return std::as_bytes(std::span{v});
87
6.81k
}
Unexecuted instantiation: _Z12MakeByteSpanINSt3__15arrayISt4byteLm8EEEEDaRKT_
Unexecuted instantiation: _Z12MakeByteSpanIA384_hEDaRKT_
88
template <typename V>
89
auto MakeWritableByteSpan(V&& v) noexcept
90
57.2M
{
91
57.2M
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
57.2M
}
Unexecuted instantiation: _Z20MakeWritableByteSpanIRNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEEDaOT_
_Z20MakeWritableByteSpanIR7uint256EDaOT_
Line
Count
Source
90
38.8k
{
91
38.8k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
38.8k
}
Unexecuted instantiation: _Z20MakeWritableByteSpanIRNSt3__16vectorISt4byteNS0_9allocatorIS2_EEEEEDaOT_
_Z20MakeWritableByteSpanIRNSt3__15arrayIhLm32EEEEDaOT_
Line
Count
Source
90
37.3M
{
91
37.3M
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
37.3M
}
_Z20MakeWritableByteSpanIRNSt3__16vectorIhNS0_9allocatorIhEEEEEDaOT_
Line
Count
Source
90
38.8k
{
91
38.8k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
38.8k
}
_Z20MakeWritableByteSpanIRA16_hEDaOT_
Line
Count
Source
90
115k
{
91
115k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
115k
}
_Z20MakeWritableByteSpanIRA4_hEDaOT_
Line
Count
Source
90
6.47M
{
91
6.47M
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
6.47M
}
Unexecuted instantiation: _Z20MakeWritableByteSpanIRA5_hEDaOT_
_Z20MakeWritableByteSpanIRNSt3__15arrayIhLm4EEEEDaOT_
Line
Count
Source
90
6.73M
{
91
6.73M
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
6.73M
}
_Z20MakeWritableByteSpanIRA12_cEDaOT_
Line
Count
Source
90
6.47M
{
91
6.47M
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
6.47M
}
Unexecuted instantiation: _Z20MakeWritableByteSpanIRNSt3__15arrayIhLm5EEEEDaOT_
Unexecuted instantiation: _Z20MakeWritableByteSpanIRNSt3__15arrayIhLm20EEEEDaOT_
Unexecuted instantiation: _Z20MakeWritableByteSpanIRNSt3__15arrayISt4byteLm20EEEEDaOT_
Unexecuted instantiation: _Z20MakeWritableByteSpanIRA368_cEDaOT_
Unexecuted instantiation: _Z20MakeWritableByteSpanIRA20_hEDaOT_
_Z20MakeWritableByteSpanIRNSt3__15arrayISt4byteLm8EEEEDaOT_
Line
Count
Source
90
38.8k
{
91
38.8k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
38.8k
}
Unexecuted instantiation: _Z20MakeWritableByteSpanIRA384_hEDaOT_
93
94
// Helper functions to safely cast basic byte pointers to unsigned char pointers.
95
0
inline unsigned char* UCharCast(char* c) { return reinterpret_cast<unsigned char*>(c); }
96
0
inline unsigned char* UCharCast(unsigned char* c) { return c; }
97
0
inline unsigned char* UCharCast(signed char* c) { return reinterpret_cast<unsigned char*>(c); }
98
0
inline unsigned char* UCharCast(std::byte* c) { return reinterpret_cast<unsigned char*>(c); }
99
0
inline const unsigned char* UCharCast(const char* c) { return reinterpret_cast<const unsigned char*>(c); }
100
7.32M
inline const unsigned char* UCharCast(const unsigned char* c) { return c; }
101
0
inline const unsigned char* UCharCast(const signed char* c) { return reinterpret_cast<const unsigned char*>(c); }
102
788M
inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_cast<const unsigned char*>(c); }
103
// Helper concept for the basic byte types.
104
template <typename B>
105
concept BasicByte = requires { UCharCast(std::span<B>{}.data()); };
106
107
// Helper function to safely convert a span to a span<[const] unsigned char>.
108
7.44M
template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; }
Unexecuted instantiation: _Z13UCharSpanCastIKcLm18446744073709551615EEDaNSt3__14spanIT_XT0_EEE
_Z13UCharSpanCastIKSt4byteLm18446744073709551615EEDaNSt3__14spanIT_XT0_EEE
Line
Count
Source
108
116k
template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; }
_Z13UCharSpanCastIKhLm18446744073709551615EEDaNSt3__14spanIT_XT0_EEE
Line
Count
Source
108
7.32M
template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; }
Unexecuted instantiation: _Z13UCharSpanCastIhLm18446744073709551615EEDaNSt3__14spanIT_XT0_EEE
Unexecuted instantiation: _Z13UCharSpanCastIKhLm8EEDaNSt3__14spanIT_XT0_EEE
109
110
/** Like the std::span constructor, but for (const) unsigned char member types only. Only works for (un)signed char containers. */
111
7.44M
template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); }
Unexecuted instantiation: _Z13MakeUCharSpanINSt3__14spanIKcLm18446744073709551615EEEEDTcl13UCharSpanCasttlS1_fp_EEERKT_
_Z13MakeUCharSpanINSt3__14spanIKSt4byteLm18446744073709551615EEEEDTcl13UCharSpanCasttlS1_fp_EEERKT_
Line
Count
Source
111
116k
template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); }
Unexecuted instantiation: _Z13MakeUCharSpanINSt3__117basic_string_viewIcNS0_11char_traitsIcEEEEEDTcl13UCharSpanCasttlNS0_4spanEfp_EEERKT_
Unexecuted instantiation: _Z13MakeUCharSpanINSt3__14spanIKhLm18446744073709551615EEEEDTcl13UCharSpanCasttlS1_fp_EEERKT_
Unexecuted instantiation: _Z13MakeUCharSpanINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEEDTcl13UCharSpanCasttlNS0_4spanEfp_EEERKT_
_Z13MakeUCharSpanINSt3__16vectorIhNS0_9allocatorIhEEEEEDTcl13UCharSpanCasttlNS0_4spanEfp_EEERKT_
Line
Count
Source
111
7.32M
template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); }
Unexecuted instantiation: _Z13MakeUCharSpanI7uint256EDTcl13UCharSpanCasttlNSt3__14spanEfp_EEERKT_
Unexecuted instantiation: _Z13MakeUCharSpanI11XOnlyPubKeyEDTcl13UCharSpanCasttlNSt3__14spanEfp_EEERKT_
Unexecuted instantiation: _Z13MakeUCharSpanI7CPubKeyEDTcl13UCharSpanCasttlNSt3__14spanEfp_EEERKT_
Unexecuted instantiation: _Z13MakeUCharSpanI7CScriptEDTcl13UCharSpanCasttlNSt3__14spanEfp_EEERKT_
Unexecuted instantiation: _Z13MakeUCharSpanINSt3__14spanIhLm18446744073709551615EEEEDTcl13UCharSpanCasttlS1_fp_EEERKT_
Unexecuted instantiation: _Z13MakeUCharSpanI10DataStreamEDTcl13UCharSpanCasttlNSt3__14spanEfp_EEERKT_
Unexecuted instantiation: _Z13MakeUCharSpanIA8_hEDTcl13UCharSpanCasttlNSt3__14spanEfp_EEERKT_
112
template <typename V> constexpr auto MakeWritableUCharSpan(V&& v) -> decltype(UCharSpanCast(std::span{std::forward<V>(v)})) { return UCharSpanCast(std::span{std::forward<V>(v)}); }
113
114
#endif // BITCOIN_SPAN_H