Coverage Report

Created: 2026-04-20 22:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/test/fuzz/bitset.cpp
Line
Count
Source
1
// Copyright (c) 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
#include <random.h>
6
#include <span.h>
7
#include <test/fuzz/util.h>
8
#include <util/bitset.h>
9
10
#include <bitset>
11
#include <vector>
12
13
namespace {
14
15
/** Pop the first byte from a byte-span, and return it. */
16
uint8_t ReadByte(FuzzBufferType& buffer)
17
1.84M
{
18
1.84M
    if (buffer.empty()) return 0;
19
1.84M
    uint8_t ret = buffer.front();
20
1.84M
    buffer = buffer.subspan(1);
21
1.84M
    return ret;
22
1.84M
}
23
24
/** Perform a simulation fuzz test on BitSet type S. */
25
template<typename S>
26
void TestType(FuzzBufferType buffer)
27
2.68k
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
2.68k
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
2.68k
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
2.68k
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
2.68k
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
404k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
404k
        auto it = real[idx].begin();
44
404k
        unsigned first = S::Size();
45
404k
        unsigned last = S::Size();
46
36.4M
        for (unsigned i = 0; i < S::Size(); ++i) {
47
36.0M
            bool match = (it != real[idx].end()) && *it == i;
48
36.0M
            assert(sim[idx][i] == real[idx][i]);
49
36.0M
            assert(match == real[idx][i]);
50
36.0M
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
36.0M
            if (match) {
52
7.02M
                ++it;
53
7.02M
                if (first == S::Size()) first = i;
54
7.02M
                last = i;
55
7.02M
            }
56
36.0M
        }
57
404k
        assert(it == real[idx].end());
58
404k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
404k
        assert(sim[idx].any() == real[idx].Any());
61
404k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
404k
        if (sim[idx].any()) {
64
327k
            assert(first == real[idx].First());
65
327k
            assert(last == real[idx].Last());
66
327k
        }
67
        /* Count */
68
404k
        assert(sim[idx].count() == real[idx].Count());
69
404k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail9IntBitSetItEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
30.9k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
30.9k
        auto it = real[idx].begin();
44
30.9k
        unsigned first = S::Size();
45
30.9k
        unsigned last = S::Size();
46
526k
        for (unsigned i = 0; i < S::Size(); ++i) {
47
495k
            bool match = (it != real[idx].end()) && *it == i;
48
495k
            assert(sim[idx][i] == real[idx][i]);
49
495k
            assert(match == real[idx][i]);
50
495k
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
495k
            if (match) {
52
130k
                ++it;
53
130k
                if (first == S::Size()) first = i;
54
130k
                last = i;
55
130k
            }
56
495k
        }
57
30.9k
        assert(it == real[idx].end());
58
30.9k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
30.9k
        assert(sim[idx].any() == real[idx].Any());
61
30.9k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
30.9k
        if (sim[idx].any()) {
64
25.1k
            assert(first == real[idx].First());
65
25.1k
            assert(last == real[idx].Last());
66
25.1k
        }
67
        /* Count */
68
30.9k
        assert(sim[idx].count() == real[idx].Count());
69
30.9k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetItLj1EEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
30.9k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
30.9k
        auto it = real[idx].begin();
44
30.9k
        unsigned first = S::Size();
45
30.9k
        unsigned last = S::Size();
46
526k
        for (unsigned i = 0; i < S::Size(); ++i) {
47
495k
            bool match = (it != real[idx].end()) && *it == i;
48
495k
            assert(sim[idx][i] == real[idx][i]);
49
495k
            assert(match == real[idx][i]);
50
495k
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
495k
            if (match) {
52
130k
                ++it;
53
130k
                if (first == S::Size()) first = i;
54
130k
                last = i;
55
130k
            }
56
495k
        }
57
30.9k
        assert(it == real[idx].end());
58
30.9k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
30.9k
        assert(sim[idx].any() == real[idx].Any());
61
30.9k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
30.9k
        if (sim[idx].any()) {
64
25.1k
            assert(first == real[idx].First());
65
25.1k
            assert(last == real[idx].Last());
66
25.1k
        }
67
        /* Count */
68
30.9k
        assert(sim[idx].count() == real[idx].Count());
69
30.9k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetItLj2EEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
26.6k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
26.6k
        auto it = real[idx].begin();
44
26.6k
        unsigned first = S::Size();
45
26.6k
        unsigned last = S::Size();
46
880k
        for (unsigned i = 0; i < S::Size(); ++i) {
47
853k
            bool match = (it != real[idx].end()) && *it == i;
48
853k
            assert(sim[idx][i] == real[idx][i]);
49
853k
            assert(match == real[idx][i]);
50
853k
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
853k
            if (match) {
52
212k
                ++it;
53
212k
                if (first == S::Size()) first = i;
54
212k
                last = i;
55
212k
            }
56
853k
        }
57
26.6k
        assert(it == real[idx].end());
58
26.6k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
26.6k
        assert(sim[idx].any() == real[idx].Any());
61
26.6k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
26.6k
        if (sim[idx].any()) {
64
21.9k
            assert(first == real[idx].First());
65
21.9k
            assert(last == real[idx].Last());
66
21.9k
        }
67
        /* Count */
68
26.6k
        assert(sim[idx].count() == real[idx].Count());
69
26.6k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail9IntBitSetIjEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
26.6k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
26.6k
        auto it = real[idx].begin();
44
26.6k
        unsigned first = S::Size();
45
26.6k
        unsigned last = S::Size();
46
880k
        for (unsigned i = 0; i < S::Size(); ++i) {
47
853k
            bool match = (it != real[idx].end()) && *it == i;
48
853k
            assert(sim[idx][i] == real[idx][i]);
49
853k
            assert(match == real[idx][i]);
50
853k
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
853k
            if (match) {
52
212k
                ++it;
53
212k
                if (first == S::Size()) first = i;
54
212k
                last = i;
55
212k
            }
56
853k
        }
57
26.6k
        assert(it == real[idx].end());
58
26.6k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
26.6k
        assert(sim[idx].any() == real[idx].Any());
61
26.6k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
26.6k
        if (sim[idx].any()) {
64
21.9k
            assert(first == real[idx].First());
65
21.9k
            assert(last == real[idx].Last());
66
21.9k
        }
67
        /* Count */
68
26.6k
        assert(sim[idx].count() == real[idx].Count());
69
26.6k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetItLj3EEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
23.4k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
23.4k
        auto it = real[idx].begin();
44
23.4k
        unsigned first = S::Size();
45
23.4k
        unsigned last = S::Size();
46
1.15M
        for (unsigned i = 0; i < S::Size(); ++i) {
47
1.12M
            bool match = (it != real[idx].end()) && *it == i;
48
1.12M
            assert(sim[idx][i] == real[idx][i]);
49
1.12M
            assert(match == real[idx][i]);
50
1.12M
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
1.12M
            if (match) {
52
182k
                ++it;
53
182k
                if (first == S::Size()) first = i;
54
182k
                last = i;
55
182k
            }
56
1.12M
        }
57
23.4k
        assert(it == real[idx].end());
58
23.4k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
23.4k
        assert(sim[idx].any() == real[idx].Any());
61
23.4k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
23.4k
        if (sim[idx].any()) {
64
18.5k
            assert(first == real[idx].First());
65
18.5k
            assert(last == real[idx].Last());
66
18.5k
        }
67
        /* Count */
68
23.4k
        assert(sim[idx].count() == real[idx].Count());
69
23.4k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail9IntBitSetImEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
27.5k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
27.5k
        auto it = real[idx].begin();
44
27.5k
        unsigned first = S::Size();
45
27.5k
        unsigned last = S::Size();
46
1.79M
        for (unsigned i = 0; i < S::Size(); ++i) {
47
1.76M
            bool match = (it != real[idx].end()) && *it == i;
48
1.76M
            assert(sim[idx][i] == real[idx][i]);
49
1.76M
            assert(match == real[idx][i]);
50
1.76M
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
1.76M
            if (match) {
52
420k
                ++it;
53
420k
                if (first == S::Size()) first = i;
54
420k
                last = i;
55
420k
            }
56
1.76M
        }
57
27.5k
        assert(it == real[idx].end());
58
27.5k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
27.5k
        assert(sim[idx].any() == real[idx].Any());
61
27.5k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
27.5k
        if (sim[idx].any()) {
64
22.2k
            assert(first == real[idx].First());
65
22.2k
            assert(last == real[idx].Last());
66
22.2k
        }
67
        /* Count */
68
27.5k
        assert(sim[idx].count() == real[idx].Count());
69
27.5k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetImLj1EEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
27.5k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
27.5k
        auto it = real[idx].begin();
44
27.5k
        unsigned first = S::Size();
45
27.5k
        unsigned last = S::Size();
46
1.79M
        for (unsigned i = 0; i < S::Size(); ++i) {
47
1.76M
            bool match = (it != real[idx].end()) && *it == i;
48
1.76M
            assert(sim[idx][i] == real[idx][i]);
49
1.76M
            assert(match == real[idx][i]);
50
1.76M
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
1.76M
            if (match) {
52
420k
                ++it;
53
420k
                if (first == S::Size()) first = i;
54
420k
                last = i;
55
420k
            }
56
1.76M
        }
57
27.5k
        assert(it == real[idx].end());
58
27.5k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
27.5k
        assert(sim[idx].any() == real[idx].Any());
61
27.5k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
27.5k
        if (sim[idx].any()) {
64
22.2k
            assert(first == real[idx].First());
65
22.2k
            assert(last == real[idx].Last());
66
22.2k
        }
67
        /* Count */
68
27.5k
        assert(sim[idx].count() == real[idx].Count());
69
27.5k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetIjLj2EEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
27.5k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
27.5k
        auto it = real[idx].begin();
44
27.5k
        unsigned first = S::Size();
45
27.5k
        unsigned last = S::Size();
46
1.79M
        for (unsigned i = 0; i < S::Size(); ++i) {
47
1.76M
            bool match = (it != real[idx].end()) && *it == i;
48
1.76M
            assert(sim[idx][i] == real[idx][i]);
49
1.76M
            assert(match == real[idx][i]);
50
1.76M
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
1.76M
            if (match) {
52
420k
                ++it;
53
420k
                if (first == S::Size()) first = i;
54
420k
                last = i;
55
420k
            }
56
1.76M
        }
57
27.5k
        assert(it == real[idx].end());
58
27.5k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
27.5k
        assert(sim[idx].any() == real[idx].Any());
61
27.5k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
27.5k
        if (sim[idx].any()) {
64
22.2k
            assert(first == real[idx].First());
65
22.2k
            assert(last == real[idx].Last());
66
22.2k
        }
67
        /* Count */
68
27.5k
        assert(sim[idx].count() == real[idx].Count());
69
27.5k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetItLj4EEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
27.5k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
27.5k
        auto it = real[idx].begin();
44
27.5k
        unsigned first = S::Size();
45
27.5k
        unsigned last = S::Size();
46
1.79M
        for (unsigned i = 0; i < S::Size(); ++i) {
47
1.76M
            bool match = (it != real[idx].end()) && *it == i;
48
1.76M
            assert(sim[idx][i] == real[idx][i]);
49
1.76M
            assert(match == real[idx][i]);
50
1.76M
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
1.76M
            if (match) {
52
420k
                ++it;
53
420k
                if (first == S::Size()) first = i;
54
420k
                last = i;
55
420k
            }
56
1.76M
        }
57
27.5k
        assert(it == real[idx].end());
58
27.5k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
27.5k
        assert(sim[idx].any() == real[idx].Any());
61
27.5k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
27.5k
        if (sim[idx].any()) {
64
22.2k
            assert(first == real[idx].First());
65
22.2k
            assert(last == real[idx].Last());
66
22.2k
        }
67
        /* Count */
68
27.5k
        assert(sim[idx].count() == real[idx].Count());
69
27.5k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetIjLj3EEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
26.4k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
26.4k
        auto it = real[idx].begin();
44
26.4k
        unsigned first = S::Size();
45
26.4k
        unsigned last = S::Size();
46
2.56M
        for (unsigned i = 0; i < S::Size(); ++i) {
47
2.54M
            bool match = (it != real[idx].end()) && *it == i;
48
2.54M
            assert(sim[idx][i] == real[idx][i]);
49
2.54M
            assert(match == real[idx][i]);
50
2.54M
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
2.54M
            if (match) {
52
373k
                ++it;
53
373k
                if (first == S::Size()) first = i;
54
373k
                last = i;
55
373k
            }
56
2.54M
        }
57
26.4k
        assert(it == real[idx].end());
58
26.4k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
26.4k
        assert(sim[idx].any() == real[idx].Any());
61
26.4k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
26.4k
        if (sim[idx].any()) {
64
20.2k
            assert(first == real[idx].First());
65
20.2k
            assert(last == real[idx].Last());
66
20.2k
        }
67
        /* Count */
68
26.4k
        assert(sim[idx].count() == real[idx].Count());
69
26.4k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetImLj2EEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
31.9k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
31.9k
        auto it = real[idx].begin();
44
31.9k
        unsigned first = S::Size();
45
31.9k
        unsigned last = S::Size();
46
4.12M
        for (unsigned i = 0; i < S::Size(); ++i) {
47
4.09M
            bool match = (it != real[idx].end()) && *it == i;
48
4.09M
            assert(sim[idx][i] == real[idx][i]);
49
4.09M
            assert(match == real[idx][i]);
50
4.09M
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
4.09M
            if (match) {
52
781k
                ++it;
53
781k
                if (first == S::Size()) first = i;
54
781k
                last = i;
55
781k
            }
56
4.09M
        }
57
31.9k
        assert(it == real[idx].end());
58
31.9k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
31.9k
        assert(sim[idx].any() == real[idx].Any());
61
31.9k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
31.9k
        if (sim[idx].any()) {
64
26.0k
            assert(first == real[idx].First());
65
26.0k
            assert(last == real[idx].Last());
66
26.0k
        }
67
        /* Count */
68
31.9k
        assert(sim[idx].count() == real[idx].Count());
69
31.9k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetIjLj4EEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
31.9k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
31.9k
        auto it = real[idx].begin();
44
31.9k
        unsigned first = S::Size();
45
31.9k
        unsigned last = S::Size();
46
4.12M
        for (unsigned i = 0; i < S::Size(); ++i) {
47
4.09M
            bool match = (it != real[idx].end()) && *it == i;
48
4.09M
            assert(sim[idx][i] == real[idx][i]);
49
4.09M
            assert(match == real[idx][i]);
50
4.09M
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
4.09M
            if (match) {
52
781k
                ++it;
53
781k
                if (first == S::Size()) first = i;
54
781k
                last = i;
55
781k
            }
56
4.09M
        }
57
31.9k
        assert(it == real[idx].end());
58
31.9k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
31.9k
        assert(sim[idx].any() == real[idx].Any());
61
31.9k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
31.9k
        if (sim[idx].any()) {
64
26.0k
            assert(first == real[idx].First());
65
26.0k
            assert(last == real[idx].Last());
66
26.0k
        }
67
        /* Count */
68
31.9k
        assert(sim[idx].count() == real[idx].Count());
69
31.9k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetImLj3EEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
33.8k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
33.8k
        auto it = real[idx].begin();
44
33.8k
        unsigned first = S::Size();
45
33.8k
        unsigned last = S::Size();
46
6.52M
        for (unsigned i = 0; i < S::Size(); ++i) {
47
6.49M
            bool match = (it != real[idx].end()) && *it == i;
48
6.49M
            assert(sim[idx][i] == real[idx][i]);
49
6.49M
            assert(match == real[idx][i]);
50
6.49M
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
6.49M
            if (match) {
52
1.23M
                ++it;
53
1.23M
                if (first == S::Size()) first = i;
54
1.23M
                last = i;
55
1.23M
            }
56
6.49M
        }
57
33.8k
        assert(it == real[idx].end());
58
33.8k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
33.8k
        assert(sim[idx].any() == real[idx].Any());
61
33.8k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
33.8k
        if (sim[idx].any()) {
64
27.8k
            assert(first == real[idx].First());
65
27.8k
            assert(last == real[idx].Last());
66
27.8k
        }
67
        /* Count */
68
33.8k
        assert(sim[idx].count() == real[idx].Count());
69
33.8k
    };
bitset.cpp:_ZZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetImLj4EEEEEvSt4spanIKhLm18446744073709551615EEENKUljE_clEj
Line
Count
Source
41
31.1k
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
31.1k
        auto it = real[idx].begin();
44
31.1k
        unsigned first = S::Size();
45
31.1k
        unsigned last = S::Size();
46
7.99M
        for (unsigned i = 0; i < S::Size(); ++i) {
47
7.96M
            bool match = (it != real[idx].end()) && *it == i;
48
7.96M
            assert(sim[idx][i] == real[idx][i]);
49
7.96M
            assert(match == real[idx][i]);
50
7.96M
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
7.96M
            if (match) {
52
1.30M
                ++it;
53
1.30M
                if (first == S::Size()) first = i;
54
1.30M
                last = i;
55
1.30M
            }
56
7.96M
        }
