blob: d4a08496a37e3f8c4d59aa72fb89a4bcc07f94ee [file] [log] [blame]
Pavel Labathb625a0e2016-02-09 17:28:01 +00001//===-- ScalarTest.cpp ------------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Pavel Labathb625a0e2016-02-09 17:28:01 +00006//
7//===----------------------------------------------------------------------===//
8
Pavel Labathb625a0e2016-02-09 17:28:01 +00009#include "gtest/gtest.h"
10
Zachary Turner666cc0b2017-03-04 01:30:05 +000011#include "lldb/Utility/DataExtractor.h"
Zachary Turner01c32432017-02-14 19:06:07 +000012#include "lldb/Utility/Endian.h"
Pavel Labathd821c992018-08-07 11:07:21 +000013#include "lldb/Utility/Scalar.h"
Zachary Turner97206d52017-05-12 04:51:55 +000014#include "lldb/Utility/Status.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000015#include "lldb/Utility/StreamString.h"
Pavel Labath61547252018-06-19 17:24:03 +000016#include "llvm/Testing/Support/Error.h"
Pavel Labathb625a0e2016-02-09 17:28:01 +000017
18using namespace lldb_private;
Pavel Labath61547252018-06-19 17:24:03 +000019using namespace llvm;
Pavel Labathb625a0e2016-02-09 17:28:01 +000020
Davide Italiano18a0ce92018-12-21 22:42:00 +000021template <typename T>
22bool checkInequality(T c1, T c2) {
23 return (Scalar(c1) != Scalar(c2));
24}
25
26template <typename T>
27bool checkEquality(T c1, T c2) {
28 return (Scalar(c1) == Scalar(c2));
29}
30
31TEST(ScalarTest, Equality) {
32 ASSERT_TRUE(checkInequality<int>(23, 24));
33 ASSERT_TRUE(checkEquality<int>(96, 96));
34 ASSERT_TRUE(checkInequality<float>(4.0f, 4.5f));
35 ASSERT_TRUE(checkEquality<float>(4.0f, 4.0f));
Davide Italianob4296372018-12-21 22:45:07 +000036
37 auto apint1 = APInt(64, 234);
38 auto apint2 = APInt(64, 246);
39 ASSERT_TRUE(checkInequality<APInt>(apint1, apint2));
40 ASSERT_TRUE(checkEquality<APInt>(apint1, apint1));
Davide Italiano18a0ce92018-12-21 22:42:00 +000041
42 Scalar void1;
43 Scalar void2;
44 float f1 = 2.0;
45 ASSERT_TRUE(void1 == void2);
46 ASSERT_FALSE(void1 == Scalar(f1));
47}
48
Davide Italianoff92a1a2019-01-04 19:23:52 +000049TEST(ScalarTest, Comparison) {
50 auto s1 = Scalar(23);
51 auto s2 = Scalar(46);
52 ASSERT_TRUE(s1 < s2);
53 ASSERT_TRUE(s1 <= s2);
54 ASSERT_TRUE(s2 > s1);
55 ASSERT_TRUE(s2 >= s1);
56}
57
58TEST(ScalarTest, ComparisonFloat) {
59 auto s1 = Scalar(23.0f);
60 auto s2 = Scalar(46.0f);
61 ASSERT_TRUE(s1 < s2);
62 ASSERT_TRUE(s1 <= s2);
63 ASSERT_TRUE(s2 > s1);
64 ASSERT_TRUE(s2 >= s1);
65}
66
Kate Stoneb9c1b512016-09-06 20:57:50 +000067TEST(ScalarTest, RightShiftOperator) {
68 int a = 0x00001000;
69 int b = 0xFFFFFFFF;
70 int c = 4;
71 Scalar a_scalar(a);
72 Scalar b_scalar(b);
73 Scalar c_scalar(c);
74 ASSERT_EQ(a >> c, a_scalar >> c_scalar);
75 ASSERT_EQ(b >> c, b_scalar >> c_scalar);
Pavel Labathb625a0e2016-02-09 17:28:01 +000076}
Ulrich Weigand9521ad22016-04-15 09:55:52 +000077
Kate Stoneb9c1b512016-09-06 20:57:50 +000078TEST(ScalarTest, GetBytes) {
79 int a = 0x01020304;
80 long long b = 0x0102030405060708LL;
Adrian McCarthy4ee16bf2018-04-19 18:31:57 +000081 float c = 1234567.89e32f;
Kate Stoneb9c1b512016-09-06 20:57:50 +000082 double d = 1234567.89e42;
83 char e[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
84 char f[32] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
85 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
86 Scalar a_scalar(a);
87 Scalar b_scalar(b);
88 Scalar c_scalar(c);
89 Scalar d_scalar(d);
90 Scalar e_scalar;
91 Scalar f_scalar;
92 DataExtractor e_data(e, sizeof(e), endian::InlHostByteOrder(),
93 sizeof(void *));
Zachary Turner97206d52017-05-12 04:51:55 +000094 Status e_error =
Kate Stoneb9c1b512016-09-06 20:57:50 +000095 e_scalar.SetValueFromData(e_data, lldb::eEncodingUint, sizeof(e));
96 DataExtractor f_data(f, sizeof(f), endian::InlHostByteOrder(),
97 sizeof(void *));
Zachary Turner97206d52017-05-12 04:51:55 +000098 Status f_error =
Kate Stoneb9c1b512016-09-06 20:57:50 +000099 f_scalar.SetValueFromData(f_data, lldb::eEncodingUint, sizeof(f));
100 ASSERT_EQ(0, memcmp(&a, a_scalar.GetBytes(), sizeof(a)));
101 ASSERT_EQ(0, memcmp(&b, b_scalar.GetBytes(), sizeof(b)));
102 ASSERT_EQ(0, memcmp(&c, c_scalar.GetBytes(), sizeof(c)));
103 ASSERT_EQ(0, memcmp(&d, d_scalar.GetBytes(), sizeof(d)));
104 ASSERT_EQ(0, e_error.Fail());
105 ASSERT_EQ(0, memcmp(e, e_scalar.GetBytes(), sizeof(e)));
106 ASSERT_EQ(0, f_error.Fail());
107 ASSERT_EQ(0, memcmp(f, f_scalar.GetBytes(), sizeof(f)));
Ulrich Weigand9521ad22016-04-15 09:55:52 +0000108}
109
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110TEST(ScalarTest, CastOperations) {
111 long long a = 0xf1f2f3f4f5f6f7f8LL;
112 Scalar a_scalar(a);
113 ASSERT_EQ((signed char)a, a_scalar.SChar());
114 ASSERT_EQ((unsigned char)a, a_scalar.UChar());
115 ASSERT_EQ((signed short)a, a_scalar.SShort());
116 ASSERT_EQ((unsigned short)a, a_scalar.UShort());
117 ASSERT_EQ((signed int)a, a_scalar.SInt());
118 ASSERT_EQ((unsigned int)a, a_scalar.UInt());
119 ASSERT_EQ((signed long)a, a_scalar.SLong());
120 ASSERT_EQ((unsigned long)a, a_scalar.ULong());
121 ASSERT_EQ((signed long long)a, a_scalar.SLongLong());
122 ASSERT_EQ((unsigned long long)a, a_scalar.ULongLong());
Davide Italiano49d80282018-04-02 16:50:54 +0000123
124 int a2 = 23;
125 Scalar a2_scalar(a2);
126 ASSERT_EQ((float)a2, a2_scalar.Float());
127 ASSERT_EQ((double)a2, a2_scalar.Double());
128 ASSERT_EQ((long double)a2, a2_scalar.LongDouble());
Ulrich Weigand9521ad22016-04-15 09:55:52 +0000129}
130
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131TEST(ScalarTest, ExtractBitfield) {
132 uint32_t len = sizeof(long long) * 8;
Bryan Chan01319e92016-05-19 13:51:20 +0000133
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 long long a1 = 0xf1f2f3f4f5f6f7f8LL;
135 long long b1 = 0xff1f2f3f4f5f6f7fLL;
136 Scalar s_scalar(a1);
137 ASSERT_TRUE(s_scalar.ExtractBitfield(0, 0));
138 ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1)));
139 ASSERT_TRUE(s_scalar.ExtractBitfield(len, 0));
140 ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1)));
141 ASSERT_TRUE(s_scalar.ExtractBitfield(len - 4, 4));
142 ASSERT_EQ(0, memcmp(&b1, s_scalar.GetBytes(), sizeof(b1)));
Bryan Chan01319e92016-05-19 13:51:20 +0000143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 unsigned long long a2 = 0xf1f2f3f4f5f6f7f8ULL;
145 unsigned long long b2 = 0x0f1f2f3f4f5f6f7fULL;
146 Scalar u_scalar(a2);
147 ASSERT_TRUE(u_scalar.ExtractBitfield(0, 0));
148 ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2)));
149 ASSERT_TRUE(u_scalar.ExtractBitfield(len, 0));
150 ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2)));
151 ASSERT_TRUE(u_scalar.ExtractBitfield(len - 4, 4));
152 ASSERT_EQ(0, memcmp(&b2, u_scalar.GetBytes(), sizeof(b2)));
Bryan Chan01319e92016-05-19 13:51:20 +0000153}
Pavel Labathf92756e2016-09-02 10:58:52 +0000154
Kate Stoneb9c1b512016-09-06 20:57:50 +0000155template <typename T> static std::string ScalarGetValue(T value) {
156 StreamString stream;
157 Scalar(value).GetValue(&stream, false);
158 return stream.GetString();
Pavel Labathf92756e2016-09-02 10:58:52 +0000159}
160
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161TEST(ScalarTest, GetValue) {
162 EXPECT_EQ("12345", ScalarGetValue<signed short>(12345));
163 EXPECT_EQ("-12345", ScalarGetValue<signed short>(-12345));
164 EXPECT_EQ("12345", ScalarGetValue<unsigned short>(12345));
165 EXPECT_EQ(std::to_string(std::numeric_limits<unsigned short>::max()),
166 ScalarGetValue(std::numeric_limits<unsigned short>::max()));
Pavel Labathf92756e2016-09-02 10:58:52 +0000167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168 EXPECT_EQ("12345", ScalarGetValue<signed int>(12345));
169 EXPECT_EQ("-12345", ScalarGetValue<signed int>(-12345));
170 EXPECT_EQ("12345", ScalarGetValue<unsigned int>(12345));
171 EXPECT_EQ(std::to_string(std::numeric_limits<unsigned int>::max()),
172 ScalarGetValue(std::numeric_limits<unsigned int>::max()));
Pavel Labathf92756e2016-09-02 10:58:52 +0000173
Kate Stoneb9c1b512016-09-06 20:57:50 +0000174 EXPECT_EQ("12345678", ScalarGetValue<signed long>(12345678L));
175 EXPECT_EQ("-12345678", ScalarGetValue<signed long>(-12345678L));
176 EXPECT_EQ("12345678", ScalarGetValue<unsigned long>(12345678UL));
177 EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long>::max()),
178 ScalarGetValue(std::numeric_limits<unsigned long>::max()));
Pavel Labathf92756e2016-09-02 10:58:52 +0000179
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180 EXPECT_EQ("1234567890123", ScalarGetValue<signed long long>(1234567890123LL));
181 EXPECT_EQ("-1234567890123",
182 ScalarGetValue<signed long long>(-1234567890123LL));
183 EXPECT_EQ("1234567890123",
184 ScalarGetValue<unsigned long long>(1234567890123ULL));
185 EXPECT_EQ(std::to_string(std::numeric_limits<unsigned long long>::max()),
186 ScalarGetValue(std::numeric_limits<unsigned long long>::max()));
Pavel Labathf92756e2016-09-02 10:58:52 +0000187}
Davide Italiano01c33b82018-03-27 18:37:54 +0000188
189TEST(ScalarTest, Division) {
190 Scalar lhs(5.0);
191 Scalar rhs(2.0);
192 Scalar r = lhs / rhs;
193 EXPECT_TRUE(r.IsValid());
194 EXPECT_EQ(r, Scalar(2.5));
195}
Davide Italiano49d80282018-04-02 16:50:54 +0000196
197TEST(ScalarTest, Promotion) {
198 static Scalar::Type int_types[] = {
199 Scalar::e_sint, Scalar::e_uint, Scalar::e_slong,
200 Scalar::e_ulong, Scalar::e_slonglong, Scalar::e_ulonglong,
201 Scalar::e_sint128, Scalar::e_uint128, Scalar::e_sint256,
202 Scalar::e_uint256,
203 Scalar::e_void // sentinel
204 };
205
206 static Scalar::Type float_types[] = {
207 Scalar::e_float, Scalar::e_double, Scalar::e_long_double,
208 Scalar::e_void // sentinel
209 };
210
211 for (int i = 0; int_types[i] != Scalar::e_void; ++i) {
212 for (int j = 0; float_types[j] != Scalar::e_void; ++j) {
213 Scalar lhs(2);
214 EXPECT_TRUE(lhs.Promote(int_types[i])) << "int promotion #" << i;
215 Scalar rhs(0.5f);
216 EXPECT_TRUE(rhs.Promote(float_types[j])) << "float promotion #" << j;
217 Scalar x(2.5f);
218 EXPECT_TRUE(x.Promote(float_types[j]));
219 EXPECT_EQ(lhs + rhs, x);
220 }
221 }
222
223 for (int i = 0; float_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(float_types[i])) << "float 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}
Pavel Labath61547252018-06-19 17:24:03 +0000235
236TEST(ScalarTest, SetValueFromCString) {
237 Scalar a;
238
239 EXPECT_THAT_ERROR(
240 a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 8).ToError(),
241 Succeeded());
242 EXPECT_EQ(1234567890123ull, a);
243
244 EXPECT_THAT_ERROR(
245 a.SetValueFromCString("-1234567890123", lldb::eEncodingSint, 8).ToError(),
246 Succeeded());
247 EXPECT_EQ(-1234567890123ll, a);
248
249 EXPECT_THAT_ERROR(
250 a.SetValueFromCString("asdf", lldb::eEncodingSint, 8).ToError(),
251 Failed());
252 EXPECT_THAT_ERROR(
253 a.SetValueFromCString("asdf", lldb::eEncodingUint, 8).ToError(),
254 Failed());
255 EXPECT_THAT_ERROR(
256 a.SetValueFromCString("1234567890123", lldb::eEncodingUint, 4).ToError(),
257 Failed());
258 EXPECT_THAT_ERROR(a.SetValueFromCString("123456789012345678901234567890",
259 lldb::eEncodingUint, 8)
260 .ToError(),
261 Failed());
262 EXPECT_THAT_ERROR(
263 a.SetValueFromCString("-123", lldb::eEncodingUint, 8).ToError(),
264 Failed());
265}
Davide Italiano7fca260d2019-01-24 20:55:12 +0000266
267TEST(ScalarTest, APIntConstructor) {
268 auto width_array = {8, 16, 32};
269 for (auto &w : width_array) {
270 Scalar A(APInt(w, 24));
271 EXPECT_EQ(A.GetType(), Scalar::e_sint);
272 }
273
274 Scalar B(APInt(64, 42));
275 EXPECT_EQ(B.GetType(), Scalar::e_slonglong);
276 Scalar C(APInt(128, 96));
277 EXPECT_EQ(C.GetType(), Scalar::e_sint128);
278 Scalar D(APInt(256, 156));
279 EXPECT_EQ(D.GetType(), Scalar::e_sint256);
Davide Italiano51d46bd2019-01-30 18:05:36 +0000280 Scalar E(APInt(512, 456));
281 EXPECT_EQ(E.GetType(), Scalar::e_sint512);
282}
283
284TEST(ScalarTest, Scalar_512) {
285 Scalar Z(APInt(512, 0));
286 ASSERT_TRUE(Z.IsZero());
287 Z.MakeUnsigned();
288 ASSERT_TRUE(Z.IsZero());
289
290 Scalar S(APInt(512, 2000));
Jonas Devlieghere043ff332019-01-31 18:48:17 +0000291 ASSERT_STREQ(S.GetTypeAsCString(), "int512_t");
292 ASSERT_STREQ(S.GetValueTypeAsCString(Scalar::e_sint512), "int512_t");
Davide Italiano51d46bd2019-01-30 18:05:36 +0000293
294 ASSERT_TRUE(S.MakeUnsigned());
295 EXPECT_EQ(S.GetType(), Scalar::e_uint512);
Jonas Devlieghere043ff332019-01-31 18:48:17 +0000296 ASSERT_STREQ(S.GetTypeAsCString(), "unsigned int512_t");
297 ASSERT_STREQ(S.GetValueTypeAsCString(Scalar::e_uint512), "uint512_t");
Davide Italiano51d46bd2019-01-30 18:05:36 +0000298 EXPECT_EQ(S.GetByteSize(), 64U);
299
300 ASSERT_TRUE(S.MakeSigned());
301 EXPECT_EQ(S.GetType(), Scalar::e_sint512);
302 EXPECT_EQ(S.GetByteSize(), 64U);
Davide Italiano7fca260d2019-01-24 20:55:12 +0000303}