/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 | } |