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