57
31.1k
        assert(it == real[idx].end());
58
31.1k
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
31.1k
        assert(sim[idx].any() == real[idx].Any());
61
31.1k
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
31.1k
        if (sim[idx].any()) {
64
24.9k
            assert(first == real[idx].First());
65
24.9k
            assert(last == real[idx].Last());
66
24.9k
        }
67
        /* Count */
68
31.1k
        assert(sim[idx].count() == real[idx].Count());
69
31.1k
    };
70
71
793k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
793k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
793k
        unsigned args = ReadByte(buffer);
76
793k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
793k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
793k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
793k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
793k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
1.93M
        while (true) {
87
1.93M
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
76.0k
                unsigned val = ReadByte(buffer) % S::Size();
90
76.0k
                assert(sim[dest][val] == real[dest][val]);
91
76.0k
                sim[dest].set(val);
92
76.0k
                real[dest].Set(val);
93
76.0k
                break;
94
1.85M
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
24.3k
                unsigned val = ReadByte(buffer) % S::Size();
97
24.3k
                assert(sim[dest][val] == real[dest][val]);
98
24.3k
                sim[dest].reset(val);
99
24.3k
                real[dest].Reset(val);
100
24.3k
                break;
101
1.83M
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
22.7k
                unsigned val = ReadByte(buffer) % S::Size();
104
22.7k
                assert(sim[dest][val] == real[dest][val]);
105
22.7k
                sim[dest].set(val, args >> 7);
106
22.7k
                real[dest].Set(val, args >> 7);
107
22.7k
                break;
108
1.80M
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
10.5k
                sim.resize(sim.size() + 1);
111
10.5k
                real.resize(real.size() + 1);
112
10.5k
                break;
113
1.79M
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
10.7k
                unsigned val = ReadByte(buffer) % S::Size();
116
10.7k
                std::bitset<S::Size()> newset;
117
10.7k
                newset[val] = true;
118
10.7k
                sim.push_back(newset);
119
10.7k
                real.push_back(S::Singleton(val));
120
10.7k
                break;
121
1.78M
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
50.5k
                compare_fn(dest);
124
50.5k
                sim[dest].reset();
125
50.5k
                real[dest] = S{};
126
4.49M
                for (unsigned i = 0; i < S::Size(); ++i) {
127
4.44M
                    if (rng.randbool()) {
128
2.22M
                        sim[dest][i] = true;
129
2.22M
                        real[dest].Set(i);
130
2.22M
                    }
131
4.44M
                }
132
50.5k
                break;
133
1.73M
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
66.5k
                unsigned r1 = rng.randrange(S::Size());
136
66.5k
                unsigned r2 = rng.randrange(S::Size());
137
66.5k
                unsigned r3 = rng.randrange(S::Size());
138
66.5k
                compare_fn(dest);
139
66.5k
                sim[dest].reset();
140
66.5k
                real[dest] = {r1, r2, r3};
141
66.5k
                sim[dest].set(r1);
142
66.5k
                sim[dest].set(r2);
143
66.5k
                sim[dest].set(r3);
144
66.5k
                break;
145
1.67M
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
59.5k
                compare_fn(sim.size() - 1);
148
59.5k
                sim.pop_back();
149
59.5k
                real.pop_back();
150
59.5k
                break;
151
1.61M
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
10.5k
                sim.emplace_back(sim[src]);
154
10.5k
                real.emplace_back(real[src]);
155
10.5k
                break;
156
1.60M
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
21.8k
                compare_fn(dest);
159
21.8k
                sim[dest] = sim[src];
160
21.8k
                real[dest] = real[src];
161
21.8k
                break;
162
1.57M
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
15.3k
                swap(sim[dest], sim[src]);
165
15.3k
                swap(real[dest], real[src]);
166
15.3k
                break;
167
1.56M
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
29.6k
                unsigned r1 = rng.randrange(S::Size());
170
29.6k
                unsigned r2 = rng.randrange(S::Size());
171
29.6k
                sim.emplace_back();
172
29.6k
                sim.back().set(r1);
173
29.6k
                sim.back().set(r2);
174
29.6k
                real.push_back(S{r1, r2});
175
29.6k
                break;
176
1.53M
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
52.7k
                unsigned len = ReadByte(buffer) % S::Size();
179
52.7k
                compare_fn(dest);
180
52.7k
                sim[dest].reset();
181
1.63M
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
52.7k
                real[dest] = S::Fill(len);
183
52.7k
                break;
184
1.48M
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
71.3k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
71.3k
                auto it = real[src].begin(), it_copy = it;
189
6.37M
                for (unsigned i = 0; i < S::Size(); ++i) {
190
6.30M
                    if (i == val) it_copy = it;
191
6.30M
                    bool match = (it != real[src].end()) && *it == i;
192
6.30M
                    assert(match == sim[src][i]);
193
6.30M
                    if (match) ++it;
194
6.30M
                }
195
71.3k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
2.73M
                for (unsigned i = val; i < S::Size(); ++i) {
198
2.66M
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
2.66M
                    assert(match == sim[src][i]);
200
2.66M
                    if (match) ++it_copy;
201
2.66M
                }
202
71.3k
                assert(it_copy == real[src].end());
203
71.3k
                break;
204
1.40M
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
22.4k
                compare_fn(dest);
207
22.4k
                sim[dest] |= sim[src];
208
22.4k
                real[dest] |= real[src];
209
22.4k
                break;
210
1.38M
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
21.1k
                compare_fn(dest);
213
21.1k
                sim[dest] &= sim[src];
214
21.1k
                real[dest] &= real[src];
215
21.1k
                break;
216
1.36M
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
19.9k
                compare_fn(dest);
219
19.9k
                sim[dest] &= ~sim[src];
220
19.9k
                real[dest] -= real[src];
221
19.9k
                break;
222
1.34M
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
14.6k
                compare_fn(dest);
225
14.6k
                sim[dest] ^= sim[src];
226
14.6k
                real[dest] ^= real[src];
227
14.6k
                break;
228
1.33M
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
15.6k
                compare_fn(dest);
231
15.6k
                sim[dest] = sim[src] | sim[aux];
232
15.6k
                real[dest] = real[src] | real[aux];
233
15.6k
                break;
234
1.31M
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
18.9k
                compare_fn(dest);
237
18.9k
                sim[dest] = sim[src] & sim[aux];
238
18.9k
                real[dest] = real[src] & real[aux];
239
18.9k
                break;
240
1.29M
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
17.7k
                compare_fn(dest);
243
17.7k
                sim[dest] = sim[src] & ~sim[aux];
244
17.7k
                real[dest] = real[src] - real[aux];
245
17.7k
                break;
246
1.27M
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
15.2k
                compare_fn(dest);
249
15.2k
                sim[dest] = sim[src] ^ sim[aux];
250
15.2k
                real[dest] = real[src] ^ real[aux];
251
15.2k
                break;
252
1.26M
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
61.1k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
61.1k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
61.1k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
61.1k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
61.1k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
61.1k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
61.1k
                break;
261
1.20M
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
23.0k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
23.0k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
23.0k
                break;
266
1.17M
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
41.2k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
41.2k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
41.2k
                break;
271
41.2k
            }
272
1.93M
        }
273
793k
    }
274
    /* Fully compare the final state. */
275
10.1k
    for (unsigned i = 0; i < sim.size(); ++i) {
276
7.47k
        compare_fn(i);
277
7.47k
    }
278
2.68k
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail9IntBitSetItEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
159
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
159
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
159
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
159
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
159
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
159
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
159
        auto it = real[idx].begin();
44
159
        unsigned first = S::Size();
45
159
        unsigned last = S::Size();
46
159
        for (unsigned i = 0; i < S::Size(); ++i) {
47
159
            bool match = (it != real[idx].end()) && *it == i;
48
159
            assert(sim[idx][i] == real[idx][i]);
49
159
            assert(match == real[idx][i]);
50
159
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
159
            if (match) {
52
159
                ++it;
53
159
                if (first == S::Size()) first = i;
54
159
                last = i;
55
159
            }
56
159
        }
57
159
        assert(it == real[idx].end());
58
159
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
159
        assert(sim[idx].any() == real[idx].Any());
61
159
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
159
        if (sim[idx].any()) {
64
159
            assert(first == real[idx].First());
65
159
            assert(last == real[idx].Last());
66
159
        }
67
        /* Count */
68
159
        assert(sim[idx].count() == real[idx].Count());
69
159
    };
70
71
52.2k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
52.2k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
52.2k
        unsigned args = ReadByte(buffer);
76
52.2k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
52.2k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
52.2k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
52.2k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
52.2k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
134k
        while (true) {
87
134k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
5.02k
                unsigned val = ReadByte(buffer) % S::Size();
90
5.02k
                assert(sim[dest][val] == real[dest][val]);
91
5.02k
                sim[dest].set(val);
92
5.02k
                real[dest].Set(val);
93
5.02k
                break;
94
129k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
1.69k
                unsigned val = ReadByte(buffer) % S::Size();
97
1.69k
                assert(sim[dest][val] == real[dest][val]);
98
1.69k
                sim[dest].reset(val);
99
1.69k
                real[dest].Reset(val);
100
1.69k
                break;
101
127k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
1.40k
                unsigned val = ReadByte(buffer) % S::Size();
104
1.40k
                assert(sim[dest][val] == real[dest][val]);
105
1.40k
                sim[dest].set(val, args >> 7);
106
1.40k
                real[dest].Set(val, args >> 7);
107
1.40k
                break;
108
126k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
752
                sim.resize(sim.size() + 1);
111
752
                real.resize(real.size() + 1);
112
752
                break;
113
125k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
578
                unsigned val = ReadByte(buffer) % S::Size();
116
578
                std::bitset<S::Size()> newset;
117
578
                newset[val] = true;
118
578
                sim.push_back(newset);
119
578
                real.push_back(S::Singleton(val));
120
578
                break;
121
125k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
4.66k
                compare_fn(dest);
124
4.66k
                sim[dest].reset();
125
4.66k
                real[dest] = S{};
126
79.2k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
74.6k
                    if (rng.randbool()) {
128
37.3k
                        sim[dest][i] = true;
129
37.3k
                        real[dest].Set(i);
130
37.3k
                    }
131
74.6k
                }
132
4.66k
                break;
133
120k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
5.94k
                unsigned r1 = rng.randrange(S::Size());
136
5.94k
                unsigned r2 = rng.randrange(S::Size());
137
5.94k
                unsigned r3 = rng.randrange(S::Size());
138
5.94k
                compare_fn(dest);
139
5.94k
                sim[dest].reset();
140
5.94k
                real[dest] = {r1, r2, r3};
141
5.94k
                sim[dest].set(r1);
142
5.94k
                sim[dest].set(r2);
143
5.94k
                sim[dest].set(r3);
144
5.94k
                break;
145
114k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
4.13k
                compare_fn(sim.size() - 1);
148
4.13k
                sim.pop_back();
149
4.13k
                real.pop_back();
150
4.13k
                break;
151
110k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
702
                sim.emplace_back(sim[src]);
154
702
                real.emplace_back(real[src]);
155
702
                break;
156
109k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.36k
                compare_fn(dest);
159
1.36k
                sim[dest] = sim[src];
160
1.36k
                real[dest] = real[src];
161
1.36k
                break;
162
108k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
1.04k
                swap(sim[dest], sim[src]);
165
1.04k
                swap(real[dest], real[src]);
166
1.04k
                break;
167
107k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
2.17k
                unsigned r1 = rng.randrange(S::Size());
170
2.17k
                unsigned r2 = rng.randrange(S::Size());
171
2.17k
                sim.emplace_back();
172
2.17k
                sim.back().set(r1);
173
2.17k
                sim.back().set(r2);
174
2.17k
                real.push_back(S{r1, r2});
175
2.17k
                break;
176
105k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
4.50k
                unsigned len = ReadByte(buffer) % S::Size();
179
4.50k
                compare_fn(dest);
180
4.50k
                sim[dest].reset();
181
37.0k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
4.50k
                real[dest] = S::Fill(len);
183
4.50k
                break;
184
100k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
4.50k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
4.50k
                auto it = real[src].begin(), it_copy = it;
189
76.5k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
72.0k
                    if (i == val) it_copy = it;
191
72.0k
                    bool match = (it != real[src].end()) && *it == i;
192
72.0k
                    assert(match == sim[src][i]);
193
72.0k
                    if (match) ++it;
194
72.0k
                }
195
4.50k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
27.7k
                for (unsigned i = val; i < S::Size(); ++i) {
198
23.2k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
23.2k
                    assert(match == sim[src][i]);
200
23.2k
                    if (match) ++it_copy;
201
23.2k
                }
202
4.50k
                assert(it_copy == real[src].end());
203
4.50k
                break;
204
96.2k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
1.50k
                compare_fn(dest);
207
1.50k
                sim[dest] |= sim[src];
208
1.50k
                real[dest] |= real[src];
209
1.50k
                break;
210
94.7k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
2.08k
                compare_fn(dest);
213
2.08k
                sim[dest] &= sim[src];
214
2.08k
                real[dest] &= real[src];
215
2.08k
                break;
216
92.6k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.31k
                compare_fn(dest);
219
1.31k
                sim[dest] &= ~sim[src];
220
1.31k
                real[dest] -= real[src];
221
1.31k
                break;
222
91.3k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
1.08k
                compare_fn(dest);
225
1.08k
                sim[dest] ^= sim[src];
226
1.08k
                real[dest] ^= real[src];
227
1.08k
                break;
228
90.2k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
1.25k
                compare_fn(dest);
231
1.25k
                sim[dest] = sim[src] | sim[aux];
232
1.25k
                real[dest] = real[src] | real[aux];
233
1.25k
                break;
234
88.9k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
928
                compare_fn(dest);
237
928
                sim[dest] = sim[src] & sim[aux];
238
928
                real[dest] = real[src] & real[aux];
239
928
                break;
240
88.0k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
799
                compare_fn(dest);
243
799
                sim[dest] = sim[src] & ~sim[aux];
244
799
                real[dest] = real[src] - real[aux];
245
799
                break;
246
87.2k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.01k
                compare_fn(dest);
249
1.01k
                sim[dest] = sim[src] ^ sim[aux];
250
1.01k
                real[dest] = real[src] ^ real[aux];
251
1.01k
                break;
252
86.2k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
1.59k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
1.59k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
1.59k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
1.59k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
1.59k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
1.59k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
1.59k
                break;
261
84.6k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
1.08k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
1.08k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
1.08k
                break;
266
83.5k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
1.11k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
1.11k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
1.11k
                break;
271
1.11k
            }
272
134k
        }
273
52.2k
    }
274
    /* Fully compare the final state. */
275
549
    for (unsigned i = 0; i < sim.size(); ++i) {
276
390
        compare_fn(i);
277
390
    }
278
159
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetItLj1EEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
159
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
159
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
159
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
159
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
159
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
159
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
159
        auto it = real[idx].begin();
44
159
        unsigned first = S::Size();
45
159
        unsigned last = S::Size();
46
159
        for (unsigned i = 0; i < S::Size(); ++i) {
47
159
            bool match = (it != real[idx].end()) && *it == i;
48
159
            assert(sim[idx][i] == real[idx][i]);
49
159
            assert(match == real[idx][i]);
50
159
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
159
            if (match) {
52
159
                ++it;
53
159
                if (first == S::Size()) first = i;
54
159
                last = i;
55
159
            }
56
159
        }
57
159
        assert(it == real[idx].end());
58
159
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
159
        assert(sim[idx].any() == real[idx].Any());
61
159
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
159
        if (sim[idx].any()) {
64
159
            assert(first == real[idx].First());
65
159
            assert(last == real[idx].Last());
66
159
        }
67
        /* Count */
68
159
        assert(sim[idx].count() == real[idx].Count());
69
159
    };
70
71
52.2k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
52.2k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
52.2k
        unsigned args = ReadByte(buffer);
76
52.2k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
52.2k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
52.2k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
52.2k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
52.2k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
134k
        while (true) {
87
134k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
5.02k
                unsigned val = ReadByte(buffer) % S::Size();
90
5.02k
                assert(sim[dest][val] == real[dest][val]);
91
5.02k
                sim[dest].set(val);
92
5.02k
                real[dest].Set(val);
93
5.02k
                break;
94
129k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
1.69k
                unsigned val = ReadByte(buffer) % S::Size();
97
1.69k
                assert(sim[dest][val] == real[dest][val]);
98
1.69k
                sim[dest].reset(val);
99
1.69k
                real[dest].Reset(val);
100
1.69k
                break;
101
127k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
1.40k
                unsigned val = ReadByte(buffer) % S::Size();
104
1.40k
                assert(sim[dest][val] == real[dest][val]);
105
1.40k
                sim[dest].set(val, args >> 7);
106
1.40k
                real[dest].Set(val, args >> 7);
107
1.40k
                break;
108
126k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
752
                sim.resize(sim.size() + 1);
111
752
                real.resize(real.size() + 1);
112
752
                break;
113
125k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
578
                unsigned val = ReadByte(buffer) % S::Size();
116
578
                std::bitset<S::Size()> newset;
117
578
                newset[val] = true;
118
578
                sim.push_back(newset);
119
578
                real.push_back(S::Singleton(val));
120
578
                break;
121
125k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
4.66k
                compare_fn(dest);
124
4.66k
                sim[dest].reset();
125
4.66k
                real[dest] = S{};
126
79.2k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
74.6k
                    if (rng.randbool()) {
128
37.3k
                        sim[dest][i] = true;
129
37.3k
                        real[dest].Set(i);
130
37.3k
                    }
131
74.6k
                }
