xref: /openbsd-src/gnu/llvm/compiler-rt/lib/sanitizer_common/tests/sanitizer_leb128_test.cpp (revision 810390e339a5425391477d5d41c78d7cab2424ac)
1 //===-- sanitizer_leb128.cpp ------------------------------------*- 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 #include "sanitizer_common/sanitizer_leb128.h"
9 
10 #include <type_traits>
11 
12 #include "gtest/gtest.h"
13 #include "sanitizer_common/sanitizer_common.h"
14 #include "sanitizer_internal_defs.h"
15 
16 namespace __sanitizer {
17 
18 template <typename T>
19 class Leb128Test : public ::testing::Test {};
20 
21 using Leb128TestTypes = ::testing::Types<u8, u16, u32, u64>;
22 TYPED_TEST_SUITE(Leb128Test, Leb128TestTypes, );
23 
BitsNeeded(u64 v)24 static uptr BitsNeeded(u64 v) {
25   if (!v)
26     return 1;
27   uptr r = 0;
28   if (sizeof(uptr) != sizeof(u64)) {
29     uptr uptr_bits = 8 * sizeof(uptr);
30     while (v >> uptr_bits) {
31       r += uptr_bits;
32       v >>= uptr_bits;
33     }
34   }
35   return r + MostSignificantSetBitIndex(v) + 1;
36 }
37 
TYPED_TEST(Leb128Test,SignedOverflow)38 TYPED_TEST(Leb128Test, SignedOverflow) {
39   using T = typename std::make_signed<TypeParam>::type;
40   u8 buffer[16] = {255};
41   T v = -128;
42   EXPECT_EQ(buffer + 1, EncodeSLEB128(v, buffer, buffer + 1));
43   EXPECT_EQ(buffer + 1, DecodeSLEB128(buffer, buffer + 1, &v));
44 }
45 
TYPED_TEST(Leb128Test,Signed)46 TYPED_TEST(Leb128Test, Signed) {
47   using T = typename std::make_signed<TypeParam>::type;
48   T v = 0;
49   for (int i = 0; i < 100; ++i) {
50     u8 buffer[16] = {};
51     u8* p = EncodeSLEB128(v, std::begin(buffer), std::end(buffer));
52     EXPECT_EQ(int(BitsNeeded(v < 0 ? (-v - 1) : v) + 6 + 1) / 7, p - buffer)
53         << (int)v;
54     T v2;
55     u8* p2 = DecodeSLEB128(std::begin(buffer), std::end(buffer), &v2);
56     EXPECT_EQ(v, v2);
57     EXPECT_EQ(p, p2);
58     v = -TypeParam(v) * 3u + 1u;
59   }
60 }
61 
TYPED_TEST(Leb128Test,UnsignedOverflow)62 TYPED_TEST(Leb128Test, UnsignedOverflow) {
63   using T = TypeParam;
64   u8 buffer[16] = {255};
65   T v = 255;
66   EXPECT_EQ(buffer + 1, EncodeULEB128(v, buffer, buffer + 1));
67   EXPECT_EQ(buffer + 1, DecodeULEB128(buffer, buffer + 1, &v));
68 }
69 
TYPED_TEST(Leb128Test,Unsigned)70 TYPED_TEST(Leb128Test, Unsigned) {
71   using T = TypeParam;
72   T v = 0;
73   for (int i = 0; i < 100; ++i) {
74     u8 buffer[16] = {};
75     u8* p = EncodeULEB128(v, std::begin(buffer), std::end(buffer));
76     EXPECT_EQ(int(BitsNeeded(v) + 6) / 7, p - buffer);
77     T v2;
78     u8* p2 = DecodeULEB128(std::begin(buffer), std::end(buffer), &v2);
79     EXPECT_EQ(v, v2);
80     EXPECT_EQ(p, p2);
81     v = v * 3 + 1;
82   }
83 }
84 
85 }  // namespace __sanitizer
86