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 using namespace lldb_private;
19 using llvm::APInt;
20 using llvm::Failed;
21 using llvm::Succeeded;
22 
23 template <typename T>
24 bool checkInequality(T c1, T c2) {
25   return (Scalar(c1) != Scalar(c2));
26 }
27 
28 template <typename T>
29 bool checkEquality(T c1, T c2) {
30   return (Scalar(c1) == Scalar(c2));
31 }
32 
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 
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 
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 
69 template <typename T> static void CheckConversion(T val) {
70   SCOPED_TRACE("val = " + std::to_string(val));
71   EXPECT_EQ((signed char)val, Scalar(val).SChar());
72   EXPECT_EQ((unsigned char)val, Scalar(val).UChar());
73   EXPECT_EQ((short)val, Scalar(val).SShort());
74   EXPECT_EQ((unsigned short)val, Scalar(val).UShort());
75   EXPECT_EQ((int)val, Scalar(val).SInt());
76   EXPECT_EQ((unsigned)val, Scalar(val).UInt());
77   EXPECT_EQ((long)val, Scalar(val).SLong());
78   EXPECT_EQ((unsigned long)val, Scalar(val).ULong());
79   EXPECT_EQ((long long)val, Scalar(val).SLongLong());
80   EXPECT_EQ((unsigned long long)val, Scalar(val).ULongLong());
81   EXPECT_NEAR((float)val, Scalar(val).Float(), std::abs(val / 1e6));
82   EXPECT_NEAR((double)val, Scalar(val).Double(), std::abs(val / 1e12));
83   EXPECT_NEAR((long double)val, Scalar(val).LongDouble(), std::abs(val / 1e12));
84 }
85 
86 TEST(ScalarTest, Getters) {
87   CheckConversion<int>(0x87654321);
88   CheckConversion<unsigned int>(0x87654321u);
89   CheckConversion<long>(0x87654321l);
90   CheckConversion<unsigned long>(0x87654321ul);
91   CheckConversion<long long>(0x8765432112345678ll);
92   CheckConversion<unsigned long long>(0x8765432112345678ull);
93   CheckConversion<float>(42.25f);
94   CheckConversion<double>(42.25);
95 
96   EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0f, 70.0f)).SInt128(APInt()));
97   EXPECT_EQ(APInt(128, -1, true) << 70,
98             Scalar(-std::pow(2.0f, 70.0f)).SInt128(APInt()));
99   EXPECT_EQ(APInt(128, 1) << 70,
100             Scalar(std::pow(2.0f, 70.0f)).UInt128(APInt()));
101   EXPECT_EQ(APInt(128, 0), Scalar(-std::pow(2.0f, 70.0f)).UInt128(APInt()));
102 
103   EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0, 70.0)).SInt128(APInt()));
104   EXPECT_EQ(APInt(128, -1, true) << 70,
105             Scalar(-std::pow(2.0, 70.0)).SInt128(APInt()));
106   EXPECT_EQ(APInt(128, 1) << 70, Scalar(std::pow(2.0, 70.0)).UInt128(APInt()));
107   EXPECT_EQ(APInt(128, 0), Scalar(-std::pow(2.0, 70.0)).UInt128(APInt()));
108 }
109 
110 TEST(ScalarTest, RightShiftOperator) {
111   int a = 0x00001000;
112   int b = 0xFFFFFFFF;
113   int c = 4;
114   Scalar a_scalar(a);
115   Scalar b_scalar(b);
116   Scalar c_scalar(c);
117   ASSERT_EQ(a >> c, a_scalar >> c_scalar);
118   ASSERT_EQ(b >> c, b_scalar >> c_scalar);
119 }
120 
121 TEST(ScalarTest, GetBytes) {
122   uint8_t Storage[256];
123   int a = 0x01020304;
124   long long b = 0x0102030405060708LL;
125   float c = 1234567.89e32f;
126   double d = 1234567.89e42;
127   char e[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
128   char f[32] = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16,
129                 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
130   Scalar a_scalar(a);
131   Scalar b_scalar(b);
132   Scalar c_scalar(c);
133   Scalar d_scalar(d);
134   Scalar e_scalar;
135   Scalar f_scalar;
136   DataExtractor e_data(e, sizeof(e), endian::InlHostByteOrder(),
137                        sizeof(void *));
138   Status e_error =
139       e_scalar.SetValueFromData(e_data, lldb::eEncodingUint, sizeof(e));
140   DataExtractor f_data(f, sizeof(f), endian::InlHostByteOrder(),
141                        sizeof(void *));
142   Status f_error =
143       f_scalar.SetValueFromData(f_data, lldb::eEncodingUint, sizeof(f));
144   a_scalar.GetBytes(Storage);
145   ASSERT_EQ(0, memcmp(&a, Storage, sizeof(a)));
146   b_scalar.GetBytes(Storage);
147   ASSERT_EQ(0, memcmp(&b, Storage, sizeof(b)));
148   c_scalar.GetBytes(Storage);
149   ASSERT_EQ(0, memcmp(&c, Storage, sizeof(c)));
150   d_scalar.GetBytes(Storage);
151   ASSERT_EQ(0, memcmp(&d, Storage, sizeof(d)));
152   ASSERT_EQ(0, e_error.Fail());
153   e_scalar.GetBytes(Storage);
154   ASSERT_EQ(0, memcmp(e, Storage, sizeof(e)));
155   ASSERT_EQ(0, f_error.Fail());
156   f_scalar.GetBytes(Storage);
157   ASSERT_EQ(0, memcmp(f, Storage, sizeof(f)));
158 }
159 
160 TEST(ScalarTest, CastOperations) {
161   long long a = 0xf1f2f3f4f5f6f7f8LL;
162   Scalar a_scalar(a);
163   EXPECT_EQ((signed char)a, a_scalar.SChar());
164   EXPECT_EQ((unsigned char)a, a_scalar.UChar());
165   EXPECT_EQ((signed short)a, a_scalar.SShort());
166   EXPECT_EQ((unsigned short)a, a_scalar.UShort());
167   EXPECT_EQ((signed int)a, a_scalar.SInt());
168   EXPECT_EQ((unsigned int)a, a_scalar.UInt());
169   EXPECT_EQ((signed long)a, a_scalar.SLong());
170   EXPECT_EQ((unsigned long)a, a_scalar.ULong());
171   EXPECT_EQ((signed long long)a, a_scalar.SLongLong());
172   EXPECT_EQ((unsigned long long)a, a_scalar.ULongLong());
173 
174   int a2 = 23;
175   Scalar a2_scalar(a2);
176   EXPECT_EQ((float)a2, a2_scalar.Float());
177   EXPECT_EQ((double)a2, a2_scalar.Double());
178   EXPECT_EQ((long double)a2, a2_scalar.LongDouble());
179 
180   EXPECT_EQ(std::numeric_limits<unsigned int>::min(), Scalar(-1.0f).UInt());
181   EXPECT_EQ(std::numeric_limits<unsigned int>::max(), Scalar(1e11f).UInt());
182   EXPECT_EQ(std::numeric_limits<unsigned long long>::min(),
183             Scalar(-1.0).ULongLong());
184   EXPECT_EQ(std::numeric_limits<unsigned long long>::max(),
185             Scalar(1e22).ULongLong());
186 
187   EXPECT_EQ(std::numeric_limits<int>::min(), Scalar(-1e11f).SInt());
188   EXPECT_EQ(std::numeric_limits<int>::max(), Scalar(1e11f).SInt());
189   EXPECT_EQ(std::numeric_limits<long long>::min(), Scalar(-1e22).SLongLong());
190   EXPECT_EQ(std::numeric_limits<long long>::max(), Scalar(1e22).SLongLong());
191 }
192 
193 TEST(ScalarTest, ExtractBitfield) {
194   uint32_t len = sizeof(long long) * 8;
195 
196   long long a1 = 0xf1f2f3f4f5f6f7f8LL;
197   long long b1 = 0xff1f2f3f4f5f6f7fLL;
198   Scalar s_scalar(a1);
199   ASSERT_TRUE(s_scalar.ExtractBitfield(0, 0));
200   EXPECT_EQ(s_scalar, a1);
201   ASSERT_TRUE(s_scalar.ExtractBitfield(len, 0));
202   EXPECT_EQ(s_scalar, a1);
203   ASSERT_TRUE(s_scalar.ExtractBitfield(len - 4, 4));
204   EXPECT_EQ(s_scalar, b1);
205 
206   unsigned long long a2 = 0xf1f2f3f4f5f6f7f8ULL;
207   unsigned long long b2 = 0x0f1f2f3f4f5f6f7fULL;
208   Scalar u_scalar(a2);
209   ASSERT_TRUE(u_scalar.ExtractBitfield(0, 0));
210   EXPECT_EQ(u_scalar, a2);
211   ASSERT_TRUE(u_scalar.ExtractBitfield(len, 0));
212   EXPECT_EQ(u_scalar, a2);
213   ASSERT_TRUE(u_scalar.ExtractBitfield(len - 4, 4));
214   EXPECT_EQ(u_scalar, b2);
215 }
216 
217 template <typename T> static std::string ScalarGetValue(T value) {
218   StreamString stream;
219   Scalar(value).GetValue(&stream, false);
220   return std::string(stream.GetString());
221 }
222 
223 TEST(ScalarTest, GetValue) {
224   EXPECT_EQ("12345", ScalarGetValue<signed short>(12345));
225   EXPECT_EQ("-12345", ScalarGetValue<signed short>(-12345));
226   EXPECT_EQ("12345", ScalarGetValue<unsigned short>(12345));
227   EXPECT_EQ(std::to_string(std::numeric_limits<unsigned short>::max()),
228             ScalarGetValue(std::numeric_limits<unsigned short>::max()));
229 
230   EXPECT_EQ("12345", ScalarGetValue<signed int>(12345));
231   EXPECT_EQ("-12345", ScalarGetValue<signed int>(-12345));
232   EXPECT_EQ("12345", ScalarGetValue<unsigned int>(12345));
233   EXPECT_EQ(std::to_string(std::numeric_limits<unsigned int>::max()),
234             ScalarGetValue(std::numeric_limits<unsigned int>::max()));
235 
236   EXPECT_EQ("12345678", ScalarGetValue<signed long>(12345678L));
237   EXPECT_EQ("-12345678", ScalarGetValue<signed long>(-12345678L));
238   EXPECT_EQ("12345678", ScalarGetValue<unsigned long>(12345678UL));
239   EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long>::max()),
240             ScalarGetValue(std::numeric_limits<unsigned long>::max()));
241 
242   EXPECT_EQ("1234567890123", ScalarGetValue<signed long long>(1234567890123LL));
243   EXPECT_EQ("-1234567890123",
244             ScalarGetValue<signed long long>(-1234567890123LL));
245   EXPECT_EQ("1234567890123",
246             ScalarGetValue<unsigned long long>(1234567890123ULL));
247   EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long long>::max()),
248             ScalarGetValue(std::numeric_limits<unsigned long long>::max()));
249 }
250 
251 TEST(ScalarTest, LongLongAssigmentOperator) {
252   Scalar ull;
253   ull = std::numeric_limits<unsigned long long>::max();
254   EXPECT_EQ(std::numeric_limits<unsigned long long>::max(), ull.ULongLong());
255 
256   Scalar sll;
257   sll = std::numeric_limits<signed long long>::max();
258   EXPECT_EQ(std::numeric_limits<signed long long>::max(), sll.SLongLong());
259 }
260 
261 TEST(ScalarTest, Division) {
262   Scalar lhs(5.0);
263   Scalar rhs(2.0);
264   Scalar r = lhs / rhs;
265   EXPECT_TRUE(r.IsValid());
266   EXPECT_EQ(r, Scalar(2.5));
267 }
268 
269 TEST(ScalarTest, Promotion) {
270   static Scalar::Type int_types[] = {
271       Scalar::e_sint,    Scalar::e_uint,      Scalar::e_slong,
272       Scalar::e_ulong,   Scalar::e_slonglong, Scalar::e_ulonglong,
273       Scalar::e_sint128, Scalar::e_uint128,   Scalar::e_sint256,
274       Scalar::e_uint256,
275       Scalar::e_void // sentinel
276   };
277 
278   static Scalar::Type float_types[] = {
279       Scalar::e_float, Scalar::e_double, Scalar::e_long_double,
280       Scalar::e_void // sentinel
281   };
282 
283   for (int i = 0; int_types[i] != Scalar::e_void; ++i) {
284     for (int j = 0; float_types[j] != Scalar::e_void; ++j) {
285       Scalar lhs(2);
286       EXPECT_TRUE(lhs.Promote(int_types[i])) << "int promotion #" << i;
287       Scalar rhs(0.5f);
288       EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j;
289       Scalar x(2.5f);
290       EXPECT_TRUE(x.Promote(float_types[j]));
291       EXPECT_EQ(lhs + rhs, x);
292     }
293   }
294 
295   for (int i = 0; float_types[i] != Scalar::e_void; ++i) {
296     for (int j = 0; float_types[j] != Scalar::e_void; ++j) {
297       Scalar lhs(2);
298       EXPECT_TRUE(lhs.Promote(float_types[i])) << "float promotion #" << i;
299       Scalar rhs(0.5f);
300       EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j;
301       Scalar x(2.5f);
302       EXPECT_TRUE(x.Promote(float_types[j]));
303       EXPECT_EQ(lhs + rhs, x);
304     }
305   }
306 }
307 
308 TEST(ScalarTest, SetValueFromCString) {
309   Scalar a;
310 
311   EXPECT_THAT_ERROR(
312       a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 8).ToError(),
313       Succeeded());
314   EXPECT_EQ(1234567890123ull, a);
315 
316   EXPECT_THAT_ERROR(
317       a.SetValueFromCString("-1234567890123", lldb::eEncodingSint, 8).ToError(),
318       Succeeded());
319   EXPECT_EQ(-1234567890123ll, a);
320 
321   EXPECT_THAT_ERROR(
322       a.SetValueFromCString("asdf", lldb::eEncodingSint, 8).ToError(),
323       Failed());
324   EXPECT_THAT_ERROR(
325       a.SetValueFromCString("asdf", lldb::eEncodingUint, 8).ToError(),
326       Failed());
327   EXPECT_THAT_ERROR(
328       a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 4).ToError(),
329       Failed());
330   EXPECT_THAT_ERROR(a.SetValueFromCString("123456789012345678901234567890",
331                                           lldb::eEncodingUint, 8)
332                         .ToError(),
333                     Failed());
334   EXPECT_THAT_ERROR(
335       a.SetValueFromCString("-123", lldb::eEncodingUint, 8).ToError(),
336       Failed());
337   EXPECT_THAT_ERROR(
338       a.SetValueFromCString("-2147483648", lldb::eEncodingSint, 4).ToError(),
339       Succeeded());
340   EXPECT_EQ(-2147483648, a);
341   EXPECT_THAT_ERROR(
342       a.SetValueFromCString("-2147483649", lldb::eEncodingSint, 4).ToError(),
343       Failed());
344   EXPECT_THAT_ERROR(
345       a.SetValueFromCString("47.25", lldb::eEncodingIEEE754, 4).ToError(),
346       Succeeded());
347   EXPECT_EQ(47.25f, a);
348   EXPECT_THAT_ERROR(
349       a.SetValueFromCString("asdf", lldb::eEncodingIEEE754, 4).ToError(),
350       Failed());
351 }
352 
353 TEST(ScalarTest, APIntConstructor) {
354   auto width_array = {8, 16, 32};
355   for (auto &w : width_array) {
356     Scalar A(APInt(w, 24));
357     EXPECT_EQ(A.GetType(), Scalar::e_sint);
358   }
359 
360   Scalar B(APInt(64, 42));
361   EXPECT_EQ(B.GetType(), Scalar::GetBestTypeForBitSize(64, true));
362   Scalar C(APInt(128, 96));
363   EXPECT_EQ(C.GetType(), Scalar::e_sint128);
364   Scalar D(APInt(256, 156));
365   EXPECT_EQ(D.GetType(), Scalar::e_sint256);
366   Scalar E(APInt(512, 456));
367   EXPECT_EQ(E.GetType(), Scalar::e_sint512);
368 }
369 
370 TEST(ScalarTest, Scalar_512) {
371   Scalar Z(APInt(512, 0));
372   ASSERT_TRUE(Z.IsZero());
373   Z.MakeUnsigned();
374   ASSERT_TRUE(Z.IsZero());
375 
376   Scalar S(APInt(512, 2000));
377   ASSERT_STREQ(S.GetTypeAsCString(), "int512_t");
378   ASSERT_STREQ(S.GetValueTypeAsCString(Scalar::e_sint512), "int512_t");
379 
380   ASSERT_TRUE(S.MakeUnsigned());
381   EXPECT_EQ(S.GetType(), Scalar::e_uint512);
382   ASSERT_STREQ(S.GetTypeAsCString(), "uint512_t");
383   ASSERT_STREQ(S.GetValueTypeAsCString(Scalar::e_uint512), "uint512_t");
384   EXPECT_EQ(S.GetByteSize(), 64U);
385 
386   ASSERT_TRUE(S.MakeSigned());
387   EXPECT_EQ(S.GetType(), Scalar::e_sint512);
388   EXPECT_EQ(S.GetByteSize(), 64U);
389 }
390 
391 TEST(ScalarTest, TruncOrExtendTo) {
392   Scalar S(0xffff);
393   S.TruncOrExtendTo(12, true);
394   EXPECT_EQ(S.UInt128(APInt()), APInt(12, 0xfffu));
395   S.TruncOrExtendTo(20, true);
396   EXPECT_EQ(S.UInt128(APInt()), APInt(20, 0xfffffu));
397   S.TruncOrExtendTo(24, false);
398   EXPECT_EQ(S.UInt128(APInt()), APInt(24, 0x0fffffu));
399   S.TruncOrExtendTo(16, false);
400   EXPECT_EQ(S.UInt128(APInt()), APInt(16, 0xffffu));
401 }
402