132
4.66k
                break;
133
120k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
5.94k
                unsigned r1 = rng.randrange(S::Size());
136
5.94k
                unsigned r2 = rng.randrange(S::Size());
137
5.94k
                unsigned r3 = rng.randrange(S::Size());
138
5.94k
                compare_fn(dest);
139
5.94k
                sim[dest].reset();
140
5.94k
                real[dest] = {r1, r2, r3};
141
5.94k
                sim[dest].set(r1);
142
5.94k
                sim[dest].set(r2);
143
5.94k
                sim[dest].set(r3);
144
5.94k
                break;
145
114k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
4.13k
                compare_fn(sim.size() - 1);
148
4.13k
                sim.pop_back();
149
4.13k
                real.pop_back();
150
4.13k
                break;
151
110k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
702
                sim.emplace_back(sim[src]);
154
702
                real.emplace_back(real[src]);
155
702
                break;
156
109k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.36k
                compare_fn(dest);
159
1.36k
                sim[dest] = sim[src];
160
1.36k
                real[dest] = real[src];
161
1.36k
                break;
162
108k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
1.04k
                swap(sim[dest], sim[src]);
165
1.04k
                swap(real[dest], real[src]);
166
1.04k
                break;
167
107k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
2.17k
                unsigned r1 = rng.randrange(S::Size());
170
2.17k
                unsigned r2 = rng.randrange(S::Size());
171
2.17k
                sim.emplace_back();
172
2.17k
                sim.back().set(r1);
173
2.17k
                sim.back().set(r2);
174
2.17k
                real.push_back(S{r1, r2});
175
2.17k
                break;
176
105k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
4.50k
                unsigned len = ReadByte(buffer) % S::Size();
179
4.50k
                compare_fn(dest);
180
4.50k
                sim[dest].reset();
181
37.0k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
4.50k
                real[dest] = S::Fill(len);
183
4.50k
                break;
184
100k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
4.50k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
4.50k
                auto it = real[src].begin(), it_copy = it;
189
76.5k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
72.0k
                    if (i == val) it_copy = it;
191
72.0k
                    bool match = (it != real[src].end()) && *it == i;
192
72.0k
                    assert(match == sim[src][i]);
193
72.0k
                    if (match) ++it;
194
72.0k
                }
195
4.50k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
27.7k
                for (unsigned i = val; i < S::Size(); ++i) {
198
23.2k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
23.2k
                    assert(match == sim[src][i]);
200
23.2k
                    if (match) ++it_copy;
201
23.2k
                }
202
4.50k
                assert(it_copy == real[src].end());
203
4.50k
                break;
204
96.2k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
1.50k
                compare_fn(dest);
207
1.50k
                sim[dest] |= sim[src];
208
1.50k
                real[dest] |= real[src];
209
1.50k
                break;
210
94.7k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
2.08k
                compare_fn(dest);
213
2.08k
                sim[dest] &= sim[src];
214
2.08k
                real[dest] &= real[src];
215
2.08k
                break;
216
92.6k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.31k
                compare_fn(dest);
219
1.31k
                sim[dest] &= ~sim[src];
220
1.31k
                real[dest] -= real[src];
221
1.31k
                break;
222
91.3k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
1.08k
                compare_fn(dest);
225
1.08k
                sim[dest] ^= sim[src];
226
1.08k
                real[dest] ^= real[src];
227
1.08k
                break;
228
90.2k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
1.25k
                compare_fn(dest);
231
1.25k
                sim[dest] = sim[src] | sim[aux];
232
1.25k
                real[dest] = real[src] | real[aux];
233
1.25k
                break;
234
88.9k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
928
                compare_fn(dest);
237
928
                sim[dest] = sim[src] & sim[aux];
238
928
                real[dest] = real[src] & real[aux];
239
928
                break;
240
88.0k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
799
                compare_fn(dest);
243
799
                sim[dest] = sim[src] & ~sim[aux];
244
799
                real[dest] = real[src] - real[aux];
245
799
                break;
246
87.2k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.01k
                compare_fn(dest);
249
1.01k
                sim[dest] = sim[src] ^ sim[aux];
250
1.01k
                real[dest] = real[src] ^ real[aux];
251
1.01k
                break;
252
86.2k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
1.59k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
1.59k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
1.59k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
1.59k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
1.59k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
1.59k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
1.59k
                break;
261
84.6k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
1.08k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
1.08k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
1.08k
                break;
266
83.5k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
1.11k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
1.11k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
1.11k
                break;
271
1.11k
            }
272
134k
        }
273
52.2k
    }
274
    /* Fully compare the final state. */
275
549
    for (unsigned i = 0; i < sim.size(); ++i) {
276
390
        compare_fn(i);
277
390
    }
278
159
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetItLj2EEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
186
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
186
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
186
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
186
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
186
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
186
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
186
        auto it = real[idx].begin();
44
186
        unsigned first = S::Size();
45
186
        unsigned last = S::Size();
46
186
        for (unsigned i = 0; i < S::Size(); ++i) {
47
186
            bool match = (it != real[idx].end()) && *it == i;
48
186
            assert(sim[idx][i] == real[idx][i]);
49
186
            assert(match == real[idx][i]);
50
186
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
186
            if (match) {
52
186
                ++it;
53
186
                if (first == S::Size()) first = i;
54
186
                last = i;
55
186
            }
56
186
        }
57
186
        assert(it == real[idx].end());
58
186
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
186
        assert(sim[idx].any() == real[idx].Any());
61
186
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
186
        if (sim[idx].any()) {
64
186
            assert(first == real[idx].First());
65
186
            assert(last == real[idx].Last());
66
186
        }
67
        /* Count */
68
186
        assert(sim[idx].count() == real[idx].Count());
69
186
    };
70
71
49.7k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
49.7k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
49.7k
        unsigned args = ReadByte(buffer);
76
49.7k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
49.7k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
49.7k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
49.7k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
49.7k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
120k
        while (true) {
87
120k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
4.79k
                unsigned val = ReadByte(buffer) % S::Size();
90
4.79k
                assert(sim[dest][val] == real[dest][val]);
91
4.79k
                sim[dest].set(val);
92
4.79k
                real[dest].Set(val);
93
4.79k
                break;
94
116k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
1.14k
                unsigned val = ReadByte(buffer) % S::Size();
97
1.14k
                assert(sim[dest][val] == real[dest][val]);
98
1.14k
                sim[dest].reset(val);
99
1.14k
                real[dest].Reset(val);
100
1.14k
                break;
101
114k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
1.24k
                unsigned val = ReadByte(buffer) % S::Size();
104
1.24k
                assert(sim[dest][val] == real[dest][val]);
105
1.24k
                sim[dest].set(val, args >> 7);
106
1.24k
                real[dest].Set(val, args >> 7);
107
1.24k
                break;
108
113k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
747
                sim.resize(sim.size() + 1);
111
747
                real.resize(real.size() + 1);
112
747
                break;
113
112k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
683
                unsigned val = ReadByte(buffer) % S::Size();
116
683
                std::bitset<S::Size()> newset;
117
683
                newset[val] = true;
118
683
                sim.push_back(newset);
119
683
                real.push_back(S::Singleton(val));
120
683
                break;
121
112k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
3.73k
                compare_fn(dest);
124
3.73k
                sim[dest].reset();
125
3.73k
                real[dest] = S{};
126
123k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
119k
                    if (rng.randbool()) {
128
59.8k
                        sim[dest][i] = true;
129
59.8k
                        real[dest].Set(i);
130
59.8k
                    }
131
119k
                }
132
3.73k
                break;
133
108k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
3.68k
                unsigned r1 = rng.randrange(S::Size());
136
3.68k
                unsigned r2 = rng.randrange(S::Size());
137
3.68k
                unsigned r3 = rng.randrange(S::Size());
138
3.68k
                compare_fn(dest);
139
3.68k
                sim[dest].reset();
140
3.68k
                real[dest] = {r1, r2, r3};
141
3.68k
                sim[dest].set(r1);
142
3.68k
                sim[dest].set(r2);
143
3.68k
                sim[dest].set(r3);
144
3.68k
                break;
145
104k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
4.28k
                compare_fn(sim.size() - 1);
148
4.28k
                sim.pop_back();
149
4.28k
                real.pop_back();
150
4.28k
                break;
151
100k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
656
                sim.emplace_back(sim[src]);
154
656
                real.emplace_back(real[src]);
155
656
                break;
156
99.8k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.47k
                compare_fn(dest);
159
1.47k
                sim[dest] = sim[src];
160
1.47k
                real[dest] = real[src];
161
1.47k
                break;
162
98.3k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
858
                swap(sim[dest], sim[src]);
165
858
                swap(real[dest], real[src]);
166
858
                break;
167
97.4k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
2.35k
                unsigned r1 = rng.randrange(S::Size());
170
2.35k
                unsigned r2 = rng.randrange(S::Size());
171
2.35k
                sim.emplace_back();
172
2.35k
                sim.back().set(r1);
173
2.35k
                sim.back().set(r2);
174
2.35k
                real.push_back(S{r1, r2});
175
2.35k
                break;
176
95.1k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
4.25k
                unsigned len = ReadByte(buffer) % S::Size();
179
4.25k
                compare_fn(dest);
180
4.25k
                sim[dest].reset();
181
64.6k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
4.25k
                real[dest] = S::Fill(len);
183
4.25k
                break;
184
90.8k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
4.81k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
4.81k
                auto it = real[src].begin(), it_copy = it;
189
158k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
153k
                    if (i == val) it_copy = it;
191
153k
                    bool match = (it != real[src].end()) && *it == i;
192
153k
                    assert(match == sim[src][i]);
193
153k
                    if (match) ++it;
194
153k
                }
195
4.81k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
53.0k
                for (unsigned i = val; i < S::Size(); ++i) {
198
48.2k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
48.2k
                    assert(match == sim[src][i]);
200
48.2k
                    if (match) ++it_copy;
201
48.2k
                }
202
4.81k
                assert(it_copy == real[src].end());
203
4.81k
                break;
204
86.0k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
1.59k
                compare_fn(dest);
207
1.59k
                sim[dest] |= sim[src];
208
1.59k
                real[dest] |= real[src];
209
1.59k
                break;
210
84.4k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
1.14k
                compare_fn(dest);
213
1.14k
                sim[dest] &= sim[src];
214
1.14k
                real[dest] &= real[src];
215
1.14k
                break;
216
83.3k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.11k
                compare_fn(dest);
219
1.11k
                sim[dest] &= ~sim[src];
220
1.11k
                real[dest] -= real[src];
221
1.11k
                break;
222
82.2k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
855
                compare_fn(dest);
225
855
                sim[dest] ^= sim[src];
226
855
                real[dest] ^= real[src];
227
855
                break;
228
81.3k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
926
                compare_fn(dest);
231
926
                sim[dest] = sim[src] | sim[aux];
232
926
                real[dest] = real[src] | real[aux];
233
926
                break;
234
80.4k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
904
                compare_fn(dest);
237
904
                sim[dest] = sim[src] & sim[aux];
238
904
                real[dest] = real[src] & real[aux];
239
904
                break;
240
79.5k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
1.12k
                compare_fn(dest);
243
1.12k
                sim[dest] = sim[src] & ~sim[aux];
244
1.12k
                real[dest] = real[src] - real[aux];
245
1.12k
                break;
246
78.4k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.05k
                compare_fn(dest);
249
1.05k
                sim[dest] = sim[src] ^ sim[aux];
250
1.05k
                real[dest] = real[src] ^ real[aux];
251
1.05k
                break;
252
77.3k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
3.18k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
3.18k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
3.18k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
3.18k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
3.18k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
3.18k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
3.18k
                break;
261
74.1k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
1.14k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
1.14k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
1.14k
                break;
266
73.0k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
1.94k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
1.94k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
1.94k
                break;
271
1.94k
            }
272
120k
        }
273
49.7k
    }
274
    /* Fully compare the final state. */
275
713
    for (unsigned i = 0; i < sim.size(); ++i) {
276
527
        compare_fn(i);
277
527
    }
278
186
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail9IntBitSetIjEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
186
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
186
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
186
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
186
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
186
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
186
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
186
        auto it = real[idx].begin();
44
186
        unsigned first = S::Size();
45
186
        unsigned last = S::Size();
46
186
        for (unsigned i = 0; i < S::Size(); ++i) {
47
186
            bool match = (it != real[idx].end()) && *it == i;
48
186
            assert(sim[idx][i] == real[idx][i]);
49
186
            assert(match == real[idx][i]);
50
186
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
186
            if (match) {
52
186
                ++it;
53
186
                if (first == S::Size()) first = i;
54
186
                last = i;
55
186
            }
56
186
        }
57
186
        assert(it == real[idx].end());
58
186
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
186
        assert(sim[idx].any() == real[idx].Any());
61
186
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
186
        if (sim[idx].any()) {
64
186
            assert(first == real[idx].First());
65
186
            assert(last == real[idx].Last());
66
186
        }
67
        /* Count */
68
186
        assert(sim[idx].count() == real[idx].Count());
69
186
    };
70
71
49.7k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
49.7k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
49.7k
        unsigned args = ReadByte(buffer);
76
49.7k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
49.7k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
49.7k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
49.7k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
49.7k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
120k
        while (true) {
87
120k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
4.79k
                unsigned val = ReadByte(buffer) % S::Size();
90
4.79k
                assert(sim[dest][val] == real[dest][val]);
91
4.79k
                sim[dest].set(val);
92
4.79k
                real[dest].Set(val);
93
4.79k
                break;
94
116k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
1.14k
                unsigned val = ReadByte(buffer) % S::Size();
97
1.14k
                assert(sim[dest][val] == real[dest][val]);
98
1.14k
                sim[dest].reset(val);
99
1.14k
                real[dest].Reset(val);
100
1.14k
                break;
101
114k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
1.24k
                unsigned val = ReadByte(buffer) % S::Size();
104
1.24k
                assert(sim[dest][val] == real[dest][val]);
105
1.24k
                sim[dest].set(val, args >> 7);
106
1.24k
                real[dest].Set(val, args >> 7);
107
1.24k
                break;
108
113k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
747
                sim.resize(sim.size() + 1);
111
747
                real.resize(real.size() + 1);
112
747
                break;
113
112k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
683
                unsigned val = ReadByte(buffer) % S::Size();
116
683
                std::bitset<S::Size()> newset;
117
683
                newset[val] = true;
118
683
                sim.push_back(newset);
119
683
                real.push_back(S::Singleton(val));
120
683
                break;
121
112k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
3.73k
                compare_fn(dest);
124
3.73k
                sim[dest].reset();
125
3.73k
                real[dest] = S{};
126
123k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
119k
                    if (rng.randbool()) {
128
59.8k
                        sim[dest][i] = true;
129
59.8k
                        real[dest].Set(i);
130
59.8k
                    }
131
119k
                }
132
3.73k
                break;
133
108k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
3.68k
                unsigned r1 = rng.randrange(S::Size());
136
3.68k
                unsigned r2 = rng.randrange(S::Size());
137
3.68k
                unsigned r3 = rng.randrange(S::Size());
138
3.68k
                compare_fn(dest);
139
3.68k
                sim[dest].reset();
140
3.68k
                real[dest] = {r1, r2, r3};
141
3.68k
                sim[dest].set(r1);
142
3.68k
                sim[dest].set(r2);
143
3.68k
                sim[dest].set(r3);
144
3.68k
                break;
145
104k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
4.28k
                compare_fn(sim.size() - 1);
148
4.28k
                sim.pop_back();
149
4.28k
                real.pop_back();
150
4.28k
                break;
151
100k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
656
                sim.emplace_back(sim[src]);
154
656
                real.emplace_back(real[src]);
155
656
                break;
156
99.8k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.47k
                compare_fn(dest);
159
1.47k
                sim[dest] = sim[src];
160
1.47k
                real[dest] = real[src];
161
1.47k
                break;
162
98.3k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
858
                swap(sim[dest], sim[src]);
165
858
                swap(real[dest], real[src]);
166
858
                break;
167
97.4k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
2.35k
                unsigned r1 = rng.randrange(S::Size());
170
2.35k
                unsigned r2 = rng.randrange(S::Size());
171
2.35k
                sim.emplace_back();
