fuzz coverage

Coverage Report

Created: 2025-06-01 19:34

/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
0
{
77
0
    size_t size = span.size();
78
0
    T& back = span.back();
79
0
    span = span.first(size - 1);
80
0
    return back;
81
0
}
Unexecuted instantiation: _Z11SpanPopBackIKNSt3__16vectorIhNS0_9allocatorIhEEEEERT_RNS0_4spanIS6_Lm18446744073709551615EEE
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
746M
{
86
746M
    return std::as_bytes(std::span{v});
87
746M
}
_Z12MakeByteSpanINSt3__16vectorIhNS0_9allocatorIhEEEEEDaRKT_
Line
Count
Source
85
64.5M
{
86
64.5M
    return std::as_bytes(std::span{v});
87
64.5M
}
_Z12MakeByteSpanINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEEDaRKT_
Line
Count
Source
85
199k
{
86
199k
    return std::as_bytes(std::span{v});
87
199k
}
_Z12MakeByteSpanI9prevectorILj28EhjiEEDaRKT_
Line
Count
Source
85
536M
{
86
536M
    return std::as_bytes(std::span{v});
87
536M
}
_Z12MakeByteSpanIA4_hEDaRKT_
Line
Count
Source
85
1.14M
{
86
1.14M
    return std::as_bytes(std::span{v});
87
1.14M
}
Unexecuted instantiation: _Z12MakeByteSpanIA5_hEDaRKT_
Unexecuted instantiation: _Z12MakeByteSpanIA78_hEDaRKT_
Unexecuted instantiation: _Z12MakeByteSpanI9prevectorILj16EhjiEEDaRKT_
_Z12MakeByteSpanIA16_hEDaRKT_
Line
Count
Source
85
598k
{
86
598k
    return std::as_bytes(std::span{v});
87
598k
}
_Z12MakeByteSpanINSt3__15arrayIhLm4EEEEDaRKT_
Line
Count
Source
85
21.1M
{
86
21.1M
    return std::as_bytes(std::span{v});
87
21.1M
}
_Z12MakeByteSpanIA12_cEDaRKT_
Line
Count
Source
85
1.14M
{
86
1.14M
    return std::as_bytes(std::span{v});
87
1.14M
}
Unexecuted instantiation: _Z12MakeByteSpanINSt3__15arrayIhLm5EEEEDaRKT_
_Z12MakeByteSpanI7uint256EDaRKT_
Line
Count
Source
85
121M
{
86
121M
    return std::as_bytes(std::span{v});
87
121M
}
Unexecuted instantiation: _Z12MakeByteSpanINSt3__16vectorIh16secure_allocatorIhEEEEDaRKT_
Unexecuted instantiation: _Z12MakeByteSpanIN7leveldb5SliceEEDaRKT_
_Z12MakeByteSpanINSt3__15arrayISt4byteLm168EEEEDaRKT_
Line
Count
Source
85
15.3k
{
86
15.3k
    return std::as_bytes(std::span{v});
87
15.3k
}
_Z12MakeByteSpanINSt3__15arrayISt4byteLm8EEEEDaRKT_
Line
Count
Source
85
49.9k
{
86
49.9k
    return std::as_bytes(std::span{v});
87
49.9k
}
Unexecuted instantiation: _Z12MakeByteSpanINSt3__16vectorISt4byteNS0_9allocatorIS2_EEEEEDaRKT_
Unexecuted instantiation: _Z12MakeByteSpanIA384_hEDaRKT_
88
template <typename V>
89
auto MakeWritableByteSpan(V&& v) noexcept
90
4.47M
{
91
4.47M
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
4.47M
}
Unexecuted instantiation: _Z20MakeWritableByteSpanIRNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEEDaOT_
_Z20MakeWritableByteSpanIR10DataStreamEDaOT_
Line
Count
Source
90
261k
{
91
261k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
261k
}
_Z20MakeWritableByteSpanIR7uint256EDaOT_
Line
Count
Source
90
49.9k
{
91
49.9k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
49.9k
}
Unexecuted instantiation: _Z20MakeWritableByteSpanIRNSt3__16vectorISt4byteNS0_9allocatorIS2_EEEEEDaOT_
_Z20MakeWritableByteSpanIRNSt3__15arrayIhLm32EEEEDaOT_
Line
Count
Source
90
1.74M
{
91
1.74M
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
1.74M
}
_Z20MakeWritableByteSpanIRNSt3__16vectorIhNS0_9allocatorIhEEEEEDaOT_
Line
Count
Source
90
100k
{
91
100k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
100k
}
_Z20MakeWritableByteSpanIRA16_hEDaOT_
Line
Count
Source
90
141k
{
91
141k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
141k
}
_Z20MakeWritableByteSpanIRA4_hEDaOT_
Line
Count
Source
90
711k
{
91
711k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
711k
}
Unexecuted instantiation: _Z20MakeWritableByteSpanIRA5_hEDaOT_
_Z20MakeWritableByteSpanIRNSt3__15arrayIhLm4EEEEDaOT_
Line
Count
Source
90
762k
{
91
762k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
762k
}
_Z20MakeWritableByteSpanIRA12_cEDaOT_
Line
Count
Source
90
711k
{
91
711k
    return std::as_writable_bytes(std::span{std::forward<V>(v)});
92
711k
}
Unexecuted instantiation: _Z20MakeWritableByteSpanIRNSt3__15arrayIhLm5EEEEDaOT_
Unexecuted instantiation: _Z20MakeWritableByteSpanIRNSt3__15arrayIhLm20EEEEDaOT_
Unexecuted instantiation: _Z20MakeWritableByteSpanIRNSt3__15arrayISt4byteLm20EEEEDaOT_
Unexecuted instantiation: _Z20MakeWritableByteSpanIRA368_cEDaOT_
Unexecuted instantiation: _Z20MakeWritableByteSpanIRA20_hEDaOT_
Unexecuted instantiation: _Z20MakeWritableByteSpanIRNSt3__15arrayISt4byteLm8EEEEDaOT_
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
1.14M
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
1.47G
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
1.19M
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
49.9k
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
1.14M
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
1.19M
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
49.9k
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
1.14M
template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); }
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_
Unexecuted instantiation: _Z13MakeUCharSpanI7uint256EDTcl13UCharSpanCasttlNSt3__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