xref: /llvm-project/libc/fuzzing/math/SingleInputSingleOutputDiff.h (revision 5d56b34807e0f6e7a6684e57bec7c1751778862c)
1 //===-- Template to diff single-input-single-output functions ---*- C++ -*-===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIBC_FUZZING_MATH_SINGLE_INPUT_SINGLE_OUTPUT_DIFF_H
10 #define LLVM_LIBC_FUZZING_MATH_SINGLE_INPUT_SINGLE_OUTPUT_DIFF_H
11 
12 #include "fuzzing/math/Compare.h"
13 
14 #include <stddef.h>
15 #include <stdint.h>
16 
17 template <typename T> using SingleInputSingleOutputFunc = T (*)(T);
18 
19 template <typename T>
SingleInputSingleOutputDiff(SingleInputSingleOutputFunc<T> func1,SingleInputSingleOutputFunc<T> func2,const uint8_t * data,size_t size)20 void SingleInputSingleOutputDiff(SingleInputSingleOutputFunc<T> func1,
21                                  SingleInputSingleOutputFunc<T> func2,
22                                  const uint8_t *data, size_t size) {
23   if (size < sizeof(T))
24     return;
25 
26   T x = *reinterpret_cast<const T *>(data);
27 
28   T result1 = func1(x);
29   T result2 = func2(x);
30 
31   if (!ValuesEqual(result1, result2))
32     __builtin_trap();
33 }
34 
35 template <typename T1, typename T2>
36 using SingleInputSingleOutputWithSideEffectFunc = T1 (*)(T1, T2 *);
37 
38 template <typename T1, typename T2>
SingleInputSingleOutputWithSideEffectDiff(SingleInputSingleOutputWithSideEffectFunc<T1,T2> func1,SingleInputSingleOutputWithSideEffectFunc<T1,T2> func2,const uint8_t * data,size_t size)39 void SingleInputSingleOutputWithSideEffectDiff(
40     SingleInputSingleOutputWithSideEffectFunc<T1, T2> func1,
41     SingleInputSingleOutputWithSideEffectFunc<T1, T2> func2,
42     const uint8_t *data, size_t size) {
43   if (size < sizeof(T1))
44     return;
45 
46   T1 x = *reinterpret_cast<const T1 *>(data);
47   T2 sideEffect1, sideEffect2;
48 
49   T1 result1 = func1(x, &sideEffect1);
50   T1 result2 = func2(x, &sideEffect2);
51 
52   if (!ValuesEqual(result1, result2))
53     __builtin_trap();
54 
55   if (!ValuesEqual(sideEffect1, sideEffect2))
56     __builtin_trap();
57 }
58 
59 #endif // LLVM_LIBC_FUZZING_MATH_SINGLE_INPUT_SINGLE_OUTPUT_DIFF_H
60