1 //===-- uint_fuzz.cpp -----------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 /// Fuzzing test for llvm-libc unsigned integer utilities.
11 //===----------------------------------------------------------------------===//
12 #include "src/__support/CPP/bit.h"
13 #include "src/__support/big_int.h"
14 #include "src/string/memory_utils/inline_memcpy.h"
16 using namespace LIBC_NAMESPACE
;
18 // Helper function when using gdb / lldb to set a breakpoint and inspect values.
19 template <typename T
> void debug_and_trap(const char *msg
, T a
, T b
) {
23 #define DEBUG_AND_TRAP()
25 #define TEST_BINOP(OP) \
26 if ((a OP b) != (static_cast<T>(BigInt(a) OP BigInt(b)))) \
27 debug_and_trap(#OP, a, b);
29 #define TEST_SHIFTOP(OP) \
30 if ((a OP b) != (static_cast<T>(BigInt(a) OP b))) \
31 debug_and_trap(#OP, a, b);
33 #define TEST_FUNCTION(FUN) \
34 if (FUN(a) != FUN(BigInt(a))) \
35 debug_and_trap(#FUN, a, b);
37 // Test that basic arithmetic operations of BigInt behave like their scalar
39 template <typename T
, typename BigInt
> void run_tests(T a
, T b
) {
45 if (b
>= 0 && b
< cpp::numeric_limits
<T
>::digits
) {
49 if constexpr (!BigInt::SIGNED
) {
50 TEST_FUNCTION(cpp::has_single_bit
)
51 TEST_FUNCTION(cpp::countr_zero
)
52 TEST_FUNCTION(cpp::countl_zero
)
53 TEST_FUNCTION(cpp::countl_one
)
54 TEST_FUNCTION(cpp::countr_one
)
58 // Reads a T from libfuzzer data.
59 template <typename T
> T
read(const uint8_t *data
, size_t &remainder
) {
61 constexpr size_t T_SIZE
= sizeof(T
);
62 const size_t copy_size
= remainder
< T_SIZE
? remainder
: T_SIZE
;
63 inline_memcpy(&out
, data
, copy_size
);
64 remainder
-= copy_size
;
68 template <typename T
, typename BigInt
>
69 void run_tests(const uint8_t *data
, size_t size
) {
70 const auto a
= read
<T
>(data
, size
);
71 const auto b
= read
<T
>(data
, size
);
72 run_tests
<T
, BigInt
>(a
, b
);
75 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data
, size_t size
) {
77 run_tests
<uint64_t, BigInt
<64, false, uint16_t>>(data
, size
);
79 run_tests
<int64_t, BigInt
<64, true, uint16_t>>(data
, size
);