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 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 
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 
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 
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 
157 template <typename T> static std::string ScalarGetValue(T value) {
158   StreamString stream;
159   Scalar(value).GetValue(&stream, false);
160   return std::string(stream.GetString());
161 }
162 
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 
191 TEST(ScalarTest, LongLongAssigmentOperator) {
192   Scalar ull;
193   ull = std::numeric_limits<unsigned long long>::max();
194   EXPECT_EQ(std::numeric_limits<unsigned long long>::max(), ull.ULongLong());
195 
196   Scalar sll;
197   sll = std::numeric_limits<signed long long>::max();
198   EXPECT_EQ(std::numeric_limits<signed long long>::max(), sll.SLongLong());
199 }
200 
201 TEST(ScalarTest, Division) {
202   Scalar lhs(5.0);
203   Scalar rhs(2.0);
204   Scalar r = lhs / rhs;
205   EXPECT_TRUE(r.IsValid());
206   EXPECT_EQ(r, Scalar(2.5));
207 }
208 
209 TEST(ScalarTest, Promotion) {
210   static Scalar::Type int_types[] = {
211       Scalar::e_sint,    Scalar::e_uint,      Scalar::e_slong,
212       Scalar::e_ulong,   Scalar::e_slonglong, Scalar::e_ulonglong,
213       Scalar::e_sint128, Scalar::e_uint128,   Scalar::e_sint256,
214       Scalar::e_uint256,
215       Scalar::e_void // sentinel
216   };
217 
218   static Scalar::Type float_types[] = {
219       Scalar::e_float, Scalar::e_double, Scalar::e_long_double,
220       Scalar::e_void // sentinel
221   };
222 
223   for (int i = 0; int_types[i] != Scalar::e_void; ++i) {
224     for (int j = 0; float_types[j] != Scalar::e_void; ++j) {
225       Scalar lhs(2);
226       EXPECT_TRUE(lhs.Promote(int_types[i])) << "int promotion #" << i;
227       Scalar rhs(0.5f);
228       EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j;
229       Scalar x(2.5f);
230       EXPECT_TRUE(x.Promote(float_types[j]));
231       EXPECT_EQ(lhs + rhs, x);
232     }
233   }
234 
235   for (int i = 0; float_types[i] != Scalar::e_void; ++i) {
236     for (int j = 0; float_types[j] != Scalar::e_void; ++j) {
237       Scalar lhs(2);
238       EXPECT_TRUE(lhs.Promote(float_types[i])) << "float promotion #" << i;
239       Scalar rhs(0.5f);
240       EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j;
241       Scalar x(2.5f);
242       EXPECT_TRUE(x.Promote(float_types[j]));
243       EXPECT_EQ(lhs + rhs, x);
244     }
245   }
246 }
247 
248 TEST(ScalarTest, SetValueFromCString) {
249   Scalar a;
250 
251   EXPECT_THAT_ERROR(
252       a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 8).ToError(),
253       Succeeded());
254   EXPECT_EQ(1234567890123ull, a);
255 
256   EXPECT_THAT_ERROR(
257       a.SetValueFromCString("-1234567890123", lldb::eEncodingSint, 8).ToError(),
258       Succeeded());
259   EXPECT_EQ(-1234567890123ll, a);
260 
261   EXPECT_THAT_ERROR(
262       a.SetValueFromCString("asdf", lldb::eEncodingSint, 8).ToError(),
263       Failed());
264   EXPECT_THAT_ERROR(
265       a.SetValueFromCString("asdf", lldb::eEncodingUint, 8).ToError(),
266       Failed());
267   EXPECT_THAT_ERROR(
268       a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 4).ToError(),
269       Failed());
270   EXPECT_THAT_ERROR(a.SetValueFromCString("123456789012345678901234567890",
271                                           lldb::eEncodingUint, 8)
272                         .ToError(),
273                     Failed());
274   EXPECT_THAT_ERROR(
275       a.SetValueFromCString("-123", lldb::eEncodingUint, 8).ToError(),
276       Failed());
277 }
278 
279 TEST(ScalarTest, APIntConstructor) {
280   auto width_array = {8, 16, 32};
281   for (auto &w : width_array) {
282     Scalar A(APInt(w, 24));
283     EXPECT_EQ(A.GetType(), Scalar::e_sint);
284   }
285 
286   Scalar B(APInt(64, 42));
287   EXPECT_EQ(B.GetType(), Scalar::GetBestTypeForBitSize(64, true));
288   Scalar C(APInt(128, 96));
289   EXPECT_EQ(C.GetType(), Scalar::e_sint128);
290   Scalar D(APInt(256, 156));
291   EXPECT_EQ(D.GetType(), Scalar::e_sint256);
292   Scalar E(APInt(512, 456));
293   EXPECT_EQ(E.GetType(), Scalar::e_sint512);
294 }
295 
296 TEST(ScalarTest, Scalar_512) {
297   Scalar Z(APInt(512, 0));
298   ASSERT_TRUE(Z.IsZero());
299   Z.MakeUnsigned();
300   ASSERT_TRUE(Z.IsZero());
301 
302   Scalar S(APInt(512, 2000));
303   ASSERT_STREQ(S.GetTypeAsCString(), "int512_t");
304   ASSERT_STREQ(S.GetValueTypeAsCString(Scalar::e_sint512), "int512_t");
305 
306   ASSERT_TRUE(S.MakeUnsigned());
307   EXPECT_EQ(S.GetType(), Scalar::e_uint512);
308   ASSERT_STREQ(S.GetTypeAsCString(), "unsigned int512_t");
309   ASSERT_STREQ(S.GetValueTypeAsCString(Scalar::e_uint512), "uint512_t");
310   EXPECT_EQ(S.GetByteSize(), 64U);
311 
312   ASSERT_TRUE(S.MakeSigned());
313   EXPECT_EQ(S.GetType(), Scalar::e_sint512);
314   EXPECT_EQ(S.GetByteSize(), 64U);
315 }
316