1//===-- ScalarTest.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-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#include <cmath>
19
20using namespace lldb_private;
21using llvm::APFloat;
22using llvm::APInt;
23using llvm::Failed;
24using llvm::Succeeded;
25
26template <typename T>
27bool checkInequality(T c1, T c2) {
28 return (Scalar(c1) != Scalar(c2));
29}
30
31template <typename T>
32bool checkEquality(T c1, T c2) {
33 return (Scalar(c1) == Scalar(c2));
34}
35
36TEST(ScalarTest, Equality) {
37 ASSERT_TRUE(checkInequality<int>(23, 24));
38 ASSERT_TRUE(checkEquality<int>(96, 96));
39 ASSERT_TRUE(checkInequality<float>(4.0f, 4.5f));
40 ASSERT_TRUE(checkEquality<float>(4.0f, 4.0f));
41
42 auto apint1 = APInt(64, 234);
43 auto apint2 = APInt(64, 246);
44 ASSERT_TRUE(checkInequality<APInt>(apint1, apint2));
45 ASSERT_TRUE(checkEquality<APInt>(apint1, apint1));
46
47 Scalar void1;
48 Scalar void2;
49 float f1 = 2.0;
50 ASSERT_TRUE(void1 == void2);
51 ASSERT_FALSE(void1 == Scalar(f1));
52}
53
54TEST(ScalarTest, Comparison) {
55 auto s1 = Scalar(23);
56 auto s2 = Scalar(46);
57 ASSERT_TRUE(s1 < s2);
58 ASSERT_TRUE(s1 <= s2);
59 ASSERT_TRUE(s2 > s1);
60 ASSERT_TRUE(s2 >= s1);
61}
62
63TEST(ScalarTest, ComparisonFloat) {
64 auto s1 = Scalar(23.0f);
65 auto s2 = Scalar(46.0f);
66 ASSERT_TRUE(s1 < s2);
67 ASSERT_TRUE(s1 <= s2);
68 ASSERT_TRUE(s2 > s1);
69 ASSERT_TRUE(s2 >= s1);
70}
71
72template <typename T> static void CheckConversion(T val) {
73 SCOPED_TRACE("val = " + std::to_string(val));
74 EXPECT_EQ((signed char)val, Scalar(val).SChar());
75 EXPECT_EQ((unsigned char)val, Scalar(val).UChar());
76 EXPECT_EQ((short)val, Scalar(val).SShort());
77 EXPECT_EQ((unsigned short)val, Scalar(val).UShort());
78 EXPECT_EQ((int)val, Scalar(val).SInt());
79 EXPECT_EQ((unsigned)val, Scalar(val).UInt());
80 EXPECT_EQ((long)val, Scalar(val).SLong());
81 EXPECT_EQ((unsigned long)val, Scalar(val).ULong());
82 EXPECT_EQ((long long)val, Scalar(val).SLongLong());
83 EXPECT_EQ((unsigned long long)val, Scalar(val).ULongLong());
84 EXPECT_NEAR((float)val, Scalar(val).Float(), std::abs(val / 1e6));
85 EXPECT_NEAR((double)val, Scalar(val).Double(), std::abs(val / 1e12));
86 EXPECT_NEAR((long double)val, Scalar(val).LongDouble(), std::abs(val / 1e12));
87}
88
89TEST(ScalarTest, Getters) {
90 CheckConversion<int>(val: 0x87654321);
91 CheckConversion<unsigned int>(val: 0x87654321u);
92 CheckConversion<long>(val: 0x87654321l);
93 CheckConversion<unsigned long>(val: 0x87654321ul);
94 CheckConversion<long long>(val: 0x8765432112345678ll);
95 CheckConversion<unsigned long long>(val: 0x8765432112345678ull);
96 CheckConversion<float>(val: 42.25f);
97 CheckConversion<double>(val: 42.25);
98 CheckConversion<long double>(val: 42.25L);
99
100 EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0f, 70.0f)).SInt128(APInt()));
101 EXPECT_EQ(APInt(128, -1, true) << 70,
102 Scalar(-std::pow(2.0f, 70.0f)).SInt128(APInt()));
103 EXPECT_EQ(APInt(128, 1) << 70,
104 Scalar(std::pow(2.0f, 70.0f)).UInt128(APInt()));
105 EXPECT_EQ(APInt(128, 0), Scalar(-std::pow(2.0f, 70.0f)).UInt128(APInt()));
106
107 EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0, 70.0)).SInt128(APInt()));
108 EXPECT_EQ(APInt(128, -1, true) << 70,
109 Scalar(-std::pow(2.0, 70.0)).SInt128(APInt()));
110 EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0, 70.0)).UInt128(APInt()));
111 EXPECT_EQ(APInt(128, 0), Scalar(-std::pow(2.0, 70.0)).UInt128(APInt()));
112}
113
114TEST(ScalarTest, RightShiftOperator) {
115 int a = 0x00001000;
116 int b = 0xFFFFFFFF;
117 int c = 4;
118 Scalar a_scalar(a);
119 Scalar b_scalar(b);
120 Scalar c_scalar(c);
121 ASSERT_EQ(a >> c, a_scalar >> c_scalar);
122 ASSERT_EQ(b >> c, b_scalar >> c_scalar);
123}
124
125TEST(ScalarTest, GetBytes) {
126 uint8_t Storage[256];
127 int a = 0x01020304;
128 long long b = 0x0102030405060708LL;
129 float c = 1234567.89e32f;
130 double d = 1234567.89e42;
131 char e[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
132 char f[32] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
133 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
134 Scalar a_scalar(a);
135 Scalar b_scalar(b);
136 Scalar c_scalar(c);
137 Scalar d_scalar(d);
138 Scalar e_scalar;
139 Scalar f_scalar;
140 DataExtractor e_data(e, sizeof(e), endian::InlHostByteOrder(),
141 sizeof(void *));
142 DataExtractor f_data(f, sizeof(f), endian::InlHostByteOrder(),
143 sizeof(void *));
144 a_scalar.GetBytes(storage: Storage);
145 ASSERT_EQ(0, memcmp(&a, Storage, sizeof(a)));
146 b_scalar.GetBytes(storage: Storage);
147 ASSERT_EQ(0, memcmp(&b, Storage, sizeof(b)));
148 c_scalar.GetBytes(storage: Storage);
149 ASSERT_EQ(0, memcmp(&c, Storage, sizeof(c)));
150 d_scalar.GetBytes(storage: Storage);
151 ASSERT_EQ(0, memcmp(&d, Storage, sizeof(d)));
152 ASSERT_THAT_ERROR(
153 e_scalar.SetValueFromData(e_data, lldb::eEncodingUint, sizeof(e))
154 .ToError(),
155 llvm::Succeeded());
156 e_scalar.GetBytes(storage: Storage);
157 ASSERT_EQ(0, memcmp(e, Storage, sizeof(e)));
158 ASSERT_THAT_ERROR(
159 f_scalar.SetValueFromData(f_data, lldb::eEncodingUint, sizeof(f))
160 .ToError(),
161 llvm::Succeeded());
162 f_scalar.GetBytes(storage: Storage);
163 ASSERT_EQ(0, memcmp(f, Storage, sizeof(f)));
164}
165
166TEST(ScalarTest, SetValueFromData) {
167 uint8_t a[] = {1, 2, 3, 4};
168 Scalar s;
169 ASSERT_THAT_ERROR(
170 s.SetValueFromData(
171 DataExtractor(a, sizeof(a), lldb::eByteOrderLittle, sizeof(void *)),
172 lldb::eEncodingSint, sizeof(a))
173 .ToError(),
174 llvm::Succeeded());
175 EXPECT_EQ(0x04030201, s);
176 ASSERT_THAT_ERROR(
177 s.SetValueFromData(
178 DataExtractor(a, sizeof(a), lldb::eByteOrderBig, sizeof(void *)),
179 lldb::eEncodingSint, sizeof(a))
180 .ToError(),
181 llvm::Succeeded());
182 EXPECT_EQ(0x01020304, s);
183}
184
185TEST(ScalarTest, CastOperations) {
186 long long a = 0xf1f2f3f4f5f6f7f8LL;
187 Scalar a_scalar(a);
188 EXPECT_EQ((signed char)a, a_scalar.SChar());
189 EXPECT_EQ((unsigned char)a, a_scalar.UChar());
190 EXPECT_EQ((signed short)a, a_scalar.SShort());
191 EXPECT_EQ((unsigned short)a, a_scalar.UShort());
192 EXPECT_EQ((signed int)a, a_scalar.SInt());
193 EXPECT_EQ((unsigned int)a, a_scalar.UInt());
194 EXPECT_EQ((signed long)a, a_scalar.SLong());
195 EXPECT_EQ((unsigned long)a, a_scalar.ULong());
196 EXPECT_EQ((signed long long)a, a_scalar.SLongLong());
197 EXPECT_EQ((unsigned long long)a, a_scalar.ULongLong());
198
199 int a2 = 23;
200 Scalar a2_scalar(a2);
201 EXPECT_EQ((float)a2, a2_scalar.Float());
202 EXPECT_EQ((double)a2, a2_scalar.Double());
203 EXPECT_EQ((long double)a2, a2_scalar.LongDouble());
204
205 EXPECT_EQ(std::numeric_limits<unsigned int>::min(), Scalar(-1.0f).UInt());
206 EXPECT_EQ(std::numeric_limits<unsigned int>::max(), Scalar(1e11f).UInt());
207 EXPECT_EQ(std::numeric_limits<unsigned long long>::min(),
208 Scalar(-1.0).ULongLong());
209 EXPECT_EQ(std::numeric_limits<unsigned long long>::max(),
210 Scalar(1e22).ULongLong());
211
212 EXPECT_EQ(std::numeric_limits<int>::min(), Scalar(-1e11f).SInt());
213 EXPECT_EQ(std::numeric_limits<int>::max(), Scalar(1e11f).SInt());
214 EXPECT_EQ(std::numeric_limits<long long>::min(), Scalar(-1e22).SLongLong());
215 EXPECT_EQ(std::numeric_limits<long long>::max(), Scalar(1e22).SLongLong());
216}
217
218TEST(ScalarTest, ExtractBitfield) {
219 uint32_t len = sizeof(long long) * 8;
220
221 long long a1 = 0xf1f2f3f4f5f6f7f8LL;
222 long long b1 = 0xff1f2f3f4f5f6f7fLL;
223 Scalar s_scalar(a1);
224 ASSERT_TRUE(s_scalar.ExtractBitfield(0, 0));
225 EXPECT_EQ(s_scalar, a1);
226 ASSERT_TRUE(s_scalar.ExtractBitfield(len, 0));
227 EXPECT_EQ(s_scalar, a1);
228 ASSERT_TRUE(s_scalar.ExtractBitfield(len - 4, 4));
229 EXPECT_EQ(s_scalar, b1);
230
231 unsigned long long a2 = 0xf1f2f3f4f5f6f7f8ULL;
232 unsigned long long b2 = 0x0f1f2f3f4f5f6f7fULL;
233 Scalar u_scalar(a2);
234 ASSERT_TRUE(u_scalar.ExtractBitfield(0, 0));
235 EXPECT_EQ(u_scalar, a2);
236 ASSERT_TRUE(u_scalar.ExtractBitfield(len, 0));
237 EXPECT_EQ(u_scalar, a2);
238 ASSERT_TRUE(u_scalar.ExtractBitfield(len - 4, 4));
239 EXPECT_EQ(u_scalar, b2);
240}
241
242template <typename T> static std::string ScalarGetValue(T value) {
243 StreamString stream;
244 Scalar(value).GetValue(s&: stream, show_type: false);
245 return std::string(stream.GetString());
246}
247
248TEST(ScalarTest, GetValue) {
249 EXPECT_EQ("12345", ScalarGetValue<signed short>(12345));
250 EXPECT_EQ("-12345", ScalarGetValue<signed short>(-12345));
251 EXPECT_EQ("12345", ScalarGetValue<unsigned short>(12345));
252 EXPECT_EQ(std::to_string(std::numeric_limits<unsigned short>::max()),
253 ScalarGetValue(std::numeric_limits<unsigned short>::max()));
254
255 EXPECT_EQ("12345", ScalarGetValue<signed int>(12345));
256 EXPECT_EQ("-12345", ScalarGetValue<signed int>(-12345));
257 EXPECT_EQ("12345", ScalarGetValue<unsigned int>(12345));
258 EXPECT_EQ(std::to_string(std::numeric_limits<unsigned int>::max()),
259 ScalarGetValue(std::numeric_limits<unsigned int>::max()));
260
261 EXPECT_EQ("12345678", ScalarGetValue<signed long>(12345678L));
262 EXPECT_EQ("-12345678", ScalarGetValue<signed long>(-12345678L));
263 EXPECT_EQ("12345678", ScalarGetValue<unsigned long>(12345678UL));
264 EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long>::max()),
265 ScalarGetValue(std::numeric_limits<unsigned long>::max()));
266
267 EXPECT_EQ("1234567890123", ScalarGetValue<signed long long>(1234567890123LL));
268 EXPECT_EQ("-1234567890123",
269 ScalarGetValue<signed long long>(-1234567890123LL));
270 EXPECT_EQ("1234567890123",
271 ScalarGetValue<unsigned long long>(1234567890123ULL));
272 EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long long>::max()),
273 ScalarGetValue(std::numeric_limits<unsigned long long>::max()));
274}
275
276TEST(ScalarTest, LongLongAssigmentOperator) {
277 Scalar ull;
278 ull = std::numeric_limits<unsigned long long>::max();
279 EXPECT_EQ(std::numeric_limits<unsigned long long>::max(), ull.ULongLong());
280
281 Scalar sll;
282 sll = std::numeric_limits<signed long long>::max();
283 EXPECT_EQ(std::numeric_limits<signed long long>::max(), sll.SLongLong());
284}
285
286TEST(ScalarTest, Division) {
287 Scalar lhs(5.0);
288 Scalar rhs(2.0);
289 Scalar r = lhs / rhs;
290 EXPECT_TRUE(r.IsValid());
291 EXPECT_EQ(r, Scalar(2.5));
292}
293
294TEST(ScalarTest, Promotion) {
295 Scalar a(47);
296 EXPECT_TRUE(a.IntegralPromote(64, true));
297 EXPECT_TRUE(a.IsSigned());
298 EXPECT_EQ(APInt(64, 47), a.UInt128(APInt()));
299
300 EXPECT_FALSE(a.IntegralPromote(32, true));
301 EXPECT_FALSE(a.IntegralPromote(32, false));
302 EXPECT_TRUE(a.IsSigned());
303
304 EXPECT_TRUE(a.IntegralPromote(64, false));
305 EXPECT_FALSE(a.IsSigned());
306 EXPECT_EQ(APInt(64, 47), a.UInt128(APInt()));
307
308 EXPECT_FALSE(a.IntegralPromote(64, true));
309
310 EXPECT_TRUE(a.FloatPromote(APFloat::IEEEdouble()));
311 EXPECT_EQ(Scalar::e_float, a.GetType());
312 EXPECT_EQ(47.0, a.Double());
313
314 EXPECT_FALSE(a.FloatPromote(APFloat::IEEEsingle()));
315 EXPECT_TRUE(a.FloatPromote(APFloat::x87DoubleExtended()));
316 EXPECT_EQ(47.0L, a.LongDouble());
317}
318
319TEST(ScalarTest, SetValueFromCString) {
320 Scalar a;
321
322 EXPECT_THAT_ERROR(
323 a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 8).ToError(),
324 Succeeded());
325 EXPECT_EQ(1234567890123ull, a);
326
327 EXPECT_THAT_ERROR(
328 a.SetValueFromCString("-1234567890123", lldb::eEncodingSint, 8).ToError(),
329 Succeeded());
330 EXPECT_EQ(-1234567890123ll, a);
331
332 EXPECT_THAT_ERROR(
333 a.SetValueFromCString("asdf", lldb::eEncodingSint, 8).ToError(),
334 Failed());
335 EXPECT_THAT_ERROR(
336 a.SetValueFromCString("asdf", lldb::eEncodingUint, 8).ToError(),
337 Failed());
338 EXPECT_THAT_ERROR(
339 a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 4).ToError(),
340 Failed());
341 EXPECT_THAT_ERROR(a.SetValueFromCString("123456789012345678901234567890",
342 lldb::eEncodingUint, 8)
343 .ToError(),
344 Failed());
345 EXPECT_THAT_ERROR(
346 a.SetValueFromCString("-123", lldb::eEncodingUint, 8).ToError(),
347 Failed());
348 EXPECT_THAT_ERROR(
349 a.SetValueFromCString("-2147483648", lldb::eEncodingSint, 4).ToError(),
350 Succeeded());
351 EXPECT_EQ(-2147483648, a);
352 EXPECT_THAT_ERROR(
353 a.SetValueFromCString("-2147483649", lldb::eEncodingSint, 4).ToError(),
354 Failed());
355 EXPECT_THAT_ERROR(
356 a.SetValueFromCString("47.25", lldb::eEncodingIEEE754, 4).ToError(),
357 Succeeded());
358 EXPECT_EQ(47.25f, a);
359 EXPECT_THAT_ERROR(
360 a.SetValueFromCString("asdf", lldb::eEncodingIEEE754, 4).ToError(),
361 Failed());
362}
363
364TEST(ScalarTest, APIntConstructor) {
365 for (auto &width : {8, 16, 32}) {
366 Scalar A(APInt(width, 24));
367 EXPECT_TRUE(A.IsSigned());
368 EXPECT_EQ(A.GetType(), Scalar::e_int);
369 EXPECT_EQ(APInt(width, 24), A.UInt128(APInt()));
370 }
371}
372
373TEST(ScalarTest, Scalar_512) {
374 Scalar Z(APInt(512, 0));
375 ASSERT_TRUE(Z.IsZero());
376 Z.MakeUnsigned();
377 ASSERT_TRUE(Z.IsZero());
378
379 Scalar S(APInt(512, 2000));
380 ASSERT_STREQ(S.GetTypeAsCString(), "int");
381
382 ASSERT_TRUE(S.MakeUnsigned());
383 EXPECT_EQ(S.GetType(), Scalar::e_int);
384 EXPECT_FALSE(S.IsSigned());
385 ASSERT_STREQ(S.GetTypeAsCString(), "int");
386 EXPECT_EQ(S.GetByteSize(), 64U);
387
388 ASSERT_TRUE(S.MakeSigned());
389 EXPECT_EQ(S.GetType(), Scalar::e_int);
390 EXPECT_TRUE(S.IsSigned());
391 EXPECT_EQ(S.GetByteSize(), 64U);
392}
393
394TEST(ScalarTest, TruncOrExtendTo) {
395 Scalar S(0xffff);
396 S.TruncOrExtendTo(bits: 12, sign: true);
397 EXPECT_EQ(S.UInt128(APInt()), APInt(12, 0xfffu));
398 S.TruncOrExtendTo(bits: 20, sign: true);
399 EXPECT_EQ(S.UInt128(APInt()), APInt(20, 0xfffffu));
400 S.TruncOrExtendTo(bits: 24, sign: false);
401 EXPECT_EQ(S.UInt128(APInt()), APInt(24, 0x0fffffu));
402 S.TruncOrExtendTo(bits: 16, sign: false);
403 EXPECT_EQ(S.UInt128(APInt()), APInt(16, 0xffffu));
404}
405
406TEST(ScalarTest, APFloatConstructor) {
407 llvm::APFloat my_single(llvm::APFloatBase::IEEEsingle(), "3.14159");
408 llvm::APFloat my_double(llvm::APFloatBase::IEEEdouble(), "3.14159");
409 Scalar S(my_single);
410 Scalar D(my_double);
411
412 EXPECT_EQ(S.GetType(), Scalar::e_float);
413 EXPECT_EQ(D.GetType(), Scalar::e_float);
414 ASSERT_TRUE(S != D);
415}
416
417TEST(ScalarTest, CreateAPFloats) {
418 llvm::APFloat ap_float(llvm::APFloatBase::IEEEsingle(), "3.14159");
419 llvm::APFloat ap_nan = llvm::APFloat::getNaN(Sem: llvm::APFloat::IEEEsingle());
420 llvm::APSInt int1("12");
421 llvm::APSInt int2("-4");
422 Scalar I1(int1);
423 Scalar I2(int2);
424 Scalar F(ap_float);
425
426 llvm::APFloat out1_float = I1.CreateAPFloatFromAPSInt(basic_type: lldb::eBasicTypeFloat);
427 llvm::APFloat out1_double =
428 I1.CreateAPFloatFromAPSInt(basic_type: lldb::eBasicTypeDouble);
429 llvm::APFloat out1_longdouble =
430 I1.CreateAPFloatFromAPSInt(basic_type: lldb::eBasicTypeLongDouble);
431 llvm::APFloat out1_nan =
432 I1.CreateAPFloatFromAPSInt(basic_type: lldb::eBasicTypeFloatComplex);
433 EXPECT_TRUE(!out1_float.isNegative());
434 EXPECT_TRUE(!out1_double.isNegative());
435 EXPECT_TRUE(out1_double.bitwiseIsEqual(out1_longdouble));
436 EXPECT_FALSE(out1_double.bitwiseIsEqual(out1_float));
437 EXPECT_TRUE(out1_nan.bitwiseIsEqual(ap_nan));
438
439 llvm::APFloat out2_float = I2.CreateAPFloatFromAPSInt(basic_type: lldb::eBasicTypeFloat);
440 llvm::APFloat out2_double =
441 I2.CreateAPFloatFromAPSInt(basic_type: lldb::eBasicTypeDouble);
442 llvm::APFloat out2_longdouble =
443 I2.CreateAPFloatFromAPSInt(basic_type: lldb::eBasicTypeLongDouble);
444 llvm::APFloat out2_nan =
445 I2.CreateAPFloatFromAPSInt(basic_type: lldb::eBasicTypeFloatComplex);
446 EXPECT_TRUE(out2_float.isNegative());
447 EXPECT_TRUE(out2_double.isNegative());
448 EXPECT_TRUE(out2_double.bitwiseIsEqual(out2_longdouble));
449 EXPECT_FALSE(out2_double.bitwiseIsEqual(out2_float));
450 EXPECT_TRUE(out2_nan.bitwiseIsEqual(ap_nan));
451
452 llvm::APFloat out3_float = F.CreateAPFloatFromAPFloat(basic_type: lldb::eBasicTypeFloat);
453 llvm::APFloat out3_double =
454 F.CreateAPFloatFromAPFloat(basic_type: lldb::eBasicTypeDouble);
455 llvm::APFloat out3_longdouble =
456 F.CreateAPFloatFromAPFloat(basic_type: lldb::eBasicTypeLongDouble);
457 llvm::APFloat out3_nan =
458 F.CreateAPFloatFromAPFloat(basic_type: lldb::eBasicTypeFloatComplex);
459 EXPECT_TRUE(out3_double.bitwiseIsEqual(out3_longdouble));
460 EXPECT_FALSE(out3_double.bitwiseIsEqual(out3_float));
461 EXPECT_TRUE(out3_nan.bitwiseIsEqual(ap_nan));
462}
463

source code of lldb/unittests/Utility/ScalarTest.cpp