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