172
2.35k
                sim.back().set(r1);
173
2.35k
                sim.back().set(r2);
174
2.35k
                real.push_back(S{r1, r2});
175
2.35k
                break;
176
95.1k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
4.25k
                unsigned len = ReadByte(buffer) % S::Size();
179
4.25k
                compare_fn(dest);
180
4.25k
                sim[dest].reset();
181
64.6k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
4.25k
                real[dest] = S::Fill(len);
183
4.25k
                break;
184
90.8k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
4.81k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
4.81k
                auto it = real[src].begin(), it_copy = it;
189
158k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
153k
                    if (i == val) it_copy = it;
191
153k
                    bool match = (it != real[src].end()) && *it == i;
192
153k
                    assert(match == sim[src][i]);
193
153k
                    if (match) ++it;
194
153k
                }
195
4.81k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
53.0k
                for (unsigned i = val; i < S::Size(); ++i) {
198
48.2k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
48.2k
                    assert(match == sim[src][i]);
200
48.2k
                    if (match) ++it_copy;
201
48.2k
                }
202
4.81k
                assert(it_copy == real[src].end());
203
4.81k
                break;
204
86.0k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
1.59k
                compare_fn(dest);
207
1.59k
                sim[dest] |= sim[src];
208
1.59k
                real[dest] |= real[src];
209
1.59k
                break;
210
84.4k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
1.14k
                compare_fn(dest);
213
1.14k
                sim[dest] &= sim[src];
214
1.14k
                real[dest] &= real[src];
215
1.14k
                break;
216
83.3k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.11k
                compare_fn(dest);
219
1.11k
                sim[dest] &= ~sim[src];
220
1.11k
                real[dest] -= real[src];
221
1.11k
                break;
222
82.2k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
855
                compare_fn(dest);
225
855
                sim[dest] ^= sim[src];
226
855
                real[dest] ^= real[src];
227
855
                break;
228
81.3k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
926
                compare_fn(dest);
231
926
                sim[dest] = sim[src] | sim[aux];
232
926
                real[dest] = real[src] | real[aux];
233
926
                break;
234
80.4k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
904
                compare_fn(dest);
237
904
                sim[dest] = sim[src] & sim[aux];
238
904
                real[dest] = real[src] & real[aux];
239
904
                break;
240
79.5k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
1.12k
                compare_fn(dest);
243
1.12k
                sim[dest] = sim[src] & ~sim[aux];
244
1.12k
                real[dest] = real[src] - real[aux];
245
1.12k
                break;
246
78.4k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.05k
                compare_fn(dest);
249
1.05k
                sim[dest] = sim[src] ^ sim[aux];
250
1.05k
                real[dest] = real[src] ^ real[aux];
251
1.05k
                break;
252
77.3k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
3.18k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
3.18k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
3.18k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
3.18k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
3.18k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
3.18k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
3.18k
                break;
261
74.1k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
1.14k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
1.14k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
1.14k
                break;
266
73.0k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
1.94k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
1.94k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
1.94k
                break;
271
1.94k
            }
272
120k
        }
273
49.7k
    }
274
    /* Fully compare the final state. */
275
713
    for (unsigned i = 0; i < sim.size(); ++i) {
276
527
        compare_fn(i);
277
527
    }
278
186
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetItLj3EEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
198
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
198
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
198
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
198
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
198
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
198
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
198
        auto it = real[idx].begin();
44
198
        unsigned first = S::Size();
45
198
        unsigned last = S::Size();
46
198
        for (unsigned i = 0; i < S::Size(); ++i) {
47
198
            bool match = (it != real[idx].end()) && *it == i;
48
198
            assert(sim[idx][i] == real[idx][i]);
49
198
            assert(match == real[idx][i]);
50
198
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
198
            if (match) {
52
198
                ++it;
53
198
                if (first == S::Size()) first = i;
54
198
                last = i;
55
198
            }
56
198
        }
57
198
        assert(it == real[idx].end());
58
198
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
198
        assert(sim[idx].any() == real[idx].Any());
61
198
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
198
        if (sim[idx].any()) {
64
198
            assert(first == real[idx].First());
65
198
            assert(last == real[idx].Last());
66
198
        }
67
        /* Count */
68
198
        assert(sim[idx].count() == real[idx].Count());
69
198
    };
70
71
44.9k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
44.9k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
44.9k
        unsigned args = ReadByte(buffer);
76
44.9k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
44.9k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
44.9k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
44.9k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
44.9k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
118k
        while (true) {
87
118k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
3.21k
                unsigned val = ReadByte(buffer) % S::Size();
90
3.21k
                assert(sim[dest][val] == real[dest][val]);
91
3.21k
                sim[dest].set(val);
92
3.21k
                real[dest].Set(val);
93
3.21k
                break;
94
115k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
1.13k
                unsigned val = ReadByte(buffer) % S::Size();
97
1.13k
                assert(sim[dest][val] == real[dest][val]);
98
1.13k
                sim[dest].reset(val);
99
1.13k
                real[dest].Reset(val);
100
1.13k
                break;
101
114k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
1.42k
                unsigned val = ReadByte(buffer) % S::Size();
104
1.42k
                assert(sim[dest][val] == real[dest][val]);
105
1.42k
                sim[dest].set(val, args >> 7);
106
1.42k
                real[dest].Set(val, args >> 7);
107
1.42k
                break;
108
112k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
619
                sim.resize(sim.size() + 1);
111
619
                real.resize(real.size() + 1);
112
619
                break;
113
112k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
756
                unsigned val = ReadByte(buffer) % S::Size();
116
756
                std::bitset<S::Size()> newset;
117
756
                newset[val] = true;
118
756
                sim.push_back(newset);
119
756
                real.push_back(S::Singleton(val));
120
756
                break;
121
111k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
2.42k
                compare_fn(dest);
124
2.42k
                sim[dest].reset();
125
2.42k
                real[dest] = S{};
126
118k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
116k
                    if (rng.randbool()) {
128
58.0k
                        sim[dest][i] = true;
129
58.0k
                        real[dest].Set(i);
130
58.0k
                    }
131
116k
                }
132
2.42k
                break;
133
108k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
5.82k
                unsigned r1 = rng.randrange(S::Size());
136
5.82k
                unsigned r2 = rng.randrange(S::Size());
137
5.82k
                unsigned r3 = rng.randrange(S::Size());
138
5.82k
                compare_fn(dest);
139
5.82k
                sim[dest].reset();
140
5.82k
                real[dest] = {r1, r2, r3};
141
5.82k
                sim[dest].set(r1);
142
5.82k
                sim[dest].set(r2);
143
5.82k
                sim[dest].set(r3);
144
5.82k
                break;
145
103k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
3.81k
                compare_fn(sim.size() - 1);
148
3.81k
                sim.pop_back();
149
3.81k
                real.pop_back();
150
3.81k
                break;
151
99.2k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
623
                sim.emplace_back(sim[src]);
154
623
                real.emplace_back(real[src]);
155
623
                break;
156
98.5k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.00k
                compare_fn(dest);
159
1.00k
                sim[dest] = sim[src];
160
1.00k
                real[dest] = real[src];
161
1.00k
                break;
162
97.5k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
918
                swap(sim[dest], sim[src]);
165
918
                swap(real[dest], real[src]);
166
918
                break;
167
96.6k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
1.96k
                unsigned r1 = rng.randrange(S::Size());
170
1.96k
                unsigned r2 = rng.randrange(S::Size());
171
1.96k
                sim.emplace_back();
172
1.96k
                sim.back().set(r1);
173
1.96k
                sim.back().set(r2);
174
1.96k
                real.push_back(S{r1, r2});
175
1.96k
                break;
176
94.7k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
2.67k
                unsigned len = ReadByte(buffer) % S::Size();
179
2.67k
                compare_fn(dest);
180
2.67k
                sim[dest].reset();
181
48.8k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
2.67k
                real[dest] = S::Fill(len);
183
2.67k
                break;
184
92.0k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
4.17k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
4.17k
                auto it = real[src].begin(), it_copy = it;
189
204k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
200k
                    if (i == val) it_copy = it;
191
200k
                    bool match = (it != real[src].end()) && *it == i;
192
200k
                    assert(match == sim[src][i]);
193
200k
                    if (match) ++it;
194
200k
                }
195
4.17k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
120k
                for (unsigned i = val; i < S::Size(); ++i) {
198
116k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
116k
                    assert(match == sim[src][i]);
200
116k
                    if (match) ++it_copy;
201
116k
                }
202
4.17k
                assert(it_copy == real[src].end());
203
4.17k
                break;
204
87.8k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
765
                compare_fn(dest);
207
765
                sim[dest] |= sim[src];
208
765
                real[dest] |= real[src];
209
765
                break;
210
87.0k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
1.13k
                compare_fn(dest);
213
1.13k
                sim[dest] &= sim[src];
214
1.13k
                real[dest] &= real[src];
215
1.13k
                break;
216
85.9k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.34k
                compare_fn(dest);
219
1.34k
                sim[dest] &= ~sim[src];
220
1.34k
                real[dest] -= real[src];
221
1.34k
                break;
222
84.6k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
767
                compare_fn(dest);
225
767
                sim[dest] ^= sim[src];
226
767
                real[dest] ^= real[src];
227
767
                break;
228
83.8k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
709
                compare_fn(dest);
231
709
                sim[dest] = sim[src] | sim[aux];
232
709
                real[dest] = real[src] | real[aux];
233
709
                break;
234
83.1k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
941
                compare_fn(dest);
237
941
                sim[dest] = sim[src] & sim[aux];
238
941
                real[dest] = real[src] & real[aux];
239
941
                break;
240
82.2k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
705
                compare_fn(dest);
243
705
                sim[dest] = sim[src] & ~sim[aux];
244
705
                real[dest] = real[src] - real[aux];
245
705
                break;
246
81.4k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
831
                compare_fn(dest);
249
831
                sim[dest] = sim[src] ^ sim[aux];
250
831
                real[dest] = real[src] ^ real[aux];
251
831
                break;
252
80.6k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
3.26k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
3.26k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
3.26k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
3.26k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
3.26k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
3.26k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
3.26k
                break;
261
77.4k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
1.04k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
1.04k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
1.04k
                break;
266
76.3k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
2.83k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
2.83k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
2.83k
                break;
271
2.83k
            }
272
118k
        }
273
44.9k
    }
274
    /* Fully compare the final state. */
275
747
    for (unsigned i = 0; i < sim.size(); ++i) {
276
549
        compare_fn(i);
277
549
    }
278
198
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail9IntBitSetImEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
196
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
196
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
196
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
196
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
196
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
196
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
196
        auto it = real[idx].begin();
44
196
        unsigned first = S::Size();
45
196
        unsigned last = S::Size();
46
196
        for (unsigned i = 0; i < S::Size(); ++i) {
47
196
            bool match = (it != real[idx].end()) && *it == i;
48
196
            assert(sim[idx][i] == real[idx][i]);
49
196
            assert(match == real[idx][i]);
50
196
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
196
            if (match) {
52
196
                ++it;
53
196
                if (first == S::Size()) first = i;
54
196
                last = i;
55
196
            }
56
196
        }
57
196
        assert(it == real[idx].end());
58
196
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
196
        assert(sim[idx].any() == real[idx].Any());
61
196
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
196
        if (sim[idx].any()) {
64
196
            assert(first == real[idx].First());
65
196
            assert(last == real[idx].Last());
66
196
        }
67
        /* Count */
68
196
        assert(sim[idx].count() == real[idx].Count());
69
196
    };
70
71
58.2k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
58.2k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
58.2k
        unsigned args = ReadByte(buffer);
76
58.2k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
58.2k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
58.2k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
58.2k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
58.2k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
140k
        while (true) {
87
140k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
6.32k
                unsigned val = ReadByte(buffer) % S::Size();
90
6.32k
                assert(sim[dest][val] == real[dest][val]);
91
6.32k
                sim[dest].set(val);
92
6.32k
                real[dest].Set(val);
93
6.32k
                break;
94
133k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
1.96k
                unsigned val = ReadByte(buffer) % S::Size();
97
1.96k
                assert(sim[dest][val] == real[dest][val]);
98
1.96k
                sim[dest].reset(val);
99
1.96k
                real[dest].Reset(val);
100
1.96k
                break;
101
131k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
1.59k
                unsigned val = ReadByte(buffer) % S::Size();
104
1.59k
                assert(sim[dest][val] == real[dest][val]);
105
1.59k
                sim[dest].set(val, args >> 7);
106
1.59k
                real[dest].Set(val, args >> 7);
107
1.59k
                break;
108
130k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
732
                sim.resize(sim.size() + 1);
111
732
                real.resize(real.size() + 1);
112
732
                break;
113
129k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
691
                unsigned val = ReadByte(buffer) % S::Size();
116
691
                std::bitset<S::Size()> newset;
117
691
                newset[val] = true;
118
691
                sim.push_back(newset);
119
691
                real.push_back(S::Singleton(val));
120
691
                break;
121
128k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
3.33k
                compare_fn(dest);
124
3.33k
                sim[dest].reset();
125
3.33k
                real[dest] = S{};
126
216k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
213k
                    if (rng.randbool()) {
128
106k
                        sim[dest][i] = true;
129
106k
                        real[dest].Set(i);
130
106k
                    }
131
213k
                }
132
3.33k
                break;
133
125k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
2.98k
                unsigned r1 = rng.randrange(S::Size());
136
2.98k
                unsigned r2 = rng.randrange(S::Size());
137
2.98k
                unsigned r3 = rng.randrange(S::Size());
138
2.98k
                compare_fn(dest);
139
2.98k
                sim[dest].reset();
140
2.98k
                real[dest] = {r1, r2, r3};
141
2.98k
                sim[dest].set(r1);
142
2.98k
                sim[dest].set(r2);
143
2.98k
                sim[dest].set(r3);
144
2.98k
                break;
145
122k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
4.17k
                compare_fn(sim.size() - 1);
148
4.17k
                sim.pop_back();
149
4.17k
                real.pop_back();
150
4.17k
                break;
151
118k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
802
                sim.emplace_back(sim[src]);
154
802
                real.emplace_back(real[src]);
155
802
                break;
156
117k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.38k
                compare_fn(dest);
159
1.38k
                sim[dest] = sim[src];
160
1.38k
                real[dest] = real[src];
161
1.38k
                break;
162
116k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
1.00k
                swap(sim[dest], sim[src]);
165
1.00k
                swap(real[dest], real[src]);
166
1.00k
                break;
167
115k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
2.11k
                unsigned r1 = rng.randrange(S::Size());
170
2.11k
                unsigned r2 = rng.randrange(S::Size());
171
2.11k
                sim.emplace_back();
172
2.11k
                sim.back().set(r1);
173
2.11k
                sim.back().set(r2);
174
2.11k
                real.push_back(S{r1, r2});
175
2.11k
                break;
176
112k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
3.76k
                unsigned len = ReadByte(buffer) % S::Size();
179
3.76k
                compare_fn(dest);
180
3.76k
                sim[dest].reset();
181
90.1k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
3.76k
                real[dest] = S::Fill(len);
183
3.76k
                break;
184
109k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
5.76k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
5.76k
                auto it = real[src].begin(), it_copy = it;
189
374k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
368k
                    if (i == val) it_copy = it;
191
368k
                    bool match = (it != real[src].end()) && *it == i;
192
368k
                    assert(match == sim[src][i]);
193
368k
                    if (match) ++it;
194
368k
                }
195
5.76k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
153k
                for (unsigned i = val; i < S::Size(); ++i) {
198
147k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
147k
                    assert(match == sim[src][i]);
200
147k
                    if (match) ++it_copy;
201
147k
                }
202
5.76k
                assert(it_copy == real[src].end());
203
5.76k
                break;
204
103k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
2.06k
                compare_fn(dest);
207
2.06k
                sim[dest] |= sim[src];
208
2.06k
                real[dest] |= real[src];
209
2.06k
                break;
210
101k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
1.61k
                compare_fn(dest);
213
1.61k
                sim[dest] &= sim[src];
214
1.61k
                real[dest] &= real[src];
215
1.61k
                break;
216
99.7k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.45k
                compare_fn(dest);
219
1.45k
                sim[dest] &= ~sim[src];
220
1.45k
                real[dest] -= real[src];
221
1.45k
                break;
222
98.3k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
1.22k
                compare_fn(dest);
225
1.22k
                sim[dest] ^= sim[src];
226
1.22k
                real[dest] ^= real[src];
227
1.22k
                break;
228
97.1k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
1.00k
                compare_fn(dest);
231
1.00k
                sim[dest] = sim[src] | sim[aux];
232
1.00k
                real[dest] = real[src] | real[aux];
233
1.00k
                break;
234
96.0k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
1.75k
                compare_fn(dest);
237
1.75k
                sim[dest] = sim[src] & sim[aux];
238
1.75k
                real[dest] = real[src] & real[aux];
239
1.75k
                break;
240
94.3k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
1.16k
                compare_fn(dest);
