brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 109375f Raw
82 lines · cpp
1//===-- uint_fuzz.cpp -----------------------------------------------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8///9/// Fuzzing test for llvm-libc unsigned integer utilities.10///11//===----------------------------------------------------------------------===//12#include "src/__support/CPP/bit.h"13#include "src/__support/big_int.h"14#include "src/string/memory_utils/inline_memcpy.h"15 16using namespace LIBC_NAMESPACE;17 18// Helper function when using gdb / lldb to set a breakpoint and inspect values.19template <typename T> void debug_and_trap(const char *msg, T a, T b) {20  __builtin_trap();21}22 23#define DEBUG_AND_TRAP()24 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);28 29#define TEST_SHIFTOP(OP)                                                       \30  if ((a OP b) != (static_cast<T>(BigInt(a) OP b)))                            \31    debug_and_trap(#OP, a, b);32 33#define TEST_FUNCTION(FUN)                                                     \34  if (FUN(a) != FUN(BigInt(a)))                                                \35    debug_and_trap(#FUN, a, b);36 37// Test that basic arithmetic operations of BigInt behave like their scalar38// counterparts.39template <typename T, typename BigInt> void run_tests(T a, T b) {40  TEST_BINOP(+)41  TEST_BINOP(-)42  TEST_BINOP(*)43  if (b != 0)44    TEST_BINOP(/)45  if (b >= 0 && b < cpp::numeric_limits<T>::digits) {46    TEST_SHIFTOP(<<)47    TEST_SHIFTOP(>>)48  }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)55  }56}57 58// Reads a T from libfuzzer data.59template <typename T> T read(const uint8_t *data, size_t &remainder) {60  T out = 0;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;65  return out;66}67 68template <typename T, typename BigInt>69void 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);73}74 75extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {76  // unsigned77  run_tests<uint64_t, BigInt<64, false, uint16_t>>(data, size);78  // signed79  run_tests<int64_t, BigInt<64, true, uint16_t>>(data, size);80  return 0;81}82