1 //===-- ScalarTest.cpp ----------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "gtest/gtest.h"
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 "lldb/lldb-enumerations.h"
17 #include "llvm/ADT/APSInt.h"
18 #include "llvm/Testing/Support/Error.h"
23 using namespace lldb_private
;
27 using llvm::Succeeded
;
30 bool checkInequality(T c1
, T c2
) {
31 return (Scalar(c1
) != Scalar(c2
));
35 bool checkEquality(T c1
, T c2
) {
36 return (Scalar(c1
) == Scalar(c2
));
39 TEST(ScalarTest
, Equality
) {
40 ASSERT_TRUE(checkInequality
<int>(23, 24));
41 ASSERT_TRUE(checkEquality
<int>(96, 96));
42 ASSERT_TRUE(checkInequality
<float>(4.0f
, 4.5f
));
43 ASSERT_TRUE(checkEquality
<float>(4.0f
, 4.0f
));
45 auto apint1
= APInt(64, 234);
46 auto apint2
= APInt(64, 246);
47 ASSERT_TRUE(checkInequality
<APInt
>(apint1
, apint2
));
48 ASSERT_TRUE(checkEquality
<APInt
>(apint1
, apint1
));
53 ASSERT_TRUE(void1
== void2
);
54 ASSERT_FALSE(void1
== Scalar(f1
));
57 TEST(ScalarTest
, Comparison
) {
61 ASSERT_TRUE(s1
<= s2
);
63 ASSERT_TRUE(s2
>= s1
);
66 TEST(ScalarTest
, ComparisonFloat
) {
67 auto s1
= Scalar(23.0f
);
68 auto s2
= Scalar(46.0f
);
70 ASSERT_TRUE(s1
<= s2
);
72 ASSERT_TRUE(s2
>= s1
);
75 template <typename T
> static void CheckConversion(T val
) {
76 SCOPED_TRACE("val = " + std::to_string(val
));
77 EXPECT_EQ((signed char)val
, Scalar(val
).SChar());
78 EXPECT_EQ((unsigned char)val
, Scalar(val
).UChar());
79 EXPECT_EQ((short)val
, Scalar(val
).SShort());
80 EXPECT_EQ((unsigned short)val
, Scalar(val
).UShort());
81 EXPECT_EQ((int)val
, Scalar(val
).SInt());
82 EXPECT_EQ((unsigned)val
, Scalar(val
).UInt());
83 EXPECT_EQ((long)val
, Scalar(val
).SLong());
84 EXPECT_EQ((unsigned long)val
, Scalar(val
).ULong());
85 EXPECT_EQ((long long)val
, Scalar(val
).SLongLong());
86 EXPECT_EQ((unsigned long long)val
, Scalar(val
).ULongLong());
87 EXPECT_NEAR((float)val
, Scalar(val
).Float(), std::abs(val
/ 1e6
));
88 EXPECT_NEAR((double)val
, Scalar(val
).Double(), std::abs(val
/ 1e12
));
89 EXPECT_NEAR((long double)val
, Scalar(val
).LongDouble(), std::abs(val
/ 1e12
));
92 TEST(ScalarTest
, Getters
) {
93 CheckConversion
<int>(0x87654321);
94 CheckConversion
<unsigned int>(0x87654321u
);
95 CheckConversion
<long>(0x87654321l
);
96 CheckConversion
<unsigned long>(0x87654321ul
);
97 CheckConversion
<long long>(0x8765432112345678ll
);
98 CheckConversion
<unsigned long long>(0x8765432112345678ull
);
99 CheckConversion
<float>(42.25f
);
100 CheckConversion
<double>(42.25);
101 CheckConversion
<long double>(42.25L);
103 EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0f
, 70.0f
)).SInt128(APInt()));
104 EXPECT_EQ(APInt(128, -1, true) << 70,
105 Scalar(-std::pow(2.0f
, 70.0f
)).SInt128(APInt()));
106 EXPECT_EQ(APInt(128, 1) << 70,
107 Scalar(std::pow(2.0f
, 70.0f
)).UInt128(APInt()));
108 EXPECT_EQ(APInt(128, 0), Scalar(-std::pow(2.0f
, 70.0f
)).UInt128(APInt()));
110 EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0, 70.0)).SInt128(APInt()));
111 EXPECT_EQ(APInt(128, -1, true) << 70,
112 Scalar(-std::pow(2.0, 70.0)).SInt128(APInt()));
113 EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0, 70.0)).UInt128(APInt()));
114 EXPECT_EQ(APInt(128, 0), Scalar(-std::pow(2.0, 70.0)).UInt128(APInt()));
117 TEST(ScalarTest
, RightShiftOperator
) {
124 ASSERT_EQ(a
>> c
, a_scalar
>> c_scalar
);
125 ASSERT_EQ(b
>> c
, b_scalar
>> c_scalar
);
128 TEST(ScalarTest
, GetBytes
) {
129 uint8_t Storage
[256];
131 long long b
= 0x0102030405060708LL
;
132 float c
= 1234567.89e32f
;
133 double d
= 1234567.89e42
;
134 char e
[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
135 char f
[32] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
136 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
143 DataExtractor
e_data(e
, sizeof(e
), endian::InlHostByteOrder(),
145 DataExtractor
f_data(f
, sizeof(f
), endian::InlHostByteOrder(),
147 a_scalar
.GetBytes(Storage
);
148 ASSERT_EQ(0, memcmp(&a
, Storage
, sizeof(a
)));
149 b_scalar
.GetBytes(Storage
);
150 ASSERT_EQ(0, memcmp(&b
, Storage
, sizeof(b
)));
151 c_scalar
.GetBytes(Storage
);
152 ASSERT_EQ(0, memcmp(&c
, Storage
, sizeof(c
)));
153 d_scalar
.GetBytes(Storage
);
154 ASSERT_EQ(0, memcmp(&d
, Storage
, sizeof(d
)));
156 e_scalar
.SetValueFromData(e_data
, lldb::eEncodingUint
, sizeof(e
))
159 e_scalar
.GetBytes(Storage
);
160 ASSERT_EQ(0, memcmp(e
, Storage
, sizeof(e
)));
162 f_scalar
.SetValueFromData(f_data
, lldb::eEncodingUint
, sizeof(f
))
165 f_scalar
.GetBytes(Storage
);
166 ASSERT_EQ(0, memcmp(f
, Storage
, sizeof(f
)));
169 TEST(ScalarTest
, GetData
) {
170 auto get_data
= [](llvm::APSInt v
) {
172 Scalar(v
).GetData(data
);
173 return data
.GetData().vec();
176 auto vec
= [](std::initializer_list
<uint8_t> l
) {
177 std::vector
<uint8_t> v(l
.begin(), l
.end());
178 if (endian::InlHostByteOrder() == lldb::eByteOrderLittle
)
179 std::reverse(v
.begin(), v
.end());
184 get_data(llvm::APSInt::getMaxValue(/*numBits=*/1, /*Unsigned=*/true)),
188 get_data(llvm::APSInt::getMaxValue(/*numBits=*/8, /*Unsigned=*/true)),
192 get_data(llvm::APSInt::getMaxValue(/*numBits=*/9, /*Unsigned=*/true)),
196 TEST(ScalarTest
, SetValueFromData
) {
197 uint8_t a
[] = {1, 2, 3, 4};
201 DataExtractor(a
, sizeof(a
), lldb::eByteOrderLittle
, sizeof(void *)),
202 lldb::eEncodingSint
, sizeof(a
))
205 EXPECT_EQ(0x04030201, s
);
208 DataExtractor(a
, sizeof(a
), lldb::eByteOrderBig
, sizeof(void *)),
209 lldb::eEncodingSint
, sizeof(a
))
212 EXPECT_EQ(0x01020304, s
);
215 TEST(ScalarTest
, CastOperations
) {
216 long long a
= 0xf1f2f3f4f5f6f7f8LL
;
218 EXPECT_EQ((signed char)a
, a_scalar
.SChar());
219 EXPECT_EQ((unsigned char)a
, a_scalar
.UChar());
220 EXPECT_EQ((signed short)a
, a_scalar
.SShort());
221 EXPECT_EQ((unsigned short)a
, a_scalar
.UShort());
222 EXPECT_EQ((signed int)a
, a_scalar
.SInt());
223 EXPECT_EQ((unsigned int)a
, a_scalar
.UInt());
224 EXPECT_EQ((signed long)a
, a_scalar
.SLong());
225 EXPECT_EQ((unsigned long)a
, a_scalar
.ULong());
226 EXPECT_EQ((signed long long)a
, a_scalar
.SLongLong());
227 EXPECT_EQ((unsigned long long)a
, a_scalar
.ULongLong());
230 Scalar
a2_scalar(a2
);
231 EXPECT_EQ((float)a2
, a2_scalar
.Float());
232 EXPECT_EQ((double)a2
, a2_scalar
.Double());
233 EXPECT_EQ((long double)a2
, a2_scalar
.LongDouble());
235 EXPECT_EQ(std::numeric_limits
<unsigned int>::min(), Scalar(-1.0f
).UInt());
236 EXPECT_EQ(std::numeric_limits
<unsigned int>::max(), Scalar(1e11f
).UInt());
237 EXPECT_EQ(std::numeric_limits
<unsigned long long>::min(),
238 Scalar(-1.0).ULongLong());
239 EXPECT_EQ(std::numeric_limits
<unsigned long long>::max(),
240 Scalar(1e22
).ULongLong());
242 EXPECT_EQ(std::numeric_limits
<int>::min(), Scalar(-1e11f
).SInt());
243 EXPECT_EQ(std::numeric_limits
<int>::max(), Scalar(1e11f
).SInt());
244 EXPECT_EQ(std::numeric_limits
<long long>::min(), Scalar(-1e22
).SLongLong());
245 EXPECT_EQ(std::numeric_limits
<long long>::max(), Scalar(1e22
).SLongLong());
248 TEST(ScalarTest
, ExtractBitfield
) {
249 uint32_t len
= sizeof(long long) * 8;
251 long long a1
= 0xf1f2f3f4f5f6f7f8LL
;
252 long long b1
= 0xff1f2f3f4f5f6f7fLL
;
254 ASSERT_TRUE(s_scalar
.ExtractBitfield(0, 0));
255 EXPECT_EQ(s_scalar
, a1
);
256 ASSERT_TRUE(s_scalar
.ExtractBitfield(len
, 0));
257 EXPECT_EQ(s_scalar
, a1
);
258 ASSERT_TRUE(s_scalar
.ExtractBitfield(len
- 4, 4));
259 EXPECT_EQ(s_scalar
, b1
);
261 unsigned long long a2
= 0xf1f2f3f4f5f6f7f8ULL
;
262 unsigned long long b2
= 0x0f1f2f3f4f5f6f7fULL
;
264 ASSERT_TRUE(u_scalar
.ExtractBitfield(0, 0));
265 EXPECT_EQ(u_scalar
, a2
);
266 ASSERT_TRUE(u_scalar
.ExtractBitfield(len
, 0));
267 EXPECT_EQ(u_scalar
, a2
);
268 ASSERT_TRUE(u_scalar
.ExtractBitfield(len
- 4, 4));
269 EXPECT_EQ(u_scalar
, b2
);
272 template <typename T
> static std::string
ScalarGetValue(T value
) {
274 Scalar(value
).GetValue(stream
, false);
275 return std::string(stream
.GetString());
278 TEST(ScalarTest
, GetValue
) {
279 EXPECT_EQ("12345", ScalarGetValue
<signed short>(12345));
280 EXPECT_EQ("-12345", ScalarGetValue
<signed short>(-12345));
281 EXPECT_EQ("12345", ScalarGetValue
<unsigned short>(12345));
282 EXPECT_EQ(std::to_string(std::numeric_limits
<unsigned short>::max()),
283 ScalarGetValue(std::numeric_limits
<unsigned short>::max()));
285 EXPECT_EQ("12345", ScalarGetValue
<signed int>(12345));
286 EXPECT_EQ("-12345", ScalarGetValue
<signed int>(-12345));
287 EXPECT_EQ("12345", ScalarGetValue
<unsigned int>(12345));
288 EXPECT_EQ(std::to_string(std::numeric_limits
<unsigned int>::max()),
289 ScalarGetValue(std::numeric_limits
<unsigned int>::max()));
291 EXPECT_EQ("12345678", ScalarGetValue
<signed long>(12345678L));
292 EXPECT_EQ("-12345678", ScalarGetValue
<signed long>(-12345678L));
293 EXPECT_EQ("12345678", ScalarGetValue
<unsigned long>(12345678UL));
294 EXPECT_EQ(std::to_string(std::numeric_limits
<unsigned long>::max()),
295 ScalarGetValue(std::numeric_limits
<unsigned long>::max()));
297 EXPECT_EQ("1234567890123", ScalarGetValue
<signed long long>(1234567890123LL));
298 EXPECT_EQ("-1234567890123",
299 ScalarGetValue
<signed long long>(-1234567890123LL));
300 EXPECT_EQ("1234567890123",
301 ScalarGetValue
<unsigned long long>(1234567890123ULL));
302 EXPECT_EQ(std::to_string(std::numeric_limits
<unsigned long long>::max()),
303 ScalarGetValue(std::numeric_limits
<unsigned long long>::max()));
306 TEST(ScalarTest
, LongLongAssigmentOperator
) {
308 ull
= std::numeric_limits
<unsigned long long>::max();
309 EXPECT_EQ(std::numeric_limits
<unsigned long long>::max(), ull
.ULongLong());
312 sll
= std::numeric_limits
<signed long long>::max();
313 EXPECT_EQ(std::numeric_limits
<signed long long>::max(), sll
.SLongLong());
316 TEST(ScalarTest
, Division
) {
319 Scalar r
= lhs
/ rhs
;
320 EXPECT_TRUE(r
.IsValid());
321 EXPECT_EQ(r
, Scalar(2.5));
324 TEST(ScalarTest
, Promotion
) {
326 EXPECT_TRUE(a
.IntegralPromote(64, true));
327 EXPECT_TRUE(a
.IsSigned());
328 EXPECT_EQ(APInt(64, 47), a
.UInt128(APInt()));
330 EXPECT_FALSE(a
.IntegralPromote(32, true));
331 EXPECT_FALSE(a
.IntegralPromote(32, false));
332 EXPECT_TRUE(a
.IsSigned());
334 EXPECT_TRUE(a
.IntegralPromote(64, false));
335 EXPECT_FALSE(a
.IsSigned());
336 EXPECT_EQ(APInt(64, 47), a
.UInt128(APInt()));
338 EXPECT_FALSE(a
.IntegralPromote(64, true));
340 EXPECT_TRUE(a
.FloatPromote(APFloat::IEEEdouble()));
341 EXPECT_EQ(Scalar::e_float
, a
.GetType());
342 EXPECT_EQ(47.0, a
.Double());
344 EXPECT_FALSE(a
.FloatPromote(APFloat::IEEEsingle()));
345 EXPECT_TRUE(a
.FloatPromote(APFloat::x87DoubleExtended()));
346 EXPECT_EQ(47.0L, a
.LongDouble());
349 TEST(ScalarTest
, SetValueFromCString
) {
353 a
.SetValueFromCString("1234567890123", lldb::eEncodingUint
, 8).ToError(),
355 EXPECT_EQ(1234567890123ull, a
);
358 a
.SetValueFromCString("-1234567890123", lldb::eEncodingSint
, 8).ToError(),
360 EXPECT_EQ(-1234567890123ll, a
);
363 a
.SetValueFromCString("asdf", lldb::eEncodingSint
, 8).ToError(),
366 a
.SetValueFromCString("asdf", lldb::eEncodingUint
, 8).ToError(),
369 a
.SetValueFromCString("1234567890123", lldb::eEncodingUint
, 4).ToError(),
371 EXPECT_THAT_ERROR(a
.SetValueFromCString("123456789012345678901234567890",
372 lldb::eEncodingUint
, 8)
376 a
.SetValueFromCString("-123", lldb::eEncodingUint
, 8).ToError(),
379 a
.SetValueFromCString("-2147483648", lldb::eEncodingSint
, 4).ToError(),
381 EXPECT_EQ(-2147483648, a
);
383 a
.SetValueFromCString("-2147483649", lldb::eEncodingSint
, 4).ToError(),
386 a
.SetValueFromCString("47.25", lldb::eEncodingIEEE754
, 4).ToError(),
388 EXPECT_EQ(47.25f
, a
);
390 a
.SetValueFromCString("asdf", lldb::eEncodingIEEE754
, 4).ToError(),
394 TEST(ScalarTest
, APIntConstructor
) {
395 for (auto &width
: {8, 16, 32}) {
396 Scalar
A(APInt(width
, 24));
397 EXPECT_TRUE(A
.IsSigned());
398 EXPECT_EQ(A
.GetType(), Scalar::e_int
);
399 EXPECT_EQ(APInt(width
, 24), A
.UInt128(APInt()));
403 TEST(ScalarTest
, Scalar_512
) {
404 Scalar
Z(APInt(512, 0));
405 ASSERT_TRUE(Z
.IsZero());
407 ASSERT_TRUE(Z
.IsZero());
409 Scalar
S(APInt(512, 2000));
410 ASSERT_STREQ(S
.GetTypeAsCString(), "int");
412 ASSERT_TRUE(S
.MakeUnsigned());
413 EXPECT_EQ(S
.GetType(), Scalar::e_int
);
414 EXPECT_FALSE(S
.IsSigned());
415 ASSERT_STREQ(S
.GetTypeAsCString(), "int");
416 EXPECT_EQ(S
.GetByteSize(), 64U);
418 ASSERT_TRUE(S
.MakeSigned());
419 EXPECT_EQ(S
.GetType(), Scalar::e_int
);
420 EXPECT_TRUE(S
.IsSigned());
421 EXPECT_EQ(S
.GetByteSize(), 64U);
424 TEST(ScalarTest
, TruncOrExtendTo
) {
426 S
.TruncOrExtendTo(12, true);
427 EXPECT_EQ(S
.UInt128(APInt()), APInt(12, 0xfffu
));
428 S
.TruncOrExtendTo(20, true);
429 EXPECT_EQ(S
.UInt128(APInt()), APInt(20, 0xfffffu
));
430 S
.TruncOrExtendTo(24, false);
431 EXPECT_EQ(S
.UInt128(APInt()), APInt(24, 0x0fffffu
));
432 S
.TruncOrExtendTo(16, false);
433 EXPECT_EQ(S
.UInt128(APInt()), APInt(16, 0xffffu
));
436 TEST(ScalarTest
, APFloatConstructor
) {
437 llvm::APFloat
my_single(llvm::APFloatBase::IEEEsingle(), "3.14159");
438 llvm::APFloat
my_double(llvm::APFloatBase::IEEEdouble(), "3.14159");
442 EXPECT_EQ(S
.GetType(), Scalar::e_float
);
443 EXPECT_EQ(D
.GetType(), Scalar::e_float
);
447 TEST(ScalarTest
, CreateAPFloats
) {
448 llvm::APFloat
ap_float(llvm::APFloatBase::IEEEsingle(), "3.14159");
449 llvm::APFloat ap_nan
= llvm::APFloat::getNaN(llvm::APFloat::IEEEsingle());
450 llvm::APSInt
int1("12");
451 llvm::APSInt
int2("-4");
456 llvm::APFloat out1_float
= I1
.CreateAPFloatFromAPSInt(lldb::eBasicTypeFloat
);
457 llvm::APFloat out1_double
=
458 I1
.CreateAPFloatFromAPSInt(lldb::eBasicTypeDouble
);
459 llvm::APFloat out1_longdouble
=
460 I1
.CreateAPFloatFromAPSInt(lldb::eBasicTypeLongDouble
);
461 llvm::APFloat out1_nan
=
462 I1
.CreateAPFloatFromAPSInt(lldb::eBasicTypeFloatComplex
);
463 EXPECT_TRUE(!out1_float
.isNegative());
464 EXPECT_TRUE(!out1_double
.isNegative());
465 EXPECT_TRUE(out1_double
.bitwiseIsEqual(out1_longdouble
));
466 EXPECT_FALSE(out1_double
.bitwiseIsEqual(out1_float
));
467 EXPECT_TRUE(out1_nan
.bitwiseIsEqual(ap_nan
));
469 llvm::APFloat out2_float
= I2
.CreateAPFloatFromAPSInt(lldb::eBasicTypeFloat
);
470 llvm::APFloat out2_double
=
471 I2
.CreateAPFloatFromAPSInt(lldb::eBasicTypeDouble
);
472 llvm::APFloat out2_longdouble
=
473 I2
.CreateAPFloatFromAPSInt(lldb::eBasicTypeLongDouble
);
474 llvm::APFloat out2_nan
=
475 I2
.CreateAPFloatFromAPSInt(lldb::eBasicTypeFloatComplex
);
476 EXPECT_TRUE(out2_float
.isNegative());
477 EXPECT_TRUE(out2_double
.isNegative());
478 EXPECT_TRUE(out2_double
.bitwiseIsEqual(out2_longdouble
));
479 EXPECT_FALSE(out2_double
.bitwiseIsEqual(out2_float
));
480 EXPECT_TRUE(out2_nan
.bitwiseIsEqual(ap_nan
));
482 llvm::APFloat out3_float
= F
.CreateAPFloatFromAPFloat(lldb::eBasicTypeFloat
);
483 llvm::APFloat out3_double
=
484 F
.CreateAPFloatFromAPFloat(lldb::eBasicTypeDouble
);
485 llvm::APFloat out3_longdouble
=
486 F
.CreateAPFloatFromAPFloat(lldb::eBasicTypeLongDouble
);
487 llvm::APFloat out3_nan
=
488 F
.CreateAPFloatFromAPFloat(lldb::eBasicTypeFloatComplex
);
489 EXPECT_TRUE(out3_double
.bitwiseIsEqual(out3_longdouble
));
490 EXPECT_FALSE(out3_double
.bitwiseIsEqual(out3_float
));
491 EXPECT_TRUE(out3_nan
.bitwiseIsEqual(ap_nan
));