243
1.16k
                sim[dest] = sim[src] & ~sim[aux];
244
1.16k
                real[dest] = real[src] - real[aux];
245
1.16k
                break;
246
93.1k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.09k
                compare_fn(dest);
249
1.09k
                sim[dest] = sim[src] ^ sim[aux];
250
1.09k
                real[dest] = real[src] ^ real[aux];
251
1.09k
                break;
252
92.0k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
5.75k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
5.75k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
5.75k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
5.75k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
5.75k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
5.75k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
5.75k
                break;
261
86.3k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
1.27k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
1.27k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
1.27k
                break;
266
85.0k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
3.23k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
3.23k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
3.23k
                break;
271
3.23k
            }
272
140k
        }
273
58.2k
    }
274
    /* Fully compare the final state. */
275
749
    for (unsigned i = 0; i < sim.size(); ++i) {
276
553
        compare_fn(i);
277
553
    }
278
196
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetImLj1EEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
196
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
196
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
196
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
196
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
196
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
196
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
196
        auto it = real[idx].begin();
44
196
        unsigned first = S::Size();
45
196
        unsigned last = S::Size();
46
196
        for (unsigned i = 0; i < S::Size(); ++i) {
47
196
            bool match = (it != real[idx].end()) && *it == i;
48
196
            assert(sim[idx][i] == real[idx][i]);
49
196
            assert(match == real[idx][i]);
50
196
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
196
            if (match) {
52
196
                ++it;
53
196
                if (first == S::Size()) first = i;
54
196
                last = i;
55
196
            }
56
196
        }
57
196
        assert(it == real[idx].end());
58
196
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
196
        assert(sim[idx].any() == real[idx].Any());
61
196
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
196
        if (sim[idx].any()) {
64
196
            assert(first == real[idx].First());
65
196
            assert(last == real[idx].Last());
66
196
        }
67
        /* Count */
68
196
        assert(sim[idx].count() == real[idx].Count());
69
196
    };
70
71
58.2k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
58.2k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
58.2k
        unsigned args = ReadByte(buffer);
76
58.2k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
58.2k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
58.2k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
58.2k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
58.2k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
140k
        while (true) {
87
140k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
6.32k
                unsigned val = ReadByte(buffer) % S::Size();
90
6.32k
                assert(sim[dest][val] == real[dest][val]);
91
6.32k
                sim[dest].set(val);
92
6.32k
                real[dest].Set(val);
93
6.32k
                break;
94
133k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
1.96k
                unsigned val = ReadByte(buffer) % S::Size();
97
1.96k
                assert(sim[dest][val] == real[dest][val]);
98
1.96k
                sim[dest].reset(val);
99
1.96k
                real[dest].Reset(val);
100
1.96k
                break;
101
131k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
1.59k
                unsigned val = ReadByte(buffer) % S::Size();
104
1.59k
                assert(sim[dest][val] == real[dest][val]);
105
1.59k
                sim[dest].set(val, args >> 7);
106
1.59k
                real[dest].Set(val, args >> 7);
107
1.59k
                break;
108
130k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
732
                sim.resize(sim.size() + 1);
111
732
                real.resize(real.size() + 1);
112
732
                break;
113
129k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
691
                unsigned val = ReadByte(buffer) % S::Size();
116
691
                std::bitset<S::Size()> newset;
117
691
                newset[val] = true;
118
691
                sim.push_back(newset);
119
691
                real.push_back(S::Singleton(val));
120
691
                break;
121
128k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
3.33k
                compare_fn(dest);
124
3.33k
                sim[dest].reset();
125
3.33k
                real[dest] = S{};
126
216k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
213k
                    if (rng.randbool()) {
128
106k
                        sim[dest][i] = true;
129
106k
                        real[dest].Set(i);
130
106k
                    }
131
213k
                }
132
3.33k
                break;
133
125k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
2.98k
                unsigned r1 = rng.randrange(S::Size());
136
2.98k
                unsigned r2 = rng.randrange(S::Size());
137
2.98k
                unsigned r3 = rng.randrange(S::Size());
138
2.98k
                compare_fn(dest);
139
2.98k
                sim[dest].reset();
140
2.98k
                real[dest] = {r1, r2, r3};
141
2.98k
                sim[dest].set(r1);
142
2.98k
                sim[dest].set(r2);
143
2.98k
                sim[dest].set(r3);
144
2.98k
                break;
145
122k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
4.17k
                compare_fn(sim.size() - 1);
148
4.17k
                sim.pop_back();
149
4.17k
                real.pop_back();
150
4.17k
                break;
151
118k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
802
                sim.emplace_back(sim[src]);
154
802
                real.emplace_back(real[src]);
155
802
                break;
156
117k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.38k
                compare_fn(dest);
159
1.38k
                sim[dest] = sim[src];
160
1.38k
                real[dest] = real[src];
161
1.38k
                break;
162
116k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
1.00k
                swap(sim[dest], sim[src]);
165
1.00k
                swap(real[dest], real[src]);
166
1.00k
                break;
167
115k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
2.11k
                unsigned r1 = rng.randrange(S::Size());
170
2.11k
                unsigned r2 = rng.randrange(S::Size());
171
2.11k
                sim.emplace_back();
172
2.11k
                sim.back().set(r1);
173
2.11k
                sim.back().set(r2);
174
2.11k
                real.push_back(S{r1, r2});
175
2.11k
                break;
176
112k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
3.76k
                unsigned len = ReadByte(buffer) % S::Size();
179
3.76k
                compare_fn(dest);
180
3.76k
                sim[dest].reset();
181
90.1k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
3.76k
                real[dest] = S::Fill(len);
183
3.76k
                break;
184
109k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
5.76k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
5.76k
                auto it = real[src].begin(), it_copy = it;
189
374k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
368k
                    if (i == val) it_copy = it;
191
368k
                    bool match = (it != real[src].end()) && *it == i;
192
368k
                    assert(match == sim[src][i]);
193
368k
                    if (match) ++it;
194
368k
                }
195
5.76k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
153k
                for (unsigned i = val; i < S::Size(); ++i) {
198
147k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
147k
                    assert(match == sim[src][i]);
200
147k
                    if (match) ++it_copy;
201
147k
                }
202
5.76k
                assert(it_copy == real[src].end());
203
5.76k
                break;
204
103k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
2.06k
                compare_fn(dest);
207
2.06k
                sim[dest] |= sim[src];
208
2.06k
                real[dest] |= real[src];
209
2.06k
                break;
210
101k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
1.61k
                compare_fn(dest);
213
1.61k
                sim[dest] &= sim[src];
214
1.61k
                real[dest] &= real[src];
215
1.61k
                break;
216
99.7k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.45k
                compare_fn(dest);
219
1.45k
                sim[dest] &= ~sim[src];
220
1.45k
                real[dest] -= real[src];
221
1.45k
                break;
222
98.3k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
1.22k
                compare_fn(dest);
225
1.22k
                sim[dest] ^= sim[src];
226
1.22k
                real[dest] ^= real[src];
227
1.22k
                break;
228
97.1k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
1.00k
                compare_fn(dest);
231
1.00k
                sim[dest] = sim[src] | sim[aux];
232
1.00k
                real[dest] = real[src] | real[aux];
233
1.00k
                break;
234
96.0k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
1.75k
                compare_fn(dest);
237
1.75k
                sim[dest] = sim[src] & sim[aux];
238
1.75k
                real[dest] = real[src] & real[aux];
239
1.75k
                break;
240
94.3k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
1.16k
                compare_fn(dest);
243
1.16k
                sim[dest] = sim[src] & ~sim[aux];
244
1.16k
                real[dest] = real[src] - real[aux];
245
1.16k
                break;
246
93.1k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.09k
                compare_fn(dest);
249
1.09k
                sim[dest] = sim[src] ^ sim[aux];
250
1.09k
                real[dest] = real[src] ^ real[aux];
251
1.09k
                break;
252
92.0k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
5.75k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
5.75k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
5.75k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
5.75k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
5.75k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
5.75k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
5.75k
                break;
261
86.3k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
1.27k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
1.27k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
1.27k
                break;
266
85.0k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
3.23k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
3.23k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
3.23k
                break;
271
3.23k
            }
272
140k
        }
273
58.2k
    }
274
    /* Fully compare the final state. */
275
749
    for (unsigned i = 0; i < sim.size(); ++i) {
276
553
        compare_fn(i);
277
553
    }
278
196
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetIjLj2EEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
196
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
196
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
196
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
196
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
196
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
196
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
196
        auto it = real[idx].begin();
44
196
        unsigned first = S::Size();
45
196
        unsigned last = S::Size();
46
196
        for (unsigned i = 0; i < S::Size(); ++i) {
47
196
            bool match = (it != real[idx].end()) && *it == i;
48
196
            assert(sim[idx][i] == real[idx][i]);
49
196
            assert(match == real[idx][i]);
50
196
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
196
            if (match) {
52
196
                ++it;
53
196
                if (first == S::Size()) first = i;
54
196
                last = i;
55
196
            }
56
196
        }
57
196
        assert(it == real[idx].end());
58
196
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
196
        assert(sim[idx].any() == real[idx].Any());
61
196
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
196
        if (sim[idx].any()) {
64
196
            assert(first == real[idx].First());
65
196
            assert(last == real[idx].Last());
66
196
        }
67
        /* Count */
68
196
        assert(sim[idx].count() == real[idx].Count());
69
196
    };
70
71
58.2k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
58.2k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
58.2k
        unsigned args = ReadByte(buffer);
76
58.2k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
58.2k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
58.2k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
58.2k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
58.2k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
140k
        while (true) {
87
140k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
6.32k
                unsigned val = ReadByte(buffer) % S::Size();
90
6.32k
                assert(sim[dest][val] == real[dest][val]);
91
6.32k
                sim[dest].set(val);
92
6.32k
                real[dest].Set(val);
93
6.32k
                break;
94
133k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
1.96k
                unsigned val = ReadByte(buffer) % S::Size();
97
1.96k
                assert(sim[dest][val] == real[dest][val]);
98
1.96k
                sim[dest].reset(val);
99
1.96k
                real[dest].Reset(val);
100
1.96k
                break;
101
131k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
1.59k
                unsigned val = ReadByte(buffer) % S::Size();
104
1.59k
                assert(sim[dest][val] == real[dest][val]);
105
1.59k
                sim[dest].set(val, args >> 7);
106
1.59k
                real[dest].Set(val, args >> 7);
107
1.59k
                break;
108
130k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
732
                sim.resize(sim.size() + 1);
111
732
                real.resize(real.size() + 1);
112
732
                break;
113
129k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
691
                unsigned val = ReadByte(buffer) % S::Size();
116
691
                std::bitset<S::Size()> newset;
117
691
                newset[val] = true;
118
691
                sim.push_back(newset);
119
691
                real.push_back(S::Singleton(val));
120
691
                break;
121
128k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
3.33k
                compare_fn(dest);
124
3.33k
                sim[dest].reset();
125
3.33k
                real[dest] = S{};
126
216k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
213k
                    if (rng.randbool()) {
128
106k
                        sim[dest][i] = true;
129
106k
                        real[dest].Set(i);
130
106k
                    }
131
213k
                }
132
3.33k
                break;
133
125k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
2.98k
                unsigned r1 = rng.randrange(S::Size());
136
2.98k
                unsigned r2 = rng.randrange(S::Size());
137
2.98k
                unsigned r3 = rng.randrange(S::Size());
138
2.98k
                compare_fn(dest);
139
2.98k
                sim[dest].reset();
140
2.98k
                real[dest] = {r1, r2, r3};
141
2.98k
                sim[dest].set(r1);
142
2.98k
                sim[dest].set(r2);
143
2.98k
                sim[dest].set(r3);
144
2.98k
                break;
145
122k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
4.17k
                compare_fn(sim.size() - 1);
148
4.17k
                sim.pop_back();
149
4.17k
                real.pop_back();
150
4.17k
                break;
151
118k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
802
                sim.emplace_back(sim[src]);
154
802
                real.emplace_back(real[src]);
155
802
                break;
156
117k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.38k
                compare_fn(dest);
159
1.38k
                sim[dest] = sim[src];
160
1.38k
                real[dest] = real[src];
161
1.38k
                break;
162
116k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
1.00k
                swap(sim[dest], sim[src]);
165
1.00k
                swap(real[dest], real[src]);
166
1.00k
                break;
167
115k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
2.11k
                unsigned r1 = rng.randrange(S::Size());
170
2.11k
                unsigned r2 = rng.randrange(S::Size());
171
2.11k
                sim.emplace_back();
172
2.11k
                sim.back().set(r1);
173
2.11k
                sim.back().set(r2);
174
2.11k
                real.push_back(S{r1, r2});
175
2.11k
                break;
176
112k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
3.76k
                unsigned len = ReadByte(buffer) % S::Size();
179
3.76k
                compare_fn(dest);
180
3.76k
                sim[dest].reset();
181
90.1k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
3.76k
                real[dest] = S::Fill(len);
183
3.76k
                break;
184
109k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
5.76k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
5.76k
                auto it = real[src].begin(), it_copy = it;
189
374k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
368k
                    if (i == val) it_copy = it;
191
368k
                    bool match = (it != real[src].end()) && *it == i;
192
368k
                    assert(match == sim[src][i]);
193
368k
                    if (match) ++it;
194
368k
                }
195
5.76k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
153k
                for (unsigned i = val; i < S::Size(); ++i) {
198
147k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
147k
                    assert(match == sim[src][i]);
200
147k
                    if (match) ++it_copy;
201
147k
                }
202
5.76k
                assert(it_copy == real[src].end());
203
5.76k
                break;
204
103k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
2.06k
                compare_fn(dest);
207
2.06k
                sim[dest] |= sim[src];
208
2.06k
                real[dest] |= real[src];
209
2.06k
                break;
210
101k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
1.61k
                compare_fn(dest);
213
1.61k
                sim[dest] &= sim[src];
214
1.61k
                real[dest] &= real[src];
215
1.61k
                break;
216
99.7k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.45k
                compare_fn(dest);
219
1.45k
                sim[dest] &= ~sim[src];
220
1.45k
                real[dest] -= real[src];
221
1.45k
                break;
222
98.3k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
1.22k
                compare_fn(dest);
225
1.22k
                sim[dest] ^= sim[src];
226
1.22k
                real[dest] ^= real[src];
227
1.22k
                break;
228
97.1k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
1.00k
                compare_fn(dest);
231
1.00k
                sim[dest] = sim[src] | sim[aux];
232
1.00k
                real[dest] = real[src] | real[aux];
233
1.00k
                break;
234
96.0k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
1.75k
                compare_fn(dest);
237
1.75k
                sim[dest] = sim[src] & sim[aux];
238
1.75k
                real[dest] = real[src] & real[aux];
239
1.75k
                break;
240
94.3k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
1.16k
                compare_fn(dest);
243
1.16k
                sim[dest] = sim[src] & ~sim[aux];
244
1.16k
                real[dest] = real[src] - real[aux];
245
1.16k
                break;
246
93.1k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.09k
                compare_fn(dest);
249
1.09k
                sim[dest] = sim[src] ^ sim[aux];
250
1.09k
                real[dest] = real[src] ^ real[aux];
251
1.09k
                break;
252
92.0k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
5.75k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
5.75k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
5.75k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
5.75k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
5.75k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
5.75k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
5.75k
                break;
261
86.3k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
1.27k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
1.27k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
1.27k
                break;
266
85.0k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
3.23k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
3.23k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
3.23k
                break;
271
3.23k
            }
272
140k
        }
273
58.2k
    }
274
    /* Fully compare the final state. */
275
749
    for (unsigned i = 0; i < sim.size(); ++i) {
276
553
        compare_fn(i);
277
553
    }
278
196
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetItLj4EEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
196
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
196
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
196
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
196
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
196
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
196
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
196
        auto it = real[idx].begin();
44
196
        unsigned first = S::Size();
45
196
        unsigned last = S::Size();
46
196
        for (unsigned i = 0; i < S::Size(); ++i) {
47
196
            bool match = (it != real[idx].end()) && *it == i;
48
196
            assert(sim[idx][i] == real[idx][i]);
49
196
            assert(match == real[idx][i]);
50
196
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
196
            if (match) {
52
196
                ++it;
53
196
                if (first == S::Size()) first = i;
54
196
                last = i;
55
196
            }
56
196
        }
57
196
        assert(it == real[idx].end());
58
196
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
196
        assert(sim[idx].any() == real[idx].Any());
61
196
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
196
        if (sim[idx].any()) {
64
196
            assert(first == real[idx].First());
65
196
            assert(last == real[idx].Last());
66
196
        }
67
        /* Count */
68
196
        assert(sim[idx].count() == real[idx].Count());
69
196
    };
70
71
58.2k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
58.2k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
58.2k
        unsigned args = ReadByte(buffer);
