1 //===-- ScalarTest.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
9 #include "gtest/gtest.h"
10
11 #include "lldb/Utility/DataExtractor.h"
12 #include "lldb/Utility/Endian.h"
13 #include "lldb/Utility/Scalar.h"
14 #include "lldb/Utility/Status.h"
15 #include "lldb/Utility/StreamString.h"
16 #include "llvm/Testing/Support/Error.h"
17
18 using namespace lldb_private;
19 using llvm::APInt;
20 using llvm::Failed;
21 using llvm::Succeeded;
22
23 template <typename T>
checkInequality(T c1,T c2)24 bool checkInequality(T c1, T c2) {
25 return (Scalar(c1) != Scalar(c2));
26 }
27
28 template <typename T>
checkEquality(T c1,T c2)29 bool checkEquality(T c1, T c2) {
30 return (Scalar(c1) == Scalar(c2));
31 }
32
TEST(ScalarTest,Equality)33 TEST(ScalarTest, Equality) {
34 ASSERT_TRUE(checkInequality<int>(23, 24));
35 ASSERT_TRUE(checkEquality<int>(96, 96));
36 ASSERT_TRUE(checkInequality<float>(4.0f, 4.5f));
37 ASSERT_TRUE(checkEquality<float>(4.0f, 4.0f));
38
39 auto apint1 = APInt(64, 234);
40 auto apint2 = APInt(64, 246);
41 ASSERT_TRUE(checkInequality<APInt>(apint1, apint2));
42 ASSERT_TRUE(checkEquality<APInt>(apint1, apint1));
43
44 Scalar void1;
45 Scalar void2;
46 float f1 = 2.0;
47 ASSERT_TRUE(void1 == void2);
48 ASSERT_FALSE(void1 == Scalar(f1));
49 }
50
TEST(ScalarTest,Comparison)51 TEST(ScalarTest, Comparison) {
52 auto s1 = Scalar(23);
53 auto s2 = Scalar(46);
54 ASSERT_TRUE(s1 < s2);
55 ASSERT_TRUE(s1 <= s2);
56 ASSERT_TRUE(s2 > s1);
57 ASSERT_TRUE(s2 >= s1);
58 }
59
TEST(ScalarTest,ComparisonFloat)60 TEST(ScalarTest, ComparisonFloat) {
61 auto s1 = Scalar(23.0f);
62 auto s2 = Scalar(46.0f);
63 ASSERT_TRUE(s1 < s2);
64 ASSERT_TRUE(s1 <= s2);
65 ASSERT_TRUE(s2 > s1);
66 ASSERT_TRUE(s2 >= s1);
67 }
68
TEST(ScalarTest,RightShiftOperator)69 TEST(ScalarTest, RightShiftOperator) {
70 int a = 0x00001000;
71 int b = 0xFFFFFFFF;
72 int c = 4;
73 Scalar a_scalar(a);
74 Scalar b_scalar(b);
75 Scalar c_scalar(c);
76 ASSERT_EQ(a >> c, a_scalar >> c_scalar);
77 ASSERT_EQ(b >> c, b_scalar >> c_scalar);
78 }
79
TEST(ScalarTest,GetBytes)80 TEST(ScalarTest, GetBytes) {
81 int a = 0x01020304;
82 long long b = 0x0102030405060708LL;
83 float c = 1234567.89e32f;
84 double d = 1234567.89e42;
85 char e[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
86 char f[32] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
87 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
88 Scalar a_scalar(a);
89 Scalar b_scalar(b);
90 Scalar c_scalar(c);
91 Scalar d_scalar(d);
92 Scalar e_scalar;
93 Scalar f_scalar;
94 DataExtractor e_data(e, sizeof(e), endian::InlHostByteOrder(),
95 sizeof(void *));
96 Status e_error =
97 e_scalar.SetValueFromData(e_data, lldb::eEncodingUint, sizeof(e));
98 DataExtractor f_data(f, sizeof(f), endian::InlHostByteOrder(),
99 sizeof(void *));
100 Status f_error =
101 f_scalar.SetValueFromData(f_data, lldb::eEncodingUint, sizeof(f));
102 ASSERT_EQ(0, memcmp(&a, a_scalar.GetBytes(), sizeof(a)));
103 ASSERT_EQ(0, memcmp(&b, b_scalar.GetBytes(), sizeof(b)));
104 ASSERT_EQ(0, memcmp(&c, c_scalar.GetBytes(), sizeof(c)));
105 ASSERT_EQ(0, memcmp(&d, d_scalar.GetBytes(), sizeof(d)));
106 ASSERT_EQ(0, e_error.Fail());
107 ASSERT_EQ(0, memcmp(e, e_scalar.GetBytes(), sizeof(e)));
108 ASSERT_EQ(0, f_error.Fail());
109 ASSERT_EQ(0, memcmp(f, f_scalar.GetBytes(), sizeof(f)));
110 }
111
TEST(ScalarTest,CastOperations)112 TEST(ScalarTest, CastOperations) {
113 long long a = 0xf1f2f3f4f5f6f7f8LL;
114 Scalar a_scalar(a);
115 ASSERT_EQ((signed char)a, a_scalar.SChar());
116 ASSERT_EQ((unsigned char)a, a_scalar.UChar());
117 ASSERT_EQ((signed short)a, a_scalar.SShort());
118 ASSERT_EQ((unsigned short)a, a_scalar.UShort());
119 ASSERT_EQ((signed int)a, a_scalar.SInt());
120 ASSERT_EQ((unsigned int)a, a_scalar.UInt());
121 ASSERT_EQ((signed long)a, a_scalar.SLong());
122 ASSERT_EQ((unsigned long)a, a_scalar.ULong());
123 ASSERT_EQ((signed long long)a, a_scalar.SLongLong());
124 ASSERT_EQ((unsigned long long)a, a_scalar.ULongLong());
125
126 int a2 = 23;
127 Scalar a2_scalar(a2);
128 ASSERT_EQ((float)a2, a2_scalar.Float());
129 ASSERT_EQ((double)a2, a2_scalar.Double());
130 ASSERT_EQ((long double)a2, a2_scalar.LongDouble());
131 }
132
TEST(ScalarTest,ExtractBitfield)133 TEST(ScalarTest, ExtractBitfield) {
134 uint32_t len = sizeof(long long) * 8;
135
136 long long a1 = 0xf1f2f3f4f5f6f7f8LL;
137 long long b1 = 0xff1f2f3f4f5f6f7fLL;
138 Scalar s_scalar(a1);
139 ASSERT_TRUE(s_scalar.ExtractBitfield(0, 0));
140 ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1)));
141 ASSERT_TRUE(s_scalar.ExtractBitfield(len, 0));
142 ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1)));
143 ASSERT_TRUE(s_scalar.ExtractBitfield(len - 4, 4));
144 ASSERT_EQ(0, memcmp(&b1, s_scalar.GetBytes(), sizeof(b1)));
145
146 unsigned long long a2 = 0xf1f2f3f4f5f6f7f8ULL;
147 unsigned long long b2 = 0x0f1f2f3f4f5f6f7fULL;
148 Scalar u_scalar(a2);
149 ASSERT_TRUE(u_scalar.ExtractBitfield(0, 0));
150 ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2)));
151 ASSERT_TRUE(u_scalar.ExtractBitfield(len, 0));
152 ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2)));
153 ASSERT_TRUE(u_scalar.ExtractBitfield(len - 4, 4));
154 ASSERT_EQ(0, memcmp(&b2, u_scalar.GetBytes(), sizeof(b2)));
155 }
156
ScalarGetValue(T value)157 template <typename T> static std::string ScalarGetValue(T value) {
158 StreamString stream;
159 Scalar(value).GetValue(&stream, false);
160 return stream.GetString();
161 }
162
TEST(ScalarTest,GetValue)163 TEST(ScalarTest, GetValue) {
164 EXPECT_EQ("12345", ScalarGetValue<signed short>(12345));
165 EXPECT_EQ("-12345", ScalarGetValue<signed short>(-12345));
166 EXPECT_EQ("12345", ScalarGetValue<unsigned short>(12345));
167 EXPECT_EQ(std::to_string(std::numeric_limits<unsigned short>::max()),
168 ScalarGetValue(std::numeric_limits<unsigned short>::max()));
169
170 EXPECT_EQ("12345", ScalarGetValue<signed int>(12345));
171 EXPECT_EQ("-12345", ScalarGetValue<signed int>(-12345));
172 EXPECT_EQ("12345", ScalarGetValue<unsigned int>(12345));
173 EXPECT_EQ(std::to_string(std::numeric_limits<unsigned int>::max()),
174 ScalarGetValue(std::numeric_limits<unsigned int>::max()));
175
176 EXPECT_EQ("12345678", ScalarGetValue<signed long>(12345678L));
177 EXPECT_EQ("-12345678", ScalarGetValue<signed long>(-12345678L));
178 EXPECT_EQ("12345678", ScalarGetValue<unsigned long>(12345678UL));
179 EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long>::max()),
180 ScalarGetValue(std::numeric_limits<unsigned long>::max()));
181
182 EXPECT_EQ("1234567890123", ScalarGetValue<signed long long>(1234567890123LL));
183 EXPECT_EQ("-1234567890123",
184 ScalarGetValue<signed long long>(-1234567890123LL));
185 EXPECT_EQ("1234567890123",
186 ScalarGetValue<unsigned long long>(1234567890123ULL));
187 EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long long>::max()),
188 ScalarGetValue(std::numeric_limits<unsigned long long>::max()));
189 }
190
TEST(ScalarTest,Division)191 TEST(ScalarTest, Division) {
192 Scalar lhs(5.0);
193 Scalar rhs(2.0);
194 Scalar r = lhs / rhs;
195 EXPECT_TRUE(r.IsValid());
196 EXPECT_EQ(r, Scalar(2.5));
197 }
198
TEST(ScalarTest,Promotion)199 TEST(ScalarTest, Promotion) {
200 static Scalar::Type int_types[] = {
201 Scalar::e_sint, Scalar::e_uint, Scalar::e_slong,
202 Scalar::e_ulong, Scalar::e_slonglong, Scalar::e_ulonglong,
203 Scalar::e_sint128, Scalar::e_uint128, Scalar::e_sint256,
204 Scalar::e_uint256,
205 Scalar::e_void // sentinel
206 };
207
208 static Scalar::Type float_types[] = {
209 Scalar::e_float, Scalar::e_double, Scalar::e_long_double,
210 Scalar::e_void // sentinel
211 };
212
213 for (int i = 0; int_types[i] != Scalar::e_void; ++i) {
214 for (int j = 0; float_types[j] != Scalar::e_void; ++j) {
215 Scalar lhs(2);
216 EXPECT_TRUE(lhs.Promote(int_types[i])) << "int promotion #" << i;
217 Scalar rhs(0.5f);
218 EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j;
219 Scalar x(2.5f);
220 EXPECT_TRUE(x.Promote(float_types[j]));
221 EXPECT_EQ(lhs + rhs, x);
222 }
223 }
224
225 for (int i = 0; float_types[i] != Scalar::e_void; ++i) {
226 for (int j = 0; float_types[j] != Scalar::e_void; ++j) {
227 Scalar lhs(2);
228 EXPECT_TRUE(lhs.Promote(float_types[i])) << "float promotion #" << i;
229 Scalar rhs(0.5f);
230 EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j;
231 Scalar x(2.5f);
232 EXPECT_TRUE(x.Promote(float_types[j]));
233 EXPECT_EQ(lhs + rhs, x);
234 }
235 }
236 }
237
TEST(ScalarTest,SetValueFromCString)238 TEST(ScalarTest, SetValueFromCString) {
239 Scalar a;
240
241 EXPECT_THAT_ERROR(
242 a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 8).ToError(),
243 Succeeded());
244 EXPECT_EQ(1234567890123ull, a);
245
246 EXPECT_THAT_ERROR(
247 a.SetValueFromCString("-1234567890123", lldb::eEncodingSint, 8).ToError(),
248 Succeeded());
249 EXPECT_EQ(-1234567890123ll, a);
250
251 EXPECT_THAT_ERROR(
252 a.SetValueFromCString("asdf", lldb::eEncodingSint, 8).ToError(),
253 Failed());
254 EXPECT_THAT_ERROR(
255 a.SetValueFromCString("asdf", lldb::eEncodingUint, 8).ToError(),
256 Failed());
257 EXPECT_THAT_ERROR(
258 a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 4).ToError(),
259 Failed());
260 EXPECT_THAT_ERROR(a.SetValueFromCString("123456789012345678901234567890",
261 lldb::eEncodingUint, 8)
262 .ToError(),
263 Failed());
264 EXPECT_THAT_ERROR(
265 a.SetValueFromCString("-123", lldb::eEncodingUint, 8).ToError(),
266 Failed());
267 }
268
TEST(ScalarTest,APIntConstructor)269 TEST(ScalarTest, APIntConstructor) {
270 auto width_array = {8, 16, 32};
271 for (auto &w : width_array) {
272 Scalar A(APInt(w, 24));
273 EXPECT_EQ(A.GetType(), Scalar::e_sint);
274 }
275
276 Scalar B(APInt(64, 42));
277 EXPECT_EQ(B.GetType(), Scalar::GetBestTypeForBitSize(64, true));
278 Scalar C(APInt(128, 96));
279 EXPECT_EQ(C.GetType(), Scalar::e_sint128);
280 Scalar D(APInt(256, 156));
281 EXPECT_EQ(D.GetType(), Scalar::e_sint256);
282 Scalar E(APInt(512, 456));
283 EXPECT_EQ(E.GetType(), Scalar::e_sint512);
284 }
285
TEST(ScalarTest,Scalar_512)286 TEST(ScalarTest, Scalar_512) {
287 Scalar Z(APInt(512, 0));
288 ASSERT_TRUE(Z.IsZero());
289 Z.MakeUnsigned();
290 ASSERT_TRUE(Z.IsZero());
291
292 Scalar S(APInt(512, 2000));
293 ASSERT_STREQ(S.GetTypeAsCString(), "int512_t");
294 ASSERT_STREQ(S.GetValueTypeAsCString(Scalar::e_sint512), "int512_t");
295
296 ASSERT_TRUE(S.MakeUnsigned());
297 EXPECT_EQ(S.GetType(), Scalar::e_uint512);
298 ASSERT_STREQ(S.GetTypeAsCString(), "unsigned int512_t");
299 ASSERT_STREQ(S.GetValueTypeAsCString(Scalar::e_uint512), "uint512_t");
300 EXPECT_EQ(S.GetByteSize(), 64U);
301
302 ASSERT_TRUE(S.MakeSigned());
303 EXPECT_EQ(S.GetType(), Scalar::e_sint512);
304 EXPECT_EQ(S.GetByteSize(), 64U);
305 }
306