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