76
58.2k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
58.2k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
58.2k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
58.2k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
58.2k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
140k
        while (true) {
87
140k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
6.32k
                unsigned val = ReadByte(buffer) % S::Size();
90
6.32k
                assert(sim[dest][val] == real[dest][val]);
91
6.32k
                sim[dest].set(val);
92
6.32k
                real[dest].Set(val);
93
6.32k
                break;
94
133k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
1.96k
                unsigned val = ReadByte(buffer) % S::Size();
97
1.96k
                assert(sim[dest][val] == real[dest][val]);
98
1.96k
                sim[dest].reset(val);
99
1.96k
                real[dest].Reset(val);
100
1.96k
                break;
101
131k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
1.59k
                unsigned val = ReadByte(buffer) % S::Size();
104
1.59k
                assert(sim[dest][val] == real[dest][val]);
105
1.59k
                sim[dest].set(val, args >> 7);
106
1.59k
                real[dest].Set(val, args >> 7);
107
1.59k
                break;
108
130k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
732
                sim.resize(sim.size() + 1);
111
732
                real.resize(real.size() + 1);
112
732
                break;
113
129k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
691
                unsigned val = ReadByte(buffer) % S::Size();
116
691
                std::bitset<S::Size()> newset;
117
691
                newset[val] = true;
118
691
                sim.push_back(newset);
119
691
                real.push_back(S::Singleton(val));
120
691
                break;
121
128k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
3.33k
                compare_fn(dest);
124
3.33k
                sim[dest].reset();
125
3.33k
                real[dest] = S{};
126
216k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
213k
                    if (rng.randbool()) {
128
106k
                        sim[dest][i] = true;
129
106k
                        real[dest].Set(i);
130
106k
                    }
131
213k
                }
132
3.33k
                break;
133
125k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
2.98k
                unsigned r1 = rng.randrange(S::Size());
136
2.98k
                unsigned r2 = rng.randrange(S::Size());
137
2.98k
                unsigned r3 = rng.randrange(S::Size());
138
2.98k
                compare_fn(dest);
139
2.98k
                sim[dest].reset();
140
2.98k
                real[dest] = {r1, r2, r3};
141
2.98k
                sim[dest].set(r1);
142
2.98k
                sim[dest].set(r2);
143
2.98k
                sim[dest].set(r3);
144
2.98k
                break;
145
122k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
4.17k
                compare_fn(sim.size() - 1);
148
4.17k
                sim.pop_back();
149
4.17k
                real.pop_back();
150
4.17k
                break;
151
118k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
802
                sim.emplace_back(sim[src]);
154
802
                real.emplace_back(real[src]);
155
802
                break;
156
117k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.38k
                compare_fn(dest);
159
1.38k
                sim[dest] = sim[src];
160
1.38k
                real[dest] = real[src];
161
1.38k
                break;
162
116k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
1.00k
                swap(sim[dest], sim[src]);
165
1.00k
                swap(real[dest], real[src]);
166
1.00k
                break;
167
115k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
2.11k
                unsigned r1 = rng.randrange(S::Size());
170
2.11k
                unsigned r2 = rng.randrange(S::Size());
171
2.11k
                sim.emplace_back();
172
2.11k
                sim.back().set(r1);
173
2.11k
                sim.back().set(r2);
174
2.11k
                real.push_back(S{r1, r2});
175
2.11k
                break;
176
112k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
3.76k
                unsigned len = ReadByte(buffer) % S::Size();
179
3.76k
                compare_fn(dest);
180
3.76k
                sim[dest].reset();
181
90.1k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
3.76k
                real[dest] = S::Fill(len);
183
3.76k
                break;
184
109k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
5.76k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
5.76k
                auto it = real[src].begin(), it_copy = it;
189
374k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
368k
                    if (i == val) it_copy = it;
191
368k
                    bool match = (it != real[src].end()) && *it == i;
192
368k
                    assert(match == sim[src][i]);
193
368k
                    if (match) ++it;
194
368k
                }
195
5.76k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
153k
                for (unsigned i = val; i < S::Size(); ++i) {
198
147k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
147k
                    assert(match == sim[src][i]);
200
147k
                    if (match) ++it_copy;
201
147k
                }
202
5.76k
                assert(it_copy == real[src].end());
203
5.76k
                break;
204
103k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
2.06k
                compare_fn(dest);
207
2.06k
                sim[dest] |= sim[src];
208
2.06k
                real[dest] |= real[src];
209
2.06k
                break;
210
101k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
1.61k
                compare_fn(dest);
213
1.61k
                sim[dest] &= sim[src];
214
1.61k
                real[dest] &= real[src];
215
1.61k
                break;
216
99.7k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.45k
                compare_fn(dest);
219
1.45k
                sim[dest] &= ~sim[src];
220
1.45k
                real[dest] -= real[src];
221
1.45k
                break;
222
98.3k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
1.22k
                compare_fn(dest);
225
1.22k
                sim[dest] ^= sim[src];
226
1.22k
                real[dest] ^= real[src];
227
1.22k
                break;
228
97.1k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
1.00k
                compare_fn(dest);
231
1.00k
                sim[dest] = sim[src] | sim[aux];
232
1.00k
                real[dest] = real[src] | real[aux];
233
1.00k
                break;
234
96.0k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
1.75k
                compare_fn(dest);
237
1.75k
                sim[dest] = sim[src] & sim[aux];
238
1.75k
                real[dest] = real[src] & real[aux];
239
1.75k
                break;
240
94.3k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
1.16k
                compare_fn(dest);
243
1.16k
                sim[dest] = sim[src] & ~sim[aux];
244
1.16k
                real[dest] = real[src] - real[aux];
245
1.16k
                break;
246
93.1k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.09k
                compare_fn(dest);
249
1.09k
                sim[dest] = sim[src] ^ sim[aux];
250
1.09k
                real[dest] = real[src] ^ real[aux];
251
1.09k
                break;
252
92.0k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
5.75k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
5.75k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
5.75k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
5.75k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
5.75k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
5.75k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
5.75k
                break;
261
86.3k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
1.27k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
1.27k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
1.27k
                break;
266
85.0k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
3.23k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
3.23k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
3.23k
                break;
271
3.23k
            }
272
140k
        }
273
58.2k
    }
274
    /* Fully compare the final state. */
275
749
    for (unsigned i = 0; i < sim.size(); ++i) {
276
553
        compare_fn(i);
277
553
    }
278
196
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetIjLj3EEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
190
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
190
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
190
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
190
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
190
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
190
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
190
        auto it = real[idx].begin();
44
190
        unsigned first = S::Size();
45
190
        unsigned last = S::Size();
46
190
        for (unsigned i = 0; i < S::Size(); ++i) {
47
190
            bool match = (it != real[idx].end()) && *it == i;
48
190
            assert(sim[idx][i] == real[idx][i]);
49
190
            assert(match == real[idx][i]);
50
190
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
190
            if (match) {
52
190
                ++it;
53
190
                if (first == S::Size()) first = i;
54
190
                last = i;
55
190
            }
56
190
        }
57
190
        assert(it == real[idx].end());
58
190
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
190
        assert(sim[idx].any() == real[idx].Any());
61
190
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
190
        if (sim[idx].any()) {
64
190
            assert(first == real[idx].First());
65
190
            assert(last == real[idx].Last());
66
190
        }
67
        /* Count */
68
190
        assert(sim[idx].count() == real[idx].Count());
69
190
    };
70
71
51.0k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
51.0k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
51.0k
        unsigned args = ReadByte(buffer);
76
51.0k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
51.0k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
51.0k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
51.0k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
51.0k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
129k
        while (true) {
87
129k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
3.93k
                unsigned val = ReadByte(buffer) % S::Size();
90
3.93k
                assert(sim[dest][val] == real[dest][val]);
91
3.93k
                sim[dest].set(val);
92
3.93k
                real[dest].Set(val);
93
3.93k
                break;
94
125k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
1.06k
                unsigned val = ReadByte(buffer) % S::Size();
97
1.06k
                assert(sim[dest][val] == real[dest][val]);
98
1.06k
                sim[dest].reset(val);
99
1.06k
                real[dest].Reset(val);
100
1.06k
                break;
101
124k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
1.38k
                unsigned val = ReadByte(buffer) % S::Size();
104
1.38k
                assert(sim[dest][val] == real[dest][val]);
105
1.38k
                sim[dest].set(val, args >> 7);
106
1.38k
                real[dest].Set(val, args >> 7);
107
1.38k
                break;
108
122k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
702
                sim.resize(sim.size() + 1);
111
702
                real.resize(real.size() + 1);
112
702
                break;
113
122k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
628
                unsigned val = ReadByte(buffer) % S::Size();
116
628
                std::bitset<S::Size()> newset;
117
628
                newset[val] = true;
118
628
                sim.push_back(newset);
119
628
                real.push_back(S::Singleton(val));
120
628
                break;
121
121k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
1.82k
                compare_fn(dest);
124
1.82k
                sim[dest].reset();
125
1.82k
                real[dest] = S{};
126
177k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
175k
                    if (rng.randbool()) {
128
87.4k
                        sim[dest][i] = true;
129
87.4k
                        real[dest].Set(i);
130
87.4k
                    }
131
175k
                }
132
1.82k
                break;
133
119k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
5.67k
                unsigned r1 = rng.randrange(S::Size());
136
5.67k
                unsigned r2 = rng.randrange(S::Size());
137
5.67k
                unsigned r3 = rng.randrange(S::Size());
138
5.67k
                compare_fn(dest);
139
5.67k
                sim[dest].reset();
140
5.67k
                real[dest] = {r1, r2, r3};
141
5.67k
                sim[dest].set(r1);
142
5.67k
                sim[dest].set(r2);
143
5.67k
                sim[dest].set(r3);
144
5.67k
                break;
145
114k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
4.18k
                compare_fn(sim.size() - 1);
148
4.18k
                sim.pop_back();
149
4.18k
                real.pop_back();
150
4.18k
                break;
151
109k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
1.02k
                sim.emplace_back(sim[src]);
154
1.02k
                real.emplace_back(real[src]);
155
1.02k
                break;
156
108k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.59k
                compare_fn(dest);
159
1.59k
                sim[dest] = sim[src];
160
1.59k
                real[dest] = real[src];
161
1.59k
                break;
162
107k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
1.31k
                swap(sim[dest], sim[src]);
165
1.31k
                swap(real[dest], real[src]);
166
1.31k
                break;
167
105k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
2.01k
                unsigned r1 = rng.randrange(S::Size());
170
2.01k
                unsigned r2 = rng.randrange(S::Size());
171
2.01k
                sim.emplace_back();
172
2.01k
                sim.back().set(r1);
173
2.01k
                sim.back().set(r2);
174
2.01k
                real.push_back(S{r1, r2});
175
2.01k
                break;
176
103k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
3.05k
                unsigned len = ReadByte(buffer) % S::Size();
179
3.05k
                compare_fn(dest);
180
3.05k
                sim[dest].reset();
181
108k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
3.05k
                real[dest] = S::Fill(len);
183
3.05k
                break;
184
100k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
3.63k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
3.63k
                auto it = real[src].begin(), it_copy = it;
189
352k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
348k
                    if (i == val) it_copy = it;
191
348k
                    bool match = (it != real[src].end()) && *it == i;
192
348k
                    assert(match == sim[src][i]);
193
348k
                    if (match) ++it;
194
348k
                }
195
3.63k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
154k
                for (unsigned i = val; i < S::Size(); ++i) {
198
151k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
151k
                    assert(match == sim[src][i]);
200
151k
                    if (match) ++it_copy;
201
151k
                }
202
3.63k
                assert(it_copy == real[src].end());
203
3.63k
                break;
204
97.2k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
1.03k
                compare_fn(dest);
207
1.03k
                sim[dest] |= sim[src];
208
1.03k
                real[dest] |= real[src];
209
1.03k
                break;
210
96.2k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
1.57k
                compare_fn(dest);
213
1.57k
                sim[dest] &= sim[src];
214
1.57k
                real[dest] &= real[src];
215
1.57k
                break;
216
94.6k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.55k
                compare_fn(dest);
219
1.55k
                sim[dest] &= ~sim[src];
220
1.55k
                real[dest] -= real[src];
221
1.55k
                break;
222
93.1k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
890
                compare_fn(dest);
225
890
                sim[dest] ^= sim[src];
226
890
                real[dest] ^= real[src];
227
890
                break;
228
92.2k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
1.05k
                compare_fn(dest);
231
1.05k
                sim[dest] = sim[src] | sim[aux];
232
1.05k
                real[dest] = real[src] | real[aux];
233
1.05k
                break;
234
91.1k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
1.07k
                compare_fn(dest);
237
1.07k
                sim[dest] = sim[src] & sim[aux];
238
1.07k
                real[dest] = real[src] & real[aux];
239
1.07k
                break;
240
90.0k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
1.31k
                compare_fn(dest);
243
1.31k
                sim[dest] = sim[src] & ~sim[aux];
244
1.31k
                real[dest] = real[src] - real[aux];
245
1.31k
                break;
246
88.7k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.11k
                compare_fn(dest);
249
1.11k
                sim[dest] = sim[src] ^ sim[aux];
250
1.11k
                real[dest] = real[src] ^ real[aux];
251
1.11k
                break;
252
87.6k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
3.86k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
3.86k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
3.86k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
3.86k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
3.86k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
3.86k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
3.86k
                break;
261
83.7k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
2.32k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
2.32k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
2.32k
                break;
266
81.4k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
3.17k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
3.17k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
3.17k
                break;
271
3.17k
            }
272
129k
        }
273
51.0k
    }
274
    /* Fully compare the final state. */
275
751
    for (unsigned i = 0; i < sim.size(); ++i) {
276
561
        compare_fn(i);
277
561
    }
278
190
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetImLj2EEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
206
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
206
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
206
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
206
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
206
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
206
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
206
        auto it = real[idx].begin();
44
206
        unsigned first = S::Size();
45
206
        unsigned last = S::Size();
46
206
        for (unsigned i = 0; i < S::Size(); ++i) {
47
206
            bool match = (it != real[idx].end()) && *it == i;
48
206
            assert(sim[idx][i] == real[idx][i]);
49
206
            assert(match == real[idx][i]);
50
206
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
206
            if (match) {
52
206
                ++it;
53
206
                if (first == S::Size()) first = i;
54
206
                last = i;
55
206
            }
56
206
        }
57
206
        assert(it == real[idx].end());
58
206
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
206
        assert(sim[idx].any() == real[idx].Any());
61
206
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
206
        if (sim[idx].any()) {
64
206
            assert(first == real[idx].First());
65
206
            assert(last == real[idx].Last());
66
206
        }
67
        /* Count */
68
206
        assert(sim[idx].count() == real[idx].Count());
69
206
    };
70
71
66.5k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
66.5k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
66.5k
        unsigned args = ReadByte(buffer);
76
66.5k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
66.5k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
66.5k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
66.5k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
66.5k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
155k
        while (true) {
87
155k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
6.02k
                unsigned val = ReadByte(buffer) % S::Size();
90
6.02k
                assert(sim[dest][val] == real[dest][val]);
91
6.02k
                sim[dest].set(val);
92
6.02k
                real[dest].Set(val);
93
6.02k
                break;
94
149k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
2.00k
                unsigned val = ReadByte(buffer) % S::Size();
97
2.00k
                assert(sim[dest][val] == real[dest][val]);
98
2.00k
                sim[dest].reset(val);
99
2.00k
                real[dest].Reset(val);
100
2.00k
                break;
101
147k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
2.17k
                unsigned val = ReadByte(buffer) % S::Size();
104
2.17k
                assert(sim[dest][val] == real[dest][val]);
105
2.17k
                sim[dest].set(val, args >> 7);
106
2.17k
                real[dest].Set(val, args >> 7);
107
2.17k
                break;
108
145k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
952
                sim.resize(sim.size() + 1);
111
952
                real.resize(real.size() + 1);
112
952
                break;
113
144k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
1.15k
                unsigned val = ReadByte(buffer) % S::Size();
116
1.15k
                std::bitset<S::Size()> newset;
117
1.15k
                newset[val] = true;
118
1.15k
                sim.push_back(newset);
119
1.15k
                real.push_back(S::Singleton(val));
120
1.15k
                break;
121
143k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
3.67k
                compare_fn(dest);
124
3.67k
                sim[dest].reset();
125
3.67k
                real[dest] = S{};
126
474k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
470k
                    if (rng.randbool()) {
128
235k
                        sim[dest][i] = true;
129
235k
                        real[dest].Set(i);
130
235k
                    }
131
470k
                }
132
3.67k
                break;
133
139k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
6.15k
                unsigned r1 = rng.randrange(S::Size());
136
6.15k
                unsigned r2 = rng.randrange(S::Size());
137
6.15k
                unsigned r3 = rng.randrange(S::Size());
138
6.15k
                compare_fn(dest);
139
6.15k
                sim[dest].reset();
140
6.15k
                real[dest] = {r1, r2, r3};
141
6.15k
                sim[dest].set(r1);
142
6.15k
                sim[dest].set(r2);
143
6.15k
                sim[dest].set(r3);
144
6.15k
                break;
145
133k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
4.86k
                compare_fn(sim.size() - 1);
148
4.86k
                sim.pop_back();
149
4.86k
                real.pop_back();
150
4.86k
                break;
151
128k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
736
                sim.emplace_back(sim[src]);
154
736
                real.emplace_back(real[src]);
155
736
                break;
156
127k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.95k
                compare_fn(dest);
159
1.95k
                sim[dest] = sim[src];
160
1.95k
                real[dest] = real[src];
161
1.95k
                break;
162
125k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
1.42k
                swap(sim[dest], sim[src]);
165
1.42k
                swap(real[dest], real[src]);
166
1.42k
                break;
167
124k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
2.20k
                unsigned r1 = rng.randrange(S::Size());
170
2.20k
                unsigned r2 = rng.randrange(S::Size());
171
2.20k
                sim.emplace_back();
172
2.20k
                sim.back().set(r1);
173
2.20k
                sim.back().set(r2);
174
2.20k
                real.push_back(S{r1, r2});
175
2.20k
                break;
176
122k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
3.56k
                unsigned len = ReadByte(buffer) % S::Size();
179
3.56k
                compare_fn(dest);
180
3.56k
                sim[dest].reset();
181
175k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
3.56k
                real[dest] = S::Fill(len);
183
3.56k
                break;
184
118k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
5.90k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
5.90k
                auto it = real[src].begin(), it_copy = it;
189
762k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
756k
                    if (i == val) it_copy = it;
191
756k
                    bool match = (it != real[src].end()) && *it == i;
192
756k
                    assert(match == sim[src][i]);
193
756k
                    if (match) ++it;
194
756k
                }
195
5.90k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
320k
                for (unsigned i = val; i < S::Size(); ++i) {
198
314k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
314k
                    assert(match == sim[src][i]);
200
314k
                    if (match) ++it_copy;
201
314k
                }
202
5.90k
                assert(it_copy == real[src].end());
203
5.90k
                break;
204
112k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
1.61k
                compare_fn(dest);
207
1.61k
                sim[dest] |= sim[src];
208
1.61k
                real[dest] |= real[src];
209
1.61k
                break;
210
110k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
1.44k
                compare_fn(dest);
213
1.44k
                sim[dest] &= sim[src];
214
1.44k
                real[dest] &= real[src];
215
1.44k
                break;
216
109k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.43k
                compare_fn(dest);
219
1.43k
                sim[dest] &= ~sim[src];
220
1.43k
                real[dest] -= real[src];
221
1.43k
                break;
222
108k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
942
                compare_fn(dest);
225
942
                sim[dest] ^= sim[src];
226
942
                real[dest] ^= real[src];
227
942
                break;
228
107k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
1.50k
                compare_fn(dest);
231
1.50k
                sim[dest] = sim[src] | sim[aux];
232
1.50k
                real[dest] = real[src] | real[aux];
233
1.50k
                break;
234
105k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
1.27k
                compare_fn(dest);
237
1.27k
                sim[dest] = sim[src] & sim[aux];
238
1.27k
                real[dest] = real[src] & real[aux];
239
1.27k
                break;
240
104k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
1.88k
                compare_fn(dest);
243
1.88k
                sim[dest] = sim[src] & ~sim[aux];
244
1.88k
                real[dest] = real[src] - real[aux];
245
1.88k
                break;
246
102k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.04k
                compare_fn(dest);
249
1.04k
                sim[dest] = sim[src] ^ sim[aux];
250
1.04k
                real[dest] = real[src] ^ real[aux];
251
1.04k
                break;
252
101k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
6.07k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
6.07k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
6.07k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
6.07k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
6.07k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
6.07k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
6.07k
                break;
261
95.3k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
2.29k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
2.29k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
2.29k
                break;
266
93.0k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
4.20k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
4.20k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
4.20k
                break;
271
4.20k
            }
272
155k
        }
273
66.5k
    }
274
    /* Fully compare the final state. */
275
795
    for (unsigned i = 0; i < sim.size(); ++i) {
276
589
        compare_fn(i);
277
589
    }
278
206
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetIjLj4EEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
206
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
206
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
206
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
206
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
206
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
206
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
206
        auto it = real[idx].begin();
44
206
        unsigned first = S::Size();
45
206
        unsigned last = S::Size();
46
206
        for (unsigned i = 0; i < S::Size(); ++i) {
47
206
            bool match = (it != real[idx].end()) && *it == i;
48
206
            assert(sim[idx][i] == real[idx][i]);
49
206
            assert(match == real[idx][i]);
50
206
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
206
            if (match) {
52
206
                ++it;
53
206
                if (first == S::Size()) first = i;
54
206
                last = i;
55
206
            }
56
206
        }
57
206
        assert(it == real[idx].end());
58
206
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
206
        assert(sim[idx].any() == real[idx].Any());
61
206
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
206
        if (sim[idx].any()) {
64
206
            assert(first == real[idx].First());
65
206
            assert(last == real[idx].Last());
66
206
        }
67
        /* Count */
68
206
        assert(sim[idx].count() == real[idx].Count());
69
206
    };
70
71
66.5k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
66.5k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
66.5k
        unsigned args = ReadByte(buffer);
76
66.5k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
66.5k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
66.5k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
66.5k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
66.5k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
155k
        while (true) {
87
155k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
6.02k
                unsigned val = ReadByte(buffer) % S::Size();
90
6.02k
                assert(sim[dest][val] == real[dest][val]);
91
6.02k
                sim[dest].set(val);
92
6.02k
                real[dest].Set(val);
93
6.02k
                break;
94
149k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
2.00k
                unsigned val = ReadByte(buffer) % S::Size();
97
2.00k
                assert(sim[dest][val] == real[dest][val]);
98
2.00k
                sim[dest].reset(val);
99
2.00k
                real[dest].Reset(val);
100
2.00k
                break;
101
147k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
2.17k
                unsigned val = ReadByte(buffer) % S::Size();
104
2.17k
                assert(sim[dest][val] == real[dest][val]);
105
2.17k
                sim[dest].set(val, args >> 7);
106
2.17k
                real[dest].Set(val, args >> 7);
107
2.17k
                break;
108
145k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
952
                sim.resize(sim.size() + 1);
111
952
                real.resize(real.size() + 1);
112
952
                break;
113
144k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
1.15k
                unsigned val = ReadByte(buffer) % S::Size();
116
1.15k
                std::bitset<S::Size()> newset;
117
1.15k
                newset[val] = true;
118
1.15k
                sim.push_back(newset);
119
1.15k
                real.push_back(S::Singleton(val));
120
1.15k
                break;
121
143k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
3.67k
                compare_fn(dest);
124
3.67k
                sim[dest].reset();
125
3.67k
                real[dest] = S{};
126
474k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
470k
                    if (rng.randbool()) {
128
235k
                        sim[dest][i] = true;
129
235k
                        real[dest].Set(i);
130
235k
                    }
131
470k
                }
132
3.67k
                break;
133
139k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
6.15k
                unsigned r1 = rng.randrange(S::Size());
136
6.15k
                unsigned r2 = rng.randrange(S::Size());
137
6.15k
                unsigned r3 = rng.randrange(S::Size());
138
6.15k
                compare_fn(dest);
139
6.15k
                sim[dest].reset();
140
6.15k
                real[dest] = {r1, r2, r3};
141
6.15k
                sim[dest].set(r1);
142
6.15k
                sim[dest].set(r2);
143
6.15k
                sim[dest].set(r3);
144
6.15k
                break;
145
133k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
4.86k
                compare_fn(sim.size() - 1);
148
4.86k
                sim.pop_back();
149
4.86k
                real.pop_back();
150
4.86k
                break;
151
128k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
736
                sim.emplace_back(sim[src]);
154
736
                real.emplace_back(real[src]);
155
736
                break;
156
127k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.95k
                compare_fn(dest);
159
1.95k
                sim[dest] = sim[src];
160
1.95k
                real[dest] = real[src];
161
1.95k
                break;
162
125k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
1.42k
                swap(sim[dest], sim[src]);
165
1.42k
                swap(real[dest], real[src]);
166
1.42k
                break;
167
124k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
2.20k
                unsigned r1 = rng.randrange(S::Size());
170
2.20k
                unsigned r2 = rng.randrange(S::Size());
171
2.20k
                sim.emplace_back();
172
2.20k
                sim.back().set(r1);
173
2.20k
                sim.back().set(r2);
174
2.20k
                real.push_back(S{r1, r2});
175
2.20k
                break;
176
122k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
3.56k
                unsigned len = ReadByte(buffer) % S::Size();
179
3.56k
                compare_fn(dest);
180
3.56k
                sim[dest].reset();
181
175k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
3.56k
                real[dest] = S::Fill(len);
183
3.56k
                break;
184
118k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
5.90k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
5.90k
                auto it = real[src].begin(), it_copy = it;
189
762k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
756k
                    if (i == val) it_copy = it;
191
756k
                    bool match = (it != real[src].end()) && *it == i;
192
756k
                    assert(match == sim[src][i]);
193
756k
                    if (match) ++it;
194
756k
                }
195
5.90k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
320k
                for (unsigned i = val; i < S::Size(); ++i) {
198
314k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
314k
                    assert(match == sim[src][i]);
200
314k
                    if (match) ++it_copy;
201
314k
                }
202
5.90k
                assert(it_copy == real[src].end());
203
5.90k
                break;
204
112k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
1.61k
                compare_fn(dest);
207
1.61k
                sim[dest] |= sim[src];
208
1.61k
                real[dest] |= real[src];
209
1.61k
                break;
210
110k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
1.44k
                compare_fn(dest);
213
1.44k
                sim[dest] &= sim[src];
214
1.44k
                real[dest] &= real[src];
215
1.44k
                break;
216
109k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.43k
                compare_fn(dest);
219
1.43k
                sim[dest] &= ~sim[src];
220
1.43k
                real[dest] -= real[src];
221
1.43k
                break;
222
108k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
942
                compare_fn(dest);
225
942
                sim[dest] ^= sim[src];
226
942
                real[dest] ^= real[src];
227
942
                break;
228
107k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
1.50k
                compare_fn(dest);
231
1.50k
                sim[dest] = sim[src] | sim[aux];
232
1.50k
                real[dest] = real[src] | real[aux];
233
1.50k
                break;
234
105k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
1.27k
                compare_fn(dest);
237
1.27k
                sim[dest] = sim[src] & sim[aux];
238
1.27k
                real[dest] = real[src] & real[aux];
239
1.27k
                break;
240
104k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
1.88k
                compare_fn(dest);
243
1.88k
                sim[dest] = sim[src] & ~sim[aux];
244
1.88k
                real[dest] = real[src] - real[aux];
245
1.88k
                break;
246
102k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.04k
                compare_fn(dest);
249
1.04k
                sim[dest] = sim[src] ^ sim[aux];
250
1.04k
                real[dest] = real[src] ^ real[aux];
251
1.04k
                break;
252
101k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
6.07k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
6.07k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
6.07k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
6.07k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
6.07k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
6.07k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
6.07k
                break;
261
95.3k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
2.29k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
2.29k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
2.29k
                break;
266
93.0k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
4.20k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
4.20k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
4.20k
                break;
271
4.20k
            }
272
155k
        }
273
66.5k
    }
274
    /* Fully compare the final state. */
275
795
    for (unsigned i = 0; i < sim.size(); ++i) {
276
589
        compare_fn(i);
277
589
    }
278
206
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetImLj3EEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
202
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
202
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
202
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
202
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
202
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
202
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
202
        auto it = real[idx].begin();
44
202
        unsigned first = S::Size();
45
202
        unsigned last = S::Size();
46
202
        for (unsigned i = 0; i < S::Size(); ++i) {
47
202
            bool match = (it != real[idx].end()) && *it == i;
48
202
            assert(sim[idx][i] == real[idx][i]);
49
202
            assert(match == real[idx][i]);
50
202
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
202
            if (match) {
52
202
                ++it;
53
202
                if (first == S::Size()) first = i;
54
202
                last = i;
55
202
            }
56
202
        }
57
202
        assert(it == real[idx].end());
58
202
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
202
        assert(sim[idx].any() == real[idx].Any());
61
202
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
202
        if (sim[idx].any()) {
64
202
            assert(first == real[idx].First());
65
202
            assert(last == real[idx].Last());
66
202
        }
67
        /* Count */
68
202
        assert(sim[idx].count() == real[idx].Count());
69
202
    };
70
71
64.7k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
64.7k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
64.7k
        unsigned args = ReadByte(buffer);
76
64.7k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
64.7k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
64.7k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
64.7k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
64.7k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
136k
        while (true) {
87
136k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
6.20k
                unsigned val = ReadByte(buffer) % S::Size();
90
6.20k
                assert(sim[dest][val] == real[dest][val]);
91
6.20k
                sim[dest].set(val);
92
6.20k
                real[dest].Set(val);
93
6.20k
                break;
94
130k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
2.98k
                unsigned val = ReadByte(buffer) % S::Size();
97
2.98k
                assert(sim[dest][val] == real[dest][val]);
98
2.98k
                sim[dest].reset(val);
99
2.98k
                real[dest].Reset(val);
100
2.98k
                break;
101
127k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
1.94k
                unsigned val = ReadByte(buffer) % S::Size();
104
1.94k
                assert(sim[dest][val] == real[dest][val]);
105
1.94k
                sim[dest].set(val, args >> 7);
106
1.94k
                real[dest].Set(val, args >> 7);
107
1.94k
                break;
108
125k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
802
                sim.resize(sim.size() + 1);
111
802
                real.resize(real.size() + 1);
112
802
                break;
113
124k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
1.04k
                unsigned val = ReadByte(buffer) % S::Size();
116
1.04k
                std::bitset<S::Size()> newset;
117
1.04k
                newset[val] = true;
118
1.04k
                sim.push_back(newset);
119
1.04k
                real.push_back(S::Singleton(val));
120
1.04k
                break;
121
123k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
4.47k
                compare_fn(dest);
124
4.47k
                sim[dest].reset();
125
4.47k
                real[dest] = S{};
126
862k
                for (unsigned i = 0; i < S::Size(); ++i) {
127
858k
                    if (rng.randbool()) {
128
429k
                        sim[dest][i] = true;
129
429k
                        real[dest].Set(i);
130
429k
                    }
131
858k
                }
132
4.47k
                break;
133
119k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
6.28k
                unsigned r1 = rng.randrange(S::Size());
136
6.28k
                unsigned r2 = rng.randrange(S::Size());
137
6.28k
                unsigned r3 = rng.randrange(S::Size());
138
6.28k
                compare_fn(dest);
139
6.28k
                sim[dest].reset();
140
6.28k
                real[dest] = {r1, r2, r3};
141
6.28k
                sim[dest].set(r1);
142
6.28k
                sim[dest].set(r2);
143
6.28k
                sim[dest].set(r3);
144
6.28k
                break;
145
112k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
3.91k
                compare_fn(sim.size() - 1);
148
3.91k
                sim.pop_back();
149
3.91k
                real.pop_back();
150
3.91k
                break;
151
108k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
908
                sim.emplace_back(sim[src]);
154
908
                real.emplace_back(real[src]);
155
908
                break;
156
108k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
1.76k
                compare_fn(dest);
159
1.76k
                sim[dest] = sim[src];
160
1.76k
                real[dest] = real[src];
161
1.76k
                break;
162
106k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
1.19k
                swap(sim[dest], sim[src]);
165
1.19k
                swap(real[dest], real[src]);
166
1.19k
                break;
167
105k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
1.32k
                unsigned r1 = rng.randrange(S::Size());
170
1.32k
                unsigned r2 = rng.randrange(S::Size());
171
1.32k
                sim.emplace_back();
172
1.32k
                sim.back().set(r1);
173
1.32k
                sim.back().set(r2);
174
1.32k
                real.push_back(S{r1, r2});
175
1.32k
                break;
176
103k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
4.33k
                unsigned len = ReadByte(buffer) % S::Size();
179
4.33k
                compare_fn(dest);
180
4.33k
                sim[dest].reset();
181
298k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
4.33k
                real[dest] = S::Fill(len);
183
4.33k
                break;
184
99.4k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
4.12k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
4.12k
                auto it = real[src].begin(), it_copy = it;
189
795k
                for (unsigned i = 0; i < S::Size(); ++i) {
190
791k
                    if (i == val) it_copy = it;
191
791k
                    bool match = (it != real[src].end()) && *it == i;
192
791k
                    assert(match == sim[src][i]);
193
791k
                    if (match) ++it;
194
791k
                }
195
4.12k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
446k
                for (unsigned i = val; i < S::Size(); ++i) {
198
442k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
442k
                    assert(match == sim[src][i]);
200
442k
                    if (match) ++it_copy;
201
442k
                }
202
4.12k
                assert(it_copy == real[src].end());
203
4.12k
                break;
204
95.3k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
1.69k
                compare_fn(dest);
207
1.69k
                sim[dest] |= sim[src];
208
1.69k
                real[dest] |= real[src];
209
1.69k
                break;
210
93.6k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
1.49k
                compare_fn(dest);
213
1.49k
                sim[dest] &= sim[src];
214
1.49k
                real[dest] &= real[src];
215
1.49k
                break;
216
92.1k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
2.01k
                compare_fn(dest);
219
2.01k
                sim[dest] &= ~sim[src];
220
2.01k
                real[dest] -= real[src];
221
2.01k
                break;
222
90.1k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
1.26k
                compare_fn(dest);
225
1.26k
                sim[dest] ^= sim[src];
226
1.26k
                real[dest] ^= real[src];
227
1.26k
                break;
228
88.8k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
1.18k
                compare_fn(dest);
231
1.18k
                sim[dest] = sim[src] | sim[aux];
232
1.18k
                real[dest] = real[src] | real[aux];
233
1.18k
                break;
234
87.6k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
1.48k
                compare_fn(dest);
237
1.48k
                sim[dest] = sim[src] & sim[aux];
238
1.48k
                real[dest] = real[src] & real[aux];
239
1.48k
                break;
240
86.1k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
2.17k
                compare_fn(dest);
243
2.17k
                sim[dest] = sim[src] & ~sim[aux];
244
2.17k
                real[dest] = real[src] - real[aux];
245
2.17k
                break;
246
83.9k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.18k
                compare_fn(dest);
249
1.18k
                sim[dest] = sim[src] ^ sim[aux];
250
1.18k
                real[dest] = real[src] ^ real[aux];
251
1.18k
                break;
252
82.8k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
4.31k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
4.31k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
4.31k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
4.31k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
4.31k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
4.31k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
4.31k
                break;
261
78.4k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
3.14k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
3.14k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
3.14k
                break;
266
75.3k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
3.49k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
3.49k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
3.49k
                break;
271
3.49k
            }
272
136k
        }
273
64.7k
    }
274
    /* Fully compare the final state. */
275
775
    for (unsigned i = 0; i < sim.size(); ++i) {
276
573
        compare_fn(i);
277
573
    }
278
202
}
bitset.cpp:_ZN12_GLOBAL__N_18TestTypeIN13bitset_detail14MultiIntBitSetImLj4EEEEEvSt4spanIKhLm18446744073709551615EE
Line
Count
Source
27
209
{
28
    /** This fuzz test's design is based on the assumption that the actual bits stored in the
29
     *  bitsets and their simulations do not matter for the purpose of detecting edge cases, thus
30
     *  these are taken from a deterministically-seeded RNG instead. To provide some level of
31
     *  variation however, pick the seed based on the buffer size and size of the chosen bitset. */
32
209
    InsecureRandomContext rng(buffer.size() + 0x10000 * S::Size());
33
34
209
    using Sim = std::bitset<S::Size()>;
35
    // Up to 4 real BitSets (initially 2).
36
209
    std::vector<S> real(2);
37
    // Up to 4 std::bitsets with the same corresponding contents.
38
209
    std::vector<Sim> sim(2);
39
40
    /* Compare sim[idx] with real[idx], using all inspector operations. */
41
209
    auto compare_fn = [&](unsigned idx) {
42
        /* iterators and operator[] */
43
209
        auto it = real[idx].begin();
44
209
        unsigned first = S::Size();
45
209
        unsigned last = S::Size();
46
209
        for (unsigned i = 0; i < S::Size(); ++i) {
47
209
            bool match = (it != real[idx].end()) && *it == i;
48
209
            assert(sim[idx][i] == real[idx][i]);
49
209
            assert(match == real[idx][i]);
50
209
            assert((it == real[idx].end()) != (it != real[idx].end()));
51
209
            if (match) {
52
209
                ++it;
53
209
                if (first == S::Size()) first = i;
54
209
                last = i;
55
209
            }
56
209
        }
57
209
        assert(it == real[idx].end());
58
209
        assert(!(it != real[idx].end()));
59
        /* Any / None */
60
209
        assert(sim[idx].any() == real[idx].Any());
61
209
        assert(sim[idx].none() == real[idx].None());
62
        /* First / Last */
63
209
        if (sim[idx].any()) {
64
209
            assert(first == real[idx].First());
65
209
            assert(last == real[idx].Last());
66
209
        }
67
        /* Count */
68
209
        assert(sim[idx].count() == real[idx].Count());
69
209
    };
70
71
63.0k
    LIMITED_WHILE(buffer.size() > 0, 1000) {
72
        // Read one byte to determine which operation to execute on the BitSets.
73
63.0k
        int command = ReadByte(buffer) % 64;
74
        // Read another byte that determines which bitsets will be involved.
75
63.0k
        unsigned args = ReadByte(buffer);
76
63.0k
        unsigned dest = ((args & 7) * sim.size()) >> 3;
77
63.0k
        unsigned src = (((args >> 3) & 7) * sim.size()) >> 3;
78
63.0k
        unsigned aux = (((args >> 6) & 3) * sim.size()) >> 2;
79
        // Args are in range for non-empty sim, or sim is completely empty and will be grown
80
63.0k
        assert((sim.empty() && dest == 0 && src == 0 && aux == 0) ||
81
63.0k
            (!sim.empty() &&  dest < sim.size() && src < sim.size() && aux < sim.size()));
82
83
        // Pick one operation based on value of command. Not all operations are always applicable.
84
        // Loop through the applicable ones until command reaches 0 (which avoids the need to
85
        // compute the number of applicable commands ahead of time).
86
165k
        while (true) {
87
165k
            if (dest < sim.size() && command-- == 0) {
88
                /* Set() (true) */
89
5.68k
                unsigned val = ReadByte(buffer) % S::Size();
90
5.68k
                assert(sim[dest][val] == real[dest][val]);
91
5.68k
                sim[dest].set(val);
92
5.68k
                real[dest].Set(val);
93
5.68k
                break;
94
159k
            } else if (dest < sim.size() && command-- == 0) {
95
                /* Reset() */
96
1.60k
                unsigned val = ReadByte(buffer) % S::Size();
97
1.60k
                assert(sim[dest][val] == real[dest][val]);
98
1.60k
                sim[dest].reset(val);
99
1.60k
                real[dest].Reset(val);
100
1.60k
                break;
101
157k
            } else if (dest < sim.size() && command-- == 0) {
102
                /* Set() (conditional) */
103
1.91k
                unsigned val = ReadByte(buffer) % S::Size();
104
1.91k
                assert(sim[dest][val] == real[dest][val]);
105
1.91k
                sim[dest].set(val, args >> 7);
106
1.91k
                real[dest].Set(val, args >> 7);
107
1.91k
                break;
108
156k
            } else if (sim.size() < 4 && command-- == 0) {
109
                /* Construct empty. */
110
642
                sim.resize(sim.size() + 1);
111
642
                real.resize(real.size() + 1);
112
642
                break;
113
155k
            } else if (sim.size() < 4 && command-- == 0) {
114
                /* Construct singleton. */
115
757
                unsigned val = ReadByte(buffer) % S::Size();
116
757
                std::bitset<S::Size()> newset;
117
757
                newset[val] = true;
118
757
                sim.push_back(newset);
119
757
                real.push_back(S::Singleton(val));
120
757
                break;
121
154k
            } else if (dest < sim.size() && command-- == 0) {
122
                /* Make random. */
123
4.33k
                compare_fn(dest);
124
4.33k
                sim[dest].reset();
125
4.33k
                real[dest] = S{};
126
1.11M
                for (unsigned i = 0; i < S::Size(); ++i) {
127
1.11M
                    if (rng.randbool()) {
128
555k
                        sim[dest][i] = true;
129
555k
                        real[dest].Set(i);
130
555k
                    }
131
1.11M
                }
132
4.33k
                break;
133
150k
            } else if (dest < sim.size() && command-- == 0) {
134
                /* Assign initializer list. */
135
5.28k
                unsigned r1 = rng.randrange(S::Size());
136
5.28k
                unsigned r2 = rng.randrange(S::Size());
137
5.28k
                unsigned r3 = rng.randrange(S::Size());
138
5.28k
                compare_fn(dest);
139
5.28k
                sim[dest].reset();
140
5.28k
                real[dest] = {r1, r2, r3};
141
5.28k
                sim[dest].set(r1);
142
5.28k
                sim[dest].set(r2);
143
5.28k
                sim[dest].set(r3);
144
5.28k
                break;
145
145k
            } else if (!sim.empty() && command-- == 0) {
146
                /* Destruct. */
147
4.31k
                compare_fn(sim.size() - 1);
148
4.31k
                sim.pop_back();
149
4.31k
                real.pop_back();
150
4.31k
                break;
151
140k
            } else if (sim.size() < 4 && src < sim.size() && command-- == 0) {
152
                /* Copy construct. */
153
613
                sim.emplace_back(sim[src]);
154
613
                real.emplace_back(real[src]);
155
613
                break;
156
140k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
157
                /* Copy assign. */
158
2.39k
                compare_fn(dest);
159
2.39k
                sim[dest] = sim[src];
160
2.39k
                real[dest] = real[src];
161
2.39k
                break;
162
137k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
163
                /* swap() function. */
164
1.22k
                swap(sim[dest], sim[src]);
165
1.22k
                swap(real[dest], real[src]);
166
1.22k
                break;
167
136k
            } else if (sim.size() < 4 && command-- == 0) {
168
                /* Construct with initializer list. */
169
2.45k
                unsigned r1 = rng.randrange(S::Size());
170
2.45k
                unsigned r2 = rng.randrange(S::Size());
171
2.45k
                sim.emplace_back();
172
2.45k
                sim.back().set(r1);
173
2.45k
                sim.back().set(r2);
174
2.45k
                real.push_back(S{r1, r2});
175
2.45k
                break;
176
134k
            } else if (dest < sim.size() && command-- == 0) {
177
                /* Fill() + copy assign. */
178
2.96k
                unsigned len = ReadByte(buffer) % S::Size();
179
2.96k
                compare_fn(dest);
180
2.96k
                sim[dest].reset();
181
260k
                for (unsigned i = 0; i < len; ++i) sim[dest][i] = true;
182
2.96k
                real[dest] = S::Fill(len);
183
2.96k
                break;
184
131k
            } else if (src < sim.size() && command-- == 0) {
185
                /* Iterator copy based compare. */
186
5.93k
                unsigned val = ReadByte(buffer) % S::Size();
187
                /* In a first loop, compare begin..end, and copy to it_copy at some point. */
188
5.93k
                auto it = real[src].begin(), it_copy = it;
189
1.52M
                for (unsigned i = 0; i < S::Size(); ++i) {
190
1.52M
                    if (i == val) it_copy = it;
191
1.52M
                    bool match = (it != real[src].end()) && *it == i;
192
1.52M
                    assert(match == sim[src][i]);
193
1.52M
                    if (match) ++it;
194
1.52M
                }
195
5.93k
                assert(it == real[src].end());
196
                /* Then compare from the copied point again to end. */
197
595k
                for (unsigned i = val; i < S::Size(); ++i) {
198
589k
                    bool match = (it_copy != real[src].end()) && *it_copy == i;
199
589k
                    assert(match == sim[src][i]);
200
589k
                    if (match) ++it_copy;
201
589k
                }
202
5.93k
                assert(it_copy == real[src].end());
203
5.93k
                break;
204
125k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
205
                /* operator|= */
206
1.25k
                compare_fn(dest);
207
1.25k
                sim[dest] |= sim[src];
208
1.25k
                real[dest] |= real[src];
209
1.25k
                break;
210
123k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
211
                /* operator&= */
212
1.13k
                compare_fn(dest);
213
1.13k
                sim[dest] &= sim[src];
214
1.13k
                real[dest] &= real[src];
215
1.13k
                break;
216
122k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
217
                /* operator-= */
218
1.53k
                compare_fn(dest);
219
1.53k
                sim[dest] &= ~sim[src];
220
1.53k
                real[dest] -= real[src];
221
1.53k
                break;
222
121k
            } else if (src < sim.size() && dest < sim.size() && command-- == 0) {
223
                /* operator^= */
224
1.05k
                compare_fn(dest);
225
1.05k
                sim[dest] ^= sim[src];
226
1.05k
                real[dest] ^= real[src];
227
1.05k
                break;
228
120k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
229
                /* operator| */
230
1.24k
                compare_fn(dest);
231
1.24k
                sim[dest] = sim[src] | sim[aux];
232
1.24k
                real[dest] = real[src] | real[aux];
233
1.24k
                break;
234
118k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
235
                /* operator& */
236
2.21k
                compare_fn(dest);
237
2.21k
                sim[dest] = sim[src] & sim[aux];
238
2.21k
                real[dest] = real[src] & real[aux];
239
2.21k
                break;
240
116k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
241
                /* operator- */
242
1.30k
                compare_fn(dest);
243
1.30k
                sim[dest] = sim[src] & ~sim[aux];
244
1.30k
                real[dest] = real[src] - real[aux];
245
1.30k
                break;
246
115k
            } else if (src < sim.size() && dest < sim.size() && aux < sim.size() && command-- == 0) {
247
                /* operator^ */
248
1.51k
                compare_fn(dest);
249
1.51k
                sim[dest] = sim[src] ^ sim[aux];
250
1.51k
                real[dest] = real[src] ^ real[aux];
251
1.51k
                break;
252
113k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
253
                /* IsSupersetOf() and IsSubsetOf() */
254
5.02k
                bool is_superset = (sim[aux] & ~sim[src]).none();
255
5.02k
                bool is_subset = (sim[src] & ~sim[aux]).none();
256
5.02k
                assert(real[src].IsSupersetOf(real[aux]) == is_superset);
257
5.02k
                assert(real[src].IsSubsetOf(real[aux]) == is_subset);
258
5.02k
                assert(real[aux].IsSupersetOf(real[src]) == is_subset);
259
5.02k
                assert(real[aux].IsSubsetOf(real[src]) == is_superset);
260
5.02k
                break;
261
108k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
262
                /* operator== and operator!= */
263
2.37k
                assert((sim[src] == sim[aux]) == (real[src] == real[aux]));
264
2.37k
                assert((sim[src] != sim[aux]) == (real[src] != real[aux]));
265
2.37k
                break;
266
106k
            } else if (src < sim.size() && aux < sim.size() && command-- == 0) {
267
                /* Overlaps() */
268
4.24k
                assert((sim[src] & sim[aux]).any() == real[src].Overlaps(real[aux]));
269
4.24k
                assert((sim[src] & sim[aux]).any() == real[aux].Overlaps(real[src]));
270
4.24k
                break;
271
4.24k
            }
272
165k
        }
273
63.0k
    }
274
    /* Fully compare the final state. */
275
778
    for (unsigned i = 0; i < sim.size(); ++i) {
276
569
        compare_fn(i);
277
569
    }
278
209
}
279
280
} // namespace
281
282
FUZZ_TARGET(bitset)
283
1.54k
{
284
1.54k
    unsigned typdat = ReadByte(buffer) % 8;
285
1.54k
    if (typdat == 0) {
286
        /* 16 bits */
287
159
        TestType<bitset_detail::IntBitSet<uint16_t>>(buffer);
288
159
        TestType<bitset_detail::MultiIntBitSet<uint16_t, 1>>(buffer);
289
1.38k
    } else if (typdat == 1) {
290
        /* 32 bits */
291
186
        TestType<bitset_detail::MultiIntBitSet<uint16_t, 2>>(buffer);
292
186
        TestType<bitset_detail::IntBitSet<uint32_t>>(buffer);
293
1.20k
    } else if (typdat == 2) {
294
        /* 48 bits */
295
198
        TestType<bitset_detail::MultiIntBitSet<uint16_t, 3>>(buffer);
296
1.00k
    } else if (typdat == 3) {
297
        /* 64 bits */
298
196
        TestType<bitset_detail::IntBitSet<uint64_t>>(buffer);
299
196
        TestType<bitset_detail::MultiIntBitSet<uint64_t, 1>>(buffer);
300
196
        TestType<bitset_detail::MultiIntBitSet<uint32_t, 2>>(buffer);
301
196
        TestType<bitset_detail::MultiIntBitSet<uint16_t, 4>>(buffer);
302
807
    } else if (typdat == 4) {
303
        /* 96 bits */
304
190
        TestType<bitset_detail::MultiIntBitSet<uint32_t, 3>>(buffer);
305
617
    } else if (typdat == 5) {
306
        /* 128 bits */
307
206
        TestType<bitset_detail::MultiIntBitSet<uint64_t, 2>>(buffer);
308
206
        TestType<bitset_detail::MultiIntBitSet<uint32_t, 4>>(buffer);
309
411
    } else if (typdat == 6) {
310
        /* 192 bits */
311
202
        TestType<bitset_detail::MultiIntBitSet<uint64_t, 3>>(buffer);
312
209
    } else if (typdat == 7) {
313
        /* 256 bits */
314
209
        TestType<bitset_detail::MultiIntBitSet<uint64_t, 4>>(buffer);
315
209
    }
316
1.54k
}