1 //===- llvm/unittest/FileCheck/FileCheckTest.cpp - FileCheck tests --------===// 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 "llvm/FileCheck/FileCheck.h" 10 #include "../lib/FileCheck/FileCheckImpl.h" 11 #include "llvm/Support/Regex.h" 12 #include "llvm/Testing/Support/Error.h" 13 #include "gtest/gtest.h" 14 #include <tuple> 15 #include <unordered_set> 16 17 using namespace llvm; 18 19 namespace { 20 21 class FileCheckTest : public ::testing::Test {}; 22 23 static StringRef bufferize(SourceMgr &SM, StringRef Str) { 24 std::unique_ptr<MemoryBuffer> Buffer = 25 MemoryBuffer::getMemBufferCopy(Str, "TestBuffer"); 26 StringRef StrBufferRef = Buffer->getBuffer(); 27 SM.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 28 return StrBufferRef; 29 } 30 31 static std::string toString(const std::unordered_set<std::string> &Set) { 32 bool First = true; 33 std::string Str; 34 for (StringRef S : Set) { 35 Str += Twine(First ? "{" + S : ", " + S).str(); 36 First = false; 37 } 38 Str += '}'; 39 return Str; 40 } 41 42 template <typename ErrorT> 43 static void expectSameErrors(std::unordered_set<std::string> ExpectedMsgs, 44 Error Err) { 45 auto AnyErrorMsgMatch = [&ExpectedMsgs](std::string &&ErrorMsg) -> bool { 46 for (auto ExpectedMsgItr = ExpectedMsgs.begin(), 47 ExpectedMsgEnd = ExpectedMsgs.end(); 48 ExpectedMsgItr != ExpectedMsgEnd; ++ExpectedMsgItr) { 49 if (ErrorMsg.find(*ExpectedMsgItr) != std::string::npos) { 50 ExpectedMsgs.erase(ExpectedMsgItr); 51 return true; 52 } 53 } 54 return false; 55 }; 56 57 Error RemainingErrors = std::move(Err); 58 do { 59 RemainingErrors = 60 handleErrors(std::move(RemainingErrors), [&](const ErrorT &E) { 61 EXPECT_TRUE(AnyErrorMsgMatch(E.message())) 62 << "Unexpected error message:" << std::endl 63 << E.message(); 64 }); 65 } while (RemainingErrors && !ExpectedMsgs.empty()); 66 EXPECT_THAT_ERROR(std::move(RemainingErrors), Succeeded()); 67 EXPECT_TRUE(ExpectedMsgs.empty()) 68 << "Error message(s) not found:" << std::endl 69 << toString(ExpectedMsgs); 70 } 71 72 template <typename ErrorT> 73 static void expectError(StringRef ExpectedMsg, Error Err) { 74 expectSameErrors<ErrorT>({ExpectedMsg.str()}, std::move(Err)); 75 } 76 77 static void expectDiagnosticError(StringRef ExpectedMsg, Error Err) { 78 expectError<ErrorDiagnostic>(ExpectedMsg, std::move(Err)); 79 } 80 81 constexpr uint64_t MaxUint64 = std::numeric_limits<uint64_t>::max(); 82 constexpr int64_t MaxInt64 = std::numeric_limits<int64_t>::max(); 83 constexpr int64_t MinInt64 = std::numeric_limits<int64_t>::min(); 84 constexpr uint64_t AbsoluteMinInt64 = 85 static_cast<uint64_t>(-(MinInt64 + 1)) + 1; 86 constexpr uint64_t AbsoluteMaxInt64 = static_cast<uint64_t>(MaxInt64); 87 88 struct ExpressionFormatParameterisedFixture 89 : public ::testing::TestWithParam< 90 std::tuple<ExpressionFormat::Kind, unsigned, bool>> { 91 bool AlternateForm; 92 unsigned Precision; 93 bool Signed; 94 bool AllowHex; 95 bool AllowUpperHex; 96 ExpressionFormat Format; 97 Regex WildcardRegex; 98 99 StringRef TenStr; 100 StringRef FifteenStr; 101 std::string MaxUint64Str; 102 std::string MaxInt64Str; 103 std::string MinInt64Str; 104 StringRef FirstInvalidCharDigits; 105 StringRef AcceptedHexOnlyDigits; 106 StringRef RefusedHexOnlyDigits; 107 108 SourceMgr SM; 109 110 void SetUp() override { 111 ExpressionFormat::Kind Kind; 112 std::tie(Kind, Precision, AlternateForm) = GetParam(); 113 AllowHex = Kind == ExpressionFormat::Kind::HexLower || 114 Kind == ExpressionFormat::Kind::HexUpper; 115 AllowUpperHex = Kind == ExpressionFormat::Kind::HexUpper; 116 Signed = Kind == ExpressionFormat::Kind::Signed; 117 Format = ExpressionFormat(Kind, Precision, AlternateForm); 118 119 if (!AllowHex) { 120 MaxUint64Str = std::to_string(MaxUint64); 121 MaxInt64Str = std::to_string(MaxInt64); 122 MinInt64Str = std::to_string(MinInt64); 123 TenStr = "10"; 124 FifteenStr = "15"; 125 FirstInvalidCharDigits = "aA"; 126 AcceptedHexOnlyDigits = RefusedHexOnlyDigits = "N/A"; 127 return; 128 } 129 130 MaxUint64Str = AllowUpperHex ? "FFFFFFFFFFFFFFFF" : "ffffffffffffffff"; 131 MaxInt64Str = AllowUpperHex ? "7FFFFFFFFFFFFFFF" : "7fffffffffffffff"; 132 TenStr = AllowUpperHex ? "A" : "a"; 133 FifteenStr = AllowUpperHex ? "F" : "f"; 134 AcceptedHexOnlyDigits = AllowUpperHex ? "ABCDEF" : "abcdef"; 135 RefusedHexOnlyDigits = AllowUpperHex ? "abcdef" : "ABCDEF"; 136 MinInt64Str = "N/A"; 137 FirstInvalidCharDigits = "gG"; 138 } 139 140 void checkWildcardRegexMatch(StringRef Input, 141 unsigned TrailExtendTo = 0) const { 142 ASSERT_TRUE(TrailExtendTo == 0 || AllowHex); 143 SmallVector<StringRef, 4> Matches; 144 std::string ExtendedInput = Input.str(); 145 size_t PrefixSize = AlternateForm ? 2 : 0; 146 if (TrailExtendTo > Input.size() - PrefixSize) { 147 size_t ExtensionSize = PrefixSize + TrailExtendTo - Input.size(); 148 ExtendedInput.append(ExtensionSize, Input[PrefixSize]); 149 } 150 ASSERT_TRUE(WildcardRegex.match(ExtendedInput, &Matches)) 151 << "Wildcard regex does not match " << ExtendedInput; 152 EXPECT_EQ(Matches[0], ExtendedInput); 153 } 154 155 void checkWildcardRegexMatchFailure(StringRef Input) const { 156 EXPECT_FALSE(WildcardRegex.match(Input)); 157 } 158 159 std::string addBasePrefix(StringRef Num) const { 160 StringRef Prefix = AlternateForm ? "0x" : ""; 161 return (Twine(Prefix) + Twine(Num)).str(); 162 } 163 164 void checkPerCharWildcardRegexMatchFailure(StringRef Chars) const { 165 for (auto C : Chars) { 166 std::string Str = addBasePrefix(StringRef(&C, 1)); 167 EXPECT_FALSE(WildcardRegex.match(Str)); 168 } 169 } 170 171 std::string padWithLeadingZeros(StringRef NumStr) const { 172 bool Negative = NumStr.startswith("-"); 173 if (NumStr.size() - unsigned(Negative) >= Precision) 174 return NumStr.str(); 175 176 std::string PaddedStr; 177 if (Negative) { 178 PaddedStr = "-"; 179 NumStr = NumStr.drop_front(); 180 } 181 PaddedStr.append(Precision - NumStr.size(), '0'); 182 PaddedStr.append(NumStr.str()); 183 return PaddedStr; 184 } 185 186 template <class T> void checkMatchingString(T Val, StringRef ExpectedStr) { 187 Expected<std::string> MatchingString = 188 Format.getMatchingString(ExpressionValue(Val)); 189 ASSERT_THAT_EXPECTED(MatchingString, Succeeded()) 190 << "No matching string for " << Val; 191 EXPECT_EQ(*MatchingString, ExpectedStr); 192 } 193 194 template <class T> void checkMatchingStringFailure(T Val) { 195 Expected<std::string> MatchingString = 196 Format.getMatchingString(ExpressionValue(Val)); 197 // Error message tested in ExpressionValue unit tests. 198 EXPECT_THAT_EXPECTED(MatchingString, Failed()); 199 } 200 201 Expected<ExpressionValue> getValueFromStringReprFailure(StringRef Str) { 202 StringRef BufferizedStr = bufferize(SM, Str); 203 return Format.valueFromStringRepr(BufferizedStr, SM); 204 } 205 206 template <class T> 207 void checkValueFromStringRepr(StringRef Str, T ExpectedVal) { 208 Expected<ExpressionValue> ResultValue = getValueFromStringReprFailure(Str); 209 ASSERT_THAT_EXPECTED(ResultValue, Succeeded()) 210 << "Failed to get value from " << Str; 211 APInt ResValue = ResultValue->getAPIntValue(); 212 ASSERT_EQ(ResValue.isNegative(), ExpectedVal < 0) 213 << "Value for " << Str << " is not " << ExpectedVal; 214 if (ResValue.isNegative()) 215 EXPECT_EQ(ResValue.getSExtValue(), static_cast<int64_t>(ExpectedVal)); 216 else 217 EXPECT_EQ(ResValue.getZExtValue(), static_cast<uint64_t>(ExpectedVal)); 218 } 219 220 void checkValueFromStringReprFailure( 221 StringRef Str, StringRef ErrorStr = "unable to represent numeric value") { 222 Expected<ExpressionValue> ResultValue = getValueFromStringReprFailure(Str); 223 expectDiagnosticError(ErrorStr, ResultValue.takeError()); 224 } 225 }; 226 227 TEST_P(ExpressionFormatParameterisedFixture, FormatGetWildcardRegex) { 228 // Wildcard regex is valid. 229 Expected<std::string> WildcardPattern = Format.getWildcardRegex(); 230 ASSERT_THAT_EXPECTED(WildcardPattern, Succeeded()); 231 WildcardRegex = Regex((Twine("^") + *WildcardPattern + "$").str()); 232 ASSERT_TRUE(WildcardRegex.isValid()); 233 234 // Does not match empty string. 235 checkWildcardRegexMatchFailure(""); 236 237 // Matches all decimal digits, matches several of them and match 0x prefix 238 // if and only if AlternateForm is true. 239 StringRef LongNumber = "12345678901234567890"; 240 StringRef PrefixedLongNumber = "0x12345678901234567890"; 241 if (AlternateForm) { 242 checkWildcardRegexMatch(PrefixedLongNumber); 243 checkWildcardRegexMatchFailure(LongNumber); 244 } else { 245 checkWildcardRegexMatch(LongNumber); 246 checkWildcardRegexMatchFailure(PrefixedLongNumber); 247 } 248 249 // Matches negative digits. 250 LongNumber = "-12345678901234567890"; 251 if (Signed) 252 checkWildcardRegexMatch(LongNumber); 253 else 254 checkWildcardRegexMatchFailure(LongNumber); 255 256 // Check non digits or digits with wrong casing are not matched. 257 std::string LongNumberStr; 258 if (AllowHex) { 259 LongNumberStr = addBasePrefix(AcceptedHexOnlyDigits); 260 checkWildcardRegexMatch(LongNumberStr, 16); 261 checkPerCharWildcardRegexMatchFailure(RefusedHexOnlyDigits); 262 } 263 checkPerCharWildcardRegexMatchFailure(FirstInvalidCharDigits); 264 265 // Check leading zeros are only accepted if number of digits is less than the 266 // precision. 267 LongNumber = "01234567890123456789"; 268 if (Precision) { 269 LongNumberStr = addBasePrefix(LongNumber.take_front(Precision)); 270 checkWildcardRegexMatch(LongNumberStr); 271 LongNumberStr = addBasePrefix(LongNumber.take_front(Precision - 1)); 272 checkWildcardRegexMatchFailure(LongNumberStr); 273 if (Precision < LongNumber.size()) { 274 LongNumberStr = addBasePrefix(LongNumber.take_front(Precision + 1)); 275 checkWildcardRegexMatchFailure(LongNumberStr); 276 } 277 } else { 278 LongNumberStr = addBasePrefix(LongNumber); 279 checkWildcardRegexMatch(LongNumberStr); 280 } 281 } 282 283 TEST_P(ExpressionFormatParameterisedFixture, FormatGetMatchingString) { 284 checkMatchingString(0, addBasePrefix(padWithLeadingZeros("0"))); 285 checkMatchingString(9, addBasePrefix(padWithLeadingZeros("9"))); 286 287 if (Signed) { 288 checkMatchingString(-5, padWithLeadingZeros("-5")); 289 checkMatchingStringFailure(MaxUint64); 290 checkMatchingString(MaxInt64, padWithLeadingZeros(MaxInt64Str)); 291 checkMatchingString(MinInt64, padWithLeadingZeros(MinInt64Str)); 292 } else { 293 checkMatchingStringFailure(-5); 294 checkMatchingString(MaxUint64, 295 addBasePrefix(padWithLeadingZeros(MaxUint64Str))); 296 checkMatchingString(MaxInt64, 297 addBasePrefix(padWithLeadingZeros(MaxInt64Str))); 298 checkMatchingStringFailure(MinInt64); 299 } 300 301 checkMatchingString(10, addBasePrefix(padWithLeadingZeros(TenStr))); 302 checkMatchingString(15, addBasePrefix(padWithLeadingZeros(FifteenStr))); 303 } 304 305 TEST_P(ExpressionFormatParameterisedFixture, FormatValueFromStringRepr) { 306 checkValueFromStringRepr(addBasePrefix("0"), 0); 307 checkValueFromStringRepr(addBasePrefix("9"), 9); 308 309 if (Signed) { 310 checkValueFromStringRepr("-5", -5); 311 checkValueFromStringReprFailure(MaxUint64Str); 312 } else { 313 checkValueFromStringRepr(addBasePrefix(MaxUint64Str), MaxUint64); 314 } 315 316 checkValueFromStringRepr(addBasePrefix(TenStr), 10); 317 checkValueFromStringRepr(addBasePrefix(FifteenStr), 15); 318 319 // Wrong casing is not tested because valueFromStringRepr() relies on 320 // StringRef's getAsInteger() which does not allow to restrict casing. 321 checkValueFromStringReprFailure(addBasePrefix("G")); 322 } 323 324 TEST_P(ExpressionFormatParameterisedFixture, FormatBoolOperator) { 325 EXPECT_TRUE(bool(Format)); 326 } 327 328 INSTANTIATE_TEST_SUITE_P( 329 AllowedExplicitExpressionFormat, ExpressionFormatParameterisedFixture, 330 ::testing::Values( 331 std::make_tuple(ExpressionFormat::Kind::Unsigned, 0, false), 332 std::make_tuple(ExpressionFormat::Kind::Signed, 0, false), 333 std::make_tuple(ExpressionFormat::Kind::HexLower, 0, false), 334 std::make_tuple(ExpressionFormat::Kind::HexLower, 0, true), 335 std::make_tuple(ExpressionFormat::Kind::HexUpper, 0, false), 336 std::make_tuple(ExpressionFormat::Kind::HexUpper, 0, true), 337 338 std::make_tuple(ExpressionFormat::Kind::Unsigned, 1, false), 339 std::make_tuple(ExpressionFormat::Kind::Signed, 1, false), 340 std::make_tuple(ExpressionFormat::Kind::HexLower, 1, false), 341 std::make_tuple(ExpressionFormat::Kind::HexLower, 1, true), 342 std::make_tuple(ExpressionFormat::Kind::HexUpper, 1, false), 343 std::make_tuple(ExpressionFormat::Kind::HexUpper, 1, true), 344 345 std::make_tuple(ExpressionFormat::Kind::Unsigned, 16, false), 346 std::make_tuple(ExpressionFormat::Kind::Signed, 16, false), 347 std::make_tuple(ExpressionFormat::Kind::HexLower, 16, false), 348 std::make_tuple(ExpressionFormat::Kind::HexLower, 16, true), 349 std::make_tuple(ExpressionFormat::Kind::HexUpper, 16, false), 350 std::make_tuple(ExpressionFormat::Kind::HexUpper, 16, true), 351 352 std::make_tuple(ExpressionFormat::Kind::Unsigned, 20, false), 353 std::make_tuple(ExpressionFormat::Kind::Signed, 20, false))); 354 355 TEST_F(FileCheckTest, NoFormatProperties) { 356 ExpressionFormat NoFormat(ExpressionFormat::Kind::NoFormat); 357 expectError<StringError>("trying to match value with invalid format", 358 NoFormat.getWildcardRegex().takeError()); 359 expectError<StringError>( 360 "trying to match value with invalid format", 361 NoFormat.getMatchingString(ExpressionValue(18u)).takeError()); 362 EXPECT_FALSE(bool(NoFormat)); 363 } 364 365 TEST_F(FileCheckTest, FormatEqualityOperators) { 366 ExpressionFormat UnsignedFormat(ExpressionFormat::Kind::Unsigned); 367 ExpressionFormat UnsignedFormat2(ExpressionFormat::Kind::Unsigned); 368 EXPECT_TRUE(UnsignedFormat == UnsignedFormat2); 369 EXPECT_FALSE(UnsignedFormat != UnsignedFormat2); 370 371 ExpressionFormat HexLowerFormat(ExpressionFormat::Kind::HexLower); 372 EXPECT_FALSE(UnsignedFormat == HexLowerFormat); 373 EXPECT_TRUE(UnsignedFormat != HexLowerFormat); 374 375 ExpressionFormat NoFormat(ExpressionFormat::Kind::NoFormat); 376 ExpressionFormat NoFormat2(ExpressionFormat::Kind::NoFormat); 377 EXPECT_FALSE(NoFormat == NoFormat2); 378 EXPECT_TRUE(NoFormat != NoFormat2); 379 } 380 381 TEST_F(FileCheckTest, FormatKindEqualityOperators) { 382 ExpressionFormat UnsignedFormat(ExpressionFormat::Kind::Unsigned); 383 EXPECT_TRUE(UnsignedFormat == ExpressionFormat::Kind::Unsigned); 384 EXPECT_FALSE(UnsignedFormat != ExpressionFormat::Kind::Unsigned); 385 EXPECT_FALSE(UnsignedFormat == ExpressionFormat::Kind::HexLower); 386 EXPECT_TRUE(UnsignedFormat != ExpressionFormat::Kind::HexLower); 387 ExpressionFormat NoFormat(ExpressionFormat::Kind::NoFormat); 388 EXPECT_TRUE(NoFormat == ExpressionFormat::Kind::NoFormat); 389 EXPECT_FALSE(NoFormat != ExpressionFormat::Kind::NoFormat); 390 } 391 392 template <class T1, class T2> 393 static Expected<ExpressionValue> doValueOperation(binop_eval_t Operation, 394 T1 LeftValue, T2 RightValue) { 395 ExpressionValue LeftOperand(LeftValue); 396 ExpressionValue RightOperand(RightValue); 397 return Operation(LeftOperand, RightOperand); 398 } 399 400 template <class T> 401 static void expectValueEqual(ExpressionValue ActualValue, T ExpectedValue) { 402 APInt Value = ActualValue.getAPIntValue(); 403 EXPECT_EQ(ExpectedValue < 0, Value.isNegative()); 404 if (ExpectedValue < 0) 405 EXPECT_EQ(Value.getSExtValue(), static_cast<int64_t>(ExpectedValue)); 406 else 407 EXPECT_EQ(Value.getZExtValue(), static_cast<uint64_t>(ExpectedValue)); 408 } 409 410 template <class T1, class T2, class TR> 411 static void expectOperationValueResult(binop_eval_t Operation, T1 LeftValue, 412 T2 RightValue, TR ResultValue) { 413 Expected<ExpressionValue> OperationResult = 414 doValueOperation(Operation, LeftValue, RightValue); 415 ASSERT_THAT_EXPECTED(OperationResult, Succeeded()); 416 expectValueEqual(*OperationResult, ResultValue); 417 } 418 419 template <class T1, class T2> 420 static void expectOperationValueResult(binop_eval_t Operation, T1 LeftValue, 421 T2 RightValue) { 422 expectError<OverflowError>( 423 "overflow error", 424 doValueOperation(Operation, LeftValue, RightValue).takeError()); 425 } 426 427 TEST_F(FileCheckTest, ExpressionValueAddition) { 428 // Test both negative values. 429 expectOperationValueResult(operator+, -10, -10, -20); 430 431 // Test both negative values with underflow. 432 expectOperationValueResult(operator+, MinInt64, -1); 433 expectOperationValueResult(operator+, MinInt64, MinInt64); 434 435 // Test negative and positive value. 436 expectOperationValueResult(operator+, -10, 10, 0); 437 expectOperationValueResult(operator+, -10, 11, 1); 438 expectOperationValueResult(operator+, -11, 10, -1); 439 440 // Test positive and negative value. 441 expectOperationValueResult(operator+, 10, -10, 0); 442 expectOperationValueResult(operator+, 10, -11, -1); 443 expectOperationValueResult(operator+, 11, -10, 1); 444 445 // Test both positive values. 446 expectOperationValueResult(operator+, 10, 10, 20); 447 448 // Test both positive values with overflow. 449 expectOperationValueResult(operator+, MaxUint64, 1); 450 expectOperationValueResult(operator+, MaxUint64, MaxUint64); 451 } 452 453 TEST_F(FileCheckTest, ExpressionValueSubtraction) { 454 // Test negative value and value bigger than int64_t max. 455 expectOperationValueResult(operator-, -10, MaxUint64); 456 457 // Test negative and positive value with underflow. 458 expectOperationValueResult(operator-, MinInt64, 1); 459 460 // Test negative and positive value. 461 expectOperationValueResult(operator-, -10, 10, -20); 462 463 // Test both negative values. 464 expectOperationValueResult(operator-, -10, -10, 0); 465 expectOperationValueResult(operator-, -11, -10, -1); 466 expectOperationValueResult(operator-, -10, -11, 1); 467 468 // Test positive and negative values. 469 expectOperationValueResult(operator-, 10, -10, 20); 470 471 // Test both positive values with result positive. 472 expectOperationValueResult(operator-, 10, 5, 5); 473 474 // Test both positive values with underflow. 475 expectOperationValueResult(operator-, 0, MaxUint64); 476 expectOperationValueResult(operator-, 0, 477 static_cast<uint64_t>(-(MinInt64 + 10)) + 11); 478 479 // Test both positive values with result < -(max int64_t) 480 expectOperationValueResult(operator-, 10, 481 static_cast<uint64_t>(MaxInt64) + 11, 482 -MaxInt64 - 1); 483 484 // Test both positive values with 0 > result > -(max int64_t) 485 expectOperationValueResult(operator-, 10, 11, -1); 486 } 487 488 TEST_F(FileCheckTest, ExpressionValueMultiplication) { 489 // Test mixed signed values. 490 expectOperationValueResult(operator*, -3, 10, -30); 491 expectOperationValueResult(operator*, 2, -17, -34); 492 expectOperationValueResult(operator*, 0, MinInt64, 0); 493 expectOperationValueResult(operator*, MinInt64, 1, MinInt64); 494 expectOperationValueResult(operator*, 1, MinInt64, MinInt64); 495 expectOperationValueResult(operator*, MaxInt64, -1, -MaxInt64); 496 expectOperationValueResult(operator*, -1, MaxInt64, -MaxInt64); 497 498 // Test both negative values. 499 expectOperationValueResult(operator*, -3, -10, 30); 500 expectOperationValueResult(operator*, -2, -17, 34); 501 expectOperationValueResult(operator*, MinInt64, -1, AbsoluteMinInt64); 502 503 // Test both positive values. 504 expectOperationValueResult(operator*, 3, 10, 30); 505 expectOperationValueResult(operator*, 2, 17, 34); 506 expectOperationValueResult(operator*, 0, MaxUint64, 0); 507 508 // Test negative results that underflow. 509 expectOperationValueResult(operator*, -10, MaxInt64); 510 expectOperationValueResult(operator*, MaxInt64, -10); 511 expectOperationValueResult(operator*, 10, MinInt64); 512 expectOperationValueResult(operator*, MinInt64, 10); 513 expectOperationValueResult(operator*, -1, MaxUint64); 514 expectOperationValueResult(operator*, MaxUint64, -1); 515 expectOperationValueResult(operator*, -1, AbsoluteMaxInt64 + 2); 516 expectOperationValueResult(operator*, AbsoluteMaxInt64 + 2, -1); 517 518 // Test positive results that overflow. 519 expectOperationValueResult(operator*, 10, MaxUint64); 520 expectOperationValueResult(operator*, MaxUint64, 10); 521 expectOperationValueResult(operator*, MinInt64, -10); 522 expectOperationValueResult(operator*, -10, MinInt64); 523 } 524 525 TEST_F(FileCheckTest, ExpressionValueDivision) { 526 // Test mixed signed values. 527 expectOperationValueResult(operator/, -30, 10, -3); 528 expectOperationValueResult(operator/, 34, -17, -2); 529 expectOperationValueResult(operator/, 0, -10, 0); 530 expectOperationValueResult(operator/, MinInt64, 1, MinInt64); 531 expectOperationValueResult(operator/, MaxInt64, -1, -MaxInt64); 532 expectOperationValueResult(operator/, -MaxInt64, 1, -MaxInt64); 533 534 // Test both negative values. 535 expectOperationValueResult(operator/, -30, -10, 3); 536 expectOperationValueResult(operator/, -34, -17, 2); 537 538 // Test both positive values. 539 expectOperationValueResult(operator/, 30, 10, 3); 540 expectOperationValueResult(operator/, 34, 17, 2); 541 expectOperationValueResult(operator/, 0, 10, 0); 542 543 // Test divide by zero. 544 expectOperationValueResult(operator/, -10, 0); 545 expectOperationValueResult(operator/, 10, 0); 546 expectOperationValueResult(operator/, 0, 0); 547 548 // Test negative result that underflows. 549 expectOperationValueResult(operator/, MaxUint64, -1); 550 expectOperationValueResult(operator/, AbsoluteMaxInt64 + 2, -1); 551 } 552 553 TEST_F(FileCheckTest, Literal) { 554 SourceMgr SM; 555 556 // Eval returns the literal's value. 557 ExpressionLiteral Ten(bufferize(SM, "10"), 10u); 558 Expected<ExpressionValue> Value = Ten.eval(); 559 ASSERT_THAT_EXPECTED(Value, Succeeded()); 560 EXPECT_EQ(10, Value->getAPIntValue().getSExtValue()); 561 Expected<ExpressionFormat> ImplicitFormat = Ten.getImplicitFormat(SM); 562 ASSERT_THAT_EXPECTED(ImplicitFormat, Succeeded()); 563 EXPECT_EQ(*ImplicitFormat, ExpressionFormat::Kind::NoFormat); 564 565 // Min value can be correctly represented. 566 ExpressionLiteral Min(bufferize(SM, std::to_string(MinInt64)), MinInt64); 567 Value = Min.eval(); 568 ASSERT_TRUE(bool(Value)); 569 EXPECT_EQ(MinInt64, Value->getAPIntValue().getSExtValue()); 570 571 // Max value can be correctly represented. 572 ExpressionLiteral Max(bufferize(SM, std::to_string(MaxUint64)), MaxUint64); 573 Value = Max.eval(); 574 ASSERT_THAT_EXPECTED(Value, Succeeded()); 575 EXPECT_EQ(MaxUint64, Value->getAPIntValue().getZExtValue()); 576 } 577 578 TEST_F(FileCheckTest, Expression) { 579 SourceMgr SM; 580 581 std::unique_ptr<ExpressionLiteral> Ten = 582 std::make_unique<ExpressionLiteral>(bufferize(SM, "10"), 10u); 583 ExpressionLiteral *TenPtr = Ten.get(); 584 Expression Expr(std::move(Ten), 585 ExpressionFormat(ExpressionFormat::Kind::HexLower)); 586 EXPECT_EQ(Expr.getAST(), TenPtr); 587 EXPECT_EQ(Expr.getFormat(), ExpressionFormat::Kind::HexLower); 588 } 589 590 static void 591 expectUndefErrors(std::unordered_set<std::string> ExpectedUndefVarNames, 592 Error Err) { 593 EXPECT_THAT_ERROR(handleErrors(std::move(Err), 594 [&](const UndefVarError &E) { 595 EXPECT_EQ(ExpectedUndefVarNames.erase( 596 std::string(E.getVarName())), 597 1U); 598 }), 599 Succeeded()); 600 EXPECT_TRUE(ExpectedUndefVarNames.empty()) << toString(ExpectedUndefVarNames); 601 } 602 603 TEST_F(FileCheckTest, NumericVariable) { 604 SourceMgr SM; 605 606 // Undefined variable: getValue and eval fail, error returned by eval holds 607 // the name of the undefined variable. 608 NumericVariable FooVar("FOO", 609 ExpressionFormat(ExpressionFormat::Kind::Unsigned), 1); 610 EXPECT_EQ("FOO", FooVar.getName()); 611 EXPECT_EQ(FooVar.getImplicitFormat(), ExpressionFormat::Kind::Unsigned); 612 NumericVariableUse FooVarUse("FOO", &FooVar); 613 Expected<ExpressionFormat> ImplicitFormat = FooVarUse.getImplicitFormat(SM); 614 ASSERT_THAT_EXPECTED(ImplicitFormat, Succeeded()); 615 EXPECT_EQ(*ImplicitFormat, ExpressionFormat::Kind::Unsigned); 616 EXPECT_FALSE(FooVar.getValue()); 617 Expected<ExpressionValue> EvalResult = FooVarUse.eval(); 618 expectUndefErrors({"FOO"}, EvalResult.takeError()); 619 620 // Defined variable without string: only getValue and eval return value set. 621 FooVar.setValue(ExpressionValue(42u)); 622 std::optional<ExpressionValue> Value = FooVar.getValue(); 623 ASSERT_TRUE(Value); 624 EXPECT_EQ(42, Value->getAPIntValue().getSExtValue()); 625 EXPECT_FALSE(FooVar.getStringValue()); 626 EvalResult = FooVarUse.eval(); 627 ASSERT_THAT_EXPECTED(EvalResult, Succeeded()); 628 EXPECT_EQ(42, EvalResult->getAPIntValue().getSExtValue()); 629 630 // Defined variable with string: getValue, eval, and getStringValue return 631 // value set. 632 StringRef StringValue = "925"; 633 FooVar.setValue(ExpressionValue(925u), StringValue); 634 Value = FooVar.getValue(); 635 ASSERT_TRUE(Value); 636 EXPECT_EQ(925, Value->getAPIntValue().getSExtValue()); 637 // getStringValue should return the same memory not just the same characters. 638 EXPECT_EQ(StringValue.begin(), FooVar.getStringValue()->begin()); 639 EXPECT_EQ(StringValue.end(), FooVar.getStringValue()->end()); 640 EvalResult = FooVarUse.eval(); 641 ASSERT_THAT_EXPECTED(EvalResult, Succeeded()); 642 EXPECT_EQ(925, EvalResult->getAPIntValue().getSExtValue()); 643 EXPECT_EQ(925, EvalResult->getAPIntValue().getSExtValue()); 644 645 // Clearing variable: getValue and eval fail. Error returned by eval holds 646 // the name of the cleared variable. 647 FooVar.clearValue(); 648 EXPECT_FALSE(FooVar.getValue()); 649 EXPECT_FALSE(FooVar.getStringValue()); 650 EvalResult = FooVarUse.eval(); 651 expectUndefErrors({"FOO"}, EvalResult.takeError()); 652 } 653 654 TEST_F(FileCheckTest, Binop) { 655 SourceMgr SM; 656 657 StringRef ExprStr = bufferize(SM, "FOO+BAR"); 658 StringRef FooStr = ExprStr.take_front(3); 659 NumericVariable FooVar(FooStr, 660 ExpressionFormat(ExpressionFormat::Kind::Unsigned), 1); 661 FooVar.setValue(ExpressionValue(42u)); 662 std::unique_ptr<NumericVariableUse> FooVarUse = 663 std::make_unique<NumericVariableUse>(FooStr, &FooVar); 664 StringRef BarStr = ExprStr.take_back(3); 665 NumericVariable BarVar(BarStr, 666 ExpressionFormat(ExpressionFormat::Kind::Unsigned), 2); 667 BarVar.setValue(ExpressionValue(18u)); 668 std::unique_ptr<NumericVariableUse> BarVarUse = 669 std::make_unique<NumericVariableUse>(BarStr, &BarVar); 670 binop_eval_t doAdd = operator+; 671 BinaryOperation Binop(ExprStr, doAdd, std::move(FooVarUse), 672 std::move(BarVarUse)); 673 674 // Defined variables: eval returns right value; implicit format is as 675 // expected. 676 Expected<ExpressionValue> Value = Binop.eval(); 677 ASSERT_THAT_EXPECTED(Value, Succeeded()); 678 EXPECT_EQ(60, Value->getAPIntValue().getSExtValue()); 679 Expected<ExpressionFormat> ImplicitFormat = Binop.getImplicitFormat(SM); 680 ASSERT_THAT_EXPECTED(ImplicitFormat, Succeeded()); 681 EXPECT_EQ(*ImplicitFormat, ExpressionFormat::Kind::Unsigned); 682 683 // 1 undefined variable: eval fails, error contains name of undefined 684 // variable. 685 FooVar.clearValue(); 686 Value = Binop.eval(); 687 expectUndefErrors({"FOO"}, Value.takeError()); 688 689 // 2 undefined variables: eval fails, error contains names of all undefined 690 // variables. 691 BarVar.clearValue(); 692 Value = Binop.eval(); 693 expectUndefErrors({"FOO", "BAR"}, Value.takeError()); 694 695 // Literal + Variable has format of variable. 696 ExprStr = bufferize(SM, "FOO+18"); 697 FooStr = ExprStr.take_front(3); 698 StringRef EighteenStr = ExprStr.take_back(2); 699 FooVarUse = std::make_unique<NumericVariableUse>(FooStr, &FooVar); 700 std::unique_ptr<ExpressionLiteral> Eighteen = 701 std::make_unique<ExpressionLiteral>(EighteenStr, 18u); 702 Binop = BinaryOperation(ExprStr, doAdd, std::move(FooVarUse), 703 std::move(Eighteen)); 704 ImplicitFormat = Binop.getImplicitFormat(SM); 705 ASSERT_THAT_EXPECTED(ImplicitFormat, Succeeded()); 706 EXPECT_EQ(*ImplicitFormat, ExpressionFormat::Kind::Unsigned); 707 ExprStr = bufferize(SM, "18+FOO"); 708 FooStr = ExprStr.take_back(3); 709 EighteenStr = ExprStr.take_front(2); 710 FooVarUse = std::make_unique<NumericVariableUse>(FooStr, &FooVar); 711 Eighteen = std::make_unique<ExpressionLiteral>(EighteenStr, 18u); 712 Binop = BinaryOperation(ExprStr, doAdd, std::move(Eighteen), 713 std::move(FooVarUse)); 714 ImplicitFormat = Binop.getImplicitFormat(SM); 715 ASSERT_THAT_EXPECTED(ImplicitFormat, Succeeded()); 716 EXPECT_EQ(*ImplicitFormat, ExpressionFormat::Kind::Unsigned); 717 718 // Variables with different implicit format conflict. 719 ExprStr = bufferize(SM, "FOO+BAZ"); 720 FooStr = ExprStr.take_front(3); 721 StringRef BazStr = ExprStr.take_back(3); 722 NumericVariable BazVar(BazStr, 723 ExpressionFormat(ExpressionFormat::Kind::HexLower), 3); 724 FooVarUse = std::make_unique<NumericVariableUse>(FooStr, &FooVar); 725 std::unique_ptr<NumericVariableUse> BazVarUse = 726 std::make_unique<NumericVariableUse>(BazStr, &BazVar); 727 Binop = BinaryOperation(ExprStr, doAdd, std::move(FooVarUse), 728 std::move(BazVarUse)); 729 ImplicitFormat = Binop.getImplicitFormat(SM); 730 expectDiagnosticError( 731 "implicit format conflict between 'FOO' (%u) and 'BAZ' (%x), " 732 "need an explicit format specifier", 733 ImplicitFormat.takeError()); 734 735 // All variable conflicts are reported. 736 ExprStr = bufferize(SM, "(FOO+BAZ)+(FOO+QUUX)"); 737 StringRef Paren1ExprStr = ExprStr.substr(1, 7); 738 FooStr = Paren1ExprStr.take_front(3); 739 BazStr = Paren1ExprStr.take_back(3); 740 StringRef Paren2ExprStr = ExprStr.substr(ExprStr.rfind('(') + 1, 8); 741 StringRef FooStr2 = Paren2ExprStr.take_front(3); 742 StringRef QuuxStr = Paren2ExprStr.take_back(4); 743 FooVarUse = std::make_unique<NumericVariableUse>(FooStr, &FooVar); 744 BazVarUse = std::make_unique<NumericVariableUse>(BazStr, &BazVar); 745 std::unique_ptr<NumericVariableUse> FooVarUse2 = 746 std::make_unique<NumericVariableUse>(FooStr2, &FooVar); 747 NumericVariable QuuxVar( 748 QuuxStr, ExpressionFormat(ExpressionFormat::Kind::HexLower), 4); 749 std::unique_ptr<NumericVariableUse> QuuxVarUse = 750 std::make_unique<NumericVariableUse>(QuuxStr, &QuuxVar); 751 std::unique_ptr<BinaryOperation> Binop1 = std::make_unique<BinaryOperation>( 752 ExprStr.take_front(9), doAdd, std::move(FooVarUse), std::move(BazVarUse)); 753 std::unique_ptr<BinaryOperation> Binop2 = std::make_unique<BinaryOperation>( 754 ExprStr.take_back(10), doAdd, std::move(FooVarUse2), 755 std::move(QuuxVarUse)); 756 std::unique_ptr<BinaryOperation> OuterBinop = 757 std::make_unique<BinaryOperation>(ExprStr, doAdd, std::move(Binop1), 758 std::move(Binop2)); 759 ImplicitFormat = OuterBinop->getImplicitFormat(SM); 760 expectSameErrors<ErrorDiagnostic>( 761 {("implicit format conflict between 'FOO' (%u) and 'BAZ' (%x), need an " 762 "explicit format specifier"), 763 ("implicit format conflict between 'FOO' (%u) and 'QUUX' (%x), need an " 764 "explicit format specifier")}, 765 ImplicitFormat.takeError()); 766 } 767 768 TEST_F(FileCheckTest, ValidVarNameStart) { 769 EXPECT_TRUE(Pattern::isValidVarNameStart('a')); 770 EXPECT_TRUE(Pattern::isValidVarNameStart('G')); 771 EXPECT_TRUE(Pattern::isValidVarNameStart('_')); 772 EXPECT_FALSE(Pattern::isValidVarNameStart('2')); 773 EXPECT_FALSE(Pattern::isValidVarNameStart('$')); 774 EXPECT_FALSE(Pattern::isValidVarNameStart('@')); 775 EXPECT_FALSE(Pattern::isValidVarNameStart('+')); 776 EXPECT_FALSE(Pattern::isValidVarNameStart('-')); 777 EXPECT_FALSE(Pattern::isValidVarNameStart(':')); 778 } 779 780 TEST_F(FileCheckTest, ParseVar) { 781 SourceMgr SM; 782 StringRef OrigVarName = bufferize(SM, "GoodVar42"); 783 StringRef VarName = OrigVarName; 784 Expected<Pattern::VariableProperties> ParsedVarResult = 785 Pattern::parseVariable(VarName, SM); 786 ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded()); 787 EXPECT_EQ(ParsedVarResult->Name, OrigVarName); 788 EXPECT_TRUE(VarName.empty()); 789 EXPECT_FALSE(ParsedVarResult->IsPseudo); 790 791 VarName = OrigVarName = bufferize(SM, "$GoodGlobalVar"); 792 ParsedVarResult = Pattern::parseVariable(VarName, SM); 793 ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded()); 794 EXPECT_EQ(ParsedVarResult->Name, OrigVarName); 795 EXPECT_TRUE(VarName.empty()); 796 EXPECT_FALSE(ParsedVarResult->IsPseudo); 797 798 VarName = OrigVarName = bufferize(SM, "@GoodPseudoVar"); 799 ParsedVarResult = Pattern::parseVariable(VarName, SM); 800 ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded()); 801 EXPECT_EQ(ParsedVarResult->Name, OrigVarName); 802 EXPECT_TRUE(VarName.empty()); 803 EXPECT_TRUE(ParsedVarResult->IsPseudo); 804 805 VarName = bufferize(SM, "42BadVar"); 806 ParsedVarResult = Pattern::parseVariable(VarName, SM); 807 expectDiagnosticError("invalid variable name", ParsedVarResult.takeError()); 808 809 VarName = bufferize(SM, "$@"); 810 ParsedVarResult = Pattern::parseVariable(VarName, SM); 811 expectDiagnosticError("invalid variable name", ParsedVarResult.takeError()); 812 813 VarName = OrigVarName = bufferize(SM, "B@dVar"); 814 ParsedVarResult = Pattern::parseVariable(VarName, SM); 815 ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded()); 816 EXPECT_EQ(VarName, OrigVarName.substr(1)); 817 EXPECT_EQ(ParsedVarResult->Name, "B"); 818 EXPECT_FALSE(ParsedVarResult->IsPseudo); 819 820 VarName = OrigVarName = bufferize(SM, "B$dVar"); 821 ParsedVarResult = Pattern::parseVariable(VarName, SM); 822 ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded()); 823 EXPECT_EQ(VarName, OrigVarName.substr(1)); 824 EXPECT_EQ(ParsedVarResult->Name, "B"); 825 EXPECT_FALSE(ParsedVarResult->IsPseudo); 826 827 VarName = bufferize(SM, "BadVar+"); 828 ParsedVarResult = Pattern::parseVariable(VarName, SM); 829 ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded()); 830 EXPECT_EQ(VarName, "+"); 831 EXPECT_EQ(ParsedVarResult->Name, "BadVar"); 832 EXPECT_FALSE(ParsedVarResult->IsPseudo); 833 834 VarName = bufferize(SM, "BadVar-"); 835 ParsedVarResult = Pattern::parseVariable(VarName, SM); 836 ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded()); 837 EXPECT_EQ(VarName, "-"); 838 EXPECT_EQ(ParsedVarResult->Name, "BadVar"); 839 EXPECT_FALSE(ParsedVarResult->IsPseudo); 840 841 VarName = bufferize(SM, "BadVar:"); 842 ParsedVarResult = Pattern::parseVariable(VarName, SM); 843 ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded()); 844 EXPECT_EQ(VarName, ":"); 845 EXPECT_EQ(ParsedVarResult->Name, "BadVar"); 846 EXPECT_FALSE(ParsedVarResult->IsPseudo); 847 } 848 849 static void expectNotFoundError(Error Err) { 850 expectError<NotFoundError>("String not found in input", std::move(Err)); 851 } 852 853 class PatternTester { 854 private: 855 size_t LineNumber = 1; 856 SourceMgr SM; 857 FileCheckRequest Req; 858 FileCheckPatternContext Context; 859 Pattern P{Check::CheckPlain, &Context, LineNumber}; 860 861 public: 862 PatternTester() { 863 std::vector<StringRef> GlobalDefines = {"#FOO=42", "BAR=BAZ", "#add=7"}; 864 // An ASSERT_FALSE would make more sense but cannot be used in a 865 // constructor. 866 EXPECT_THAT_ERROR(Context.defineCmdlineVariables(GlobalDefines, SM), 867 Succeeded()); 868 Context.createLineVariable(); 869 // Call parsePattern to have @LINE defined. 870 P.parsePattern("N/A", "CHECK", SM, Req); 871 // parsePattern does not expect to be called twice for the same line and 872 // will set FixedStr and RegExStr incorrectly if it is. Therefore prepare 873 // a pattern for a different line. 874 initNextPattern(); 875 } 876 877 void initNextPattern() { 878 P = Pattern(Check::CheckPlain, &Context, ++LineNumber); 879 } 880 881 size_t getLineNumber() const { return LineNumber; } 882 883 Expected<std::unique_ptr<Expression>> 884 parseSubst(StringRef Expr, bool IsLegacyLineExpr = false) { 885 StringRef ExprBufferRef = bufferize(SM, Expr); 886 std::optional<NumericVariable *> DefinedNumericVariable; 887 return P.parseNumericSubstitutionBlock( 888 ExprBufferRef, DefinedNumericVariable, IsLegacyLineExpr, LineNumber, 889 &Context, SM); 890 } 891 892 bool parsePattern(StringRef Pattern) { 893 StringRef PatBufferRef = bufferize(SM, Pattern); 894 return P.parsePattern(PatBufferRef, "CHECK", SM, Req); 895 } 896 897 Expected<size_t> match(StringRef Buffer) { 898 StringRef BufferRef = bufferize(SM, Buffer); 899 Pattern::MatchResult Res = P.match(BufferRef, SM); 900 if (Res.TheError) 901 return std::move(Res.TheError); 902 return Res.TheMatch->Pos; 903 } 904 905 void printVariableDefs(FileCheckDiag::MatchType MatchTy, 906 std::vector<FileCheckDiag> &Diags) { 907 P.printVariableDefs(SM, MatchTy, &Diags); 908 } 909 }; 910 911 TEST_F(FileCheckTest, ParseNumericSubstitutionBlock) { 912 PatternTester Tester; 913 914 // Variable definition. 915 916 expectDiagnosticError("invalid variable name", 917 Tester.parseSubst("%VAR:").takeError()); 918 919 expectDiagnosticError("definition of pseudo numeric variable unsupported", 920 Tester.parseSubst("@LINE:").takeError()); 921 922 expectDiagnosticError("string variable with name 'BAR' already exists", 923 Tester.parseSubst("BAR:").takeError()); 924 925 expectDiagnosticError("unexpected characters after numeric variable name", 926 Tester.parseSubst("VAR GARBAGE:").takeError()); 927 928 // Change of format. 929 expectDiagnosticError("format different from previous variable definition", 930 Tester.parseSubst("%X,FOO:").takeError()); 931 932 // Invalid format. 933 expectDiagnosticError("invalid matching format specification in expression", 934 Tester.parseSubst("X,VAR1:").takeError()); 935 expectDiagnosticError("invalid format specifier in expression", 936 Tester.parseSubst("%F,VAR1:").takeError()); 937 expectDiagnosticError("invalid matching format specification in expression", 938 Tester.parseSubst("%X a,VAR1:").takeError()); 939 940 // Acceptable variable definition. 941 EXPECT_THAT_EXPECTED(Tester.parseSubst("VAR1:"), Succeeded()); 942 EXPECT_THAT_EXPECTED(Tester.parseSubst(" VAR2:"), Succeeded()); 943 EXPECT_THAT_EXPECTED(Tester.parseSubst("VAR3 :"), Succeeded()); 944 EXPECT_THAT_EXPECTED(Tester.parseSubst("VAR3: "), Succeeded()); 945 946 // Acceptable variable definition with format specifier. Use parsePattern for 947 // variables whose definition needs to be visible for later checks. 948 EXPECT_FALSE(Tester.parsePattern("[[#%u, VAR_UNSIGNED:]]")); 949 EXPECT_FALSE(Tester.parsePattern("[[#%x, VAR_LOWER_HEX:]]")); 950 EXPECT_THAT_EXPECTED(Tester.parseSubst("%X, VAR_UPPER_HEX:"), Succeeded()); 951 952 // Acceptable variable definition with precision specifier. 953 EXPECT_FALSE(Tester.parsePattern("[[#%.8X, PADDED_ADDR:]]")); 954 EXPECT_FALSE(Tester.parsePattern("[[#%.8, PADDED_NUM:]]")); 955 956 // Acceptable variable definition in alternate form. 957 EXPECT_THAT_EXPECTED(Tester.parseSubst("%#x, PREFIXED_ADDR:"), Succeeded()); 958 EXPECT_THAT_EXPECTED(Tester.parseSubst("%#X, PREFIXED_ADDR:"), Succeeded()); 959 960 // Acceptable variable definition in alternate form. 961 expectDiagnosticError("alternate form only supported for hex values", 962 Tester.parseSubst("%#u, PREFIXED_UNSI:").takeError()); 963 expectDiagnosticError("alternate form only supported for hex values", 964 Tester.parseSubst("%#d, PREFIXED_UNSI:").takeError()); 965 966 // Acceptable variable definition from a numeric expression. 967 EXPECT_THAT_EXPECTED(Tester.parseSubst("FOOBAR: FOO+1"), Succeeded()); 968 969 // Numeric expression. Switch to next line to make above valid definition 970 // available in expressions. 971 Tester.initNextPattern(); 972 973 // Invalid variable name. 974 expectDiagnosticError("invalid matching constraint or operand format", 975 Tester.parseSubst("%VAR").takeError()); 976 977 expectDiagnosticError("invalid pseudo numeric variable '@FOO'", 978 Tester.parseSubst("@FOO").takeError()); 979 980 // parsePattern() is used here instead of parseSubst() for the variable to be 981 // recorded in GlobalNumericVariableTable and thus appear defined to 982 // parseNumericVariableUse(). Note that the same pattern object is used for 983 // the parsePattern() and parseSubst() since no initNextPattern() is called, 984 // thus appearing as being on the same line from the pattern's point of view. 985 ASSERT_FALSE(Tester.parsePattern("[[#SAME_LINE_VAR:]]")); 986 expectDiagnosticError("numeric variable 'SAME_LINE_VAR' defined earlier in " 987 "the same CHECK directive", 988 Tester.parseSubst("SAME_LINE_VAR").takeError()); 989 990 // Invalid use of variable defined on the same line from an expression not 991 // using any variable defined on the same line. 992 ASSERT_FALSE(Tester.parsePattern("[[#SAME_LINE_EXPR_VAR:@LINE+1]]")); 993 expectDiagnosticError("numeric variable 'SAME_LINE_EXPR_VAR' defined earlier " 994 "in the same CHECK directive", 995 Tester.parseSubst("SAME_LINE_EXPR_VAR").takeError()); 996 997 // Valid use of undefined variable which creates the variable and record it 998 // in GlobalNumericVariableTable. 999 ASSERT_THAT_EXPECTED(Tester.parseSubst("UNDEF"), Succeeded()); 1000 EXPECT_TRUE(Tester.parsePattern("[[UNDEF:.*]]")); 1001 1002 // Invalid literal. 1003 expectDiagnosticError("unsupported operation 'U'", 1004 Tester.parseSubst("42U").takeError()); 1005 1006 // Valid empty expression. 1007 EXPECT_THAT_EXPECTED(Tester.parseSubst(""), Succeeded()); 1008 1009 // Invalid equality matching constraint with empty expression. 1010 expectDiagnosticError("empty numeric expression should not have a constraint", 1011 Tester.parseSubst("==").takeError()); 1012 1013 // Valid single operand expression. 1014 EXPECT_THAT_EXPECTED(Tester.parseSubst("FOO"), Succeeded()); 1015 EXPECT_THAT_EXPECTED(Tester.parseSubst("18"), Succeeded()); 1016 EXPECT_THAT_EXPECTED(Tester.parseSubst(std::to_string(MaxUint64)), 1017 Succeeded()); 1018 EXPECT_THAT_EXPECTED(Tester.parseSubst("0x12"), Succeeded()); 1019 EXPECT_THAT_EXPECTED(Tester.parseSubst("-30"), Succeeded()); 1020 EXPECT_THAT_EXPECTED(Tester.parseSubst(std::to_string(MinInt64)), 1021 Succeeded()); 1022 1023 // Valid optional matching constraint. 1024 EXPECT_THAT_EXPECTED(Tester.parseSubst("==FOO"), Succeeded()); 1025 1026 // Invalid matching constraint. 1027 expectDiagnosticError("invalid matching constraint or operand format", 1028 Tester.parseSubst("+=FOO").takeError()); 1029 1030 // Invalid format. 1031 expectDiagnosticError("invalid matching format specification in expression", 1032 Tester.parseSubst("X,FOO:").takeError()); 1033 expectDiagnosticError("invalid format specifier in expression", 1034 Tester.parseSubst("%F,FOO").takeError()); 1035 expectDiagnosticError("invalid matching format specification in expression", 1036 Tester.parseSubst("%X a,FOO").takeError()); 1037 1038 // Valid expression with 2 or more operands. 1039 EXPECT_THAT_EXPECTED(Tester.parseSubst("FOO+3"), Succeeded()); 1040 EXPECT_THAT_EXPECTED(Tester.parseSubst("FOO+0xC"), Succeeded()); 1041 EXPECT_THAT_EXPECTED(Tester.parseSubst("FOO-3+FOO"), Succeeded()); 1042 1043 expectDiagnosticError("unsupported operation '/'", 1044 Tester.parseSubst("@LINE/2").takeError()); 1045 1046 expectDiagnosticError("missing operand in expression", 1047 Tester.parseSubst("@LINE+").takeError()); 1048 1049 // Errors in RHS operand are bubbled up by parseBinop() to 1050 // parseNumericSubstitutionBlock(). 1051 expectDiagnosticError("invalid operand format", 1052 Tester.parseSubst("@LINE+%VAR").takeError()); 1053 1054 // Invalid legacy @LINE expression with non literal rhs. 1055 expectDiagnosticError( 1056 "invalid operand format", 1057 Tester.parseSubst("@LINE+@LINE", /*IsLegacyNumExpr=*/true).takeError()); 1058 1059 // Invalid legacy @LINE expression made of a single literal. 1060 expectDiagnosticError( 1061 "invalid variable name", 1062 Tester.parseSubst("2", /*IsLegacyNumExpr=*/true).takeError()); 1063 1064 // Invalid hex literal in legacy @LINE expression. 1065 expectDiagnosticError( 1066 "unexpected characters at end of expression 'xC'", 1067 Tester.parseSubst("@LINE+0xC", /*LegacyLineExpr=*/true).takeError()); 1068 1069 // Valid expression with format specifier. 1070 EXPECT_THAT_EXPECTED(Tester.parseSubst("%u, FOO"), Succeeded()); 1071 EXPECT_THAT_EXPECTED(Tester.parseSubst("%d, FOO"), Succeeded()); 1072 EXPECT_THAT_EXPECTED(Tester.parseSubst("%x, FOO"), Succeeded()); 1073 EXPECT_THAT_EXPECTED(Tester.parseSubst("%X, FOO"), Succeeded()); 1074 1075 // Valid expression with precision specifier. 1076 EXPECT_THAT_EXPECTED(Tester.parseSubst("%.8u, FOO"), Succeeded()); 1077 EXPECT_THAT_EXPECTED(Tester.parseSubst("%.8, FOO"), Succeeded()); 1078 1079 // Valid legacy @LINE expression. 1080 EXPECT_THAT_EXPECTED(Tester.parseSubst("@LINE+2", /*IsLegacyNumExpr=*/true), 1081 Succeeded()); 1082 1083 // Invalid legacy @LINE expression with more than 2 operands. 1084 expectDiagnosticError( 1085 "unexpected characters at end of expression '+@LINE'", 1086 Tester.parseSubst("@LINE+2+@LINE", /*IsLegacyNumExpr=*/true).takeError()); 1087 expectDiagnosticError( 1088 "unexpected characters at end of expression '+2'", 1089 Tester.parseSubst("@LINE+2+2", /*IsLegacyNumExpr=*/true).takeError()); 1090 1091 // Valid expression with several variables when their implicit formats do not 1092 // conflict. 1093 EXPECT_THAT_EXPECTED(Tester.parseSubst("FOO+VAR_UNSIGNED"), Succeeded()); 1094 1095 // Valid implicit format conflict in presence of explicit formats. 1096 EXPECT_THAT_EXPECTED(Tester.parseSubst("%X,FOO+VAR_LOWER_HEX"), Succeeded()); 1097 1098 // Implicit format conflict. 1099 expectDiagnosticError( 1100 "implicit format conflict between 'FOO' (%u) and " 1101 "'VAR_LOWER_HEX' (%x), need an explicit format specifier", 1102 Tester.parseSubst("FOO+VAR_LOWER_HEX").takeError()); 1103 1104 // Simple parenthesized expressions: 1105 EXPECT_THAT_EXPECTED(Tester.parseSubst("(1)"), Succeeded()); 1106 EXPECT_THAT_EXPECTED(Tester.parseSubst("(1+1)"), Succeeded()); 1107 EXPECT_THAT_EXPECTED(Tester.parseSubst("(1)+1"), Succeeded()); 1108 EXPECT_THAT_EXPECTED(Tester.parseSubst("((1)+1)"), Succeeded()); 1109 EXPECT_THAT_EXPECTED(Tester.parseSubst("((1)+X)"), Succeeded()); 1110 EXPECT_THAT_EXPECTED(Tester.parseSubst("((X)+Y)"), Succeeded()); 1111 1112 expectDiagnosticError("missing operand in expression", 1113 Tester.parseSubst("(").takeError()); 1114 expectDiagnosticError("missing ')' at end of nested expression", 1115 Tester.parseSubst("(1").takeError()); 1116 expectDiagnosticError("missing operand in expression", 1117 Tester.parseSubst("(1+").takeError()); 1118 expectDiagnosticError("missing ')' at end of nested expression", 1119 Tester.parseSubst("(1+1").takeError()); 1120 expectDiagnosticError("missing ')' at end of nested expression", 1121 Tester.parseSubst("((1+2+3").takeError()); 1122 expectDiagnosticError("missing ')' at end of nested expression", 1123 Tester.parseSubst("((1+2)+3").takeError()); 1124 1125 // Test missing operation between operands: 1126 expectDiagnosticError("unsupported operation '('", 1127 Tester.parseSubst("(1)(2)").takeError()); 1128 expectDiagnosticError("unsupported operation '('", 1129 Tester.parseSubst("2(X)").takeError()); 1130 1131 // Test more closing than opening parentheses. The diagnostic messages are 1132 // not ideal, but for now simply check that we reject invalid input. 1133 expectDiagnosticError("invalid matching constraint or operand format", 1134 Tester.parseSubst(")").takeError()); 1135 expectDiagnosticError("unsupported operation ')'", 1136 Tester.parseSubst("1)").takeError()); 1137 expectDiagnosticError("unsupported operation ')'", 1138 Tester.parseSubst("(1+2))").takeError()); 1139 expectDiagnosticError("unsupported operation ')'", 1140 Tester.parseSubst("(2))").takeError()); 1141 expectDiagnosticError("unsupported operation ')'", 1142 Tester.parseSubst("(1))(").takeError()); 1143 1144 // Valid expression with function call. 1145 EXPECT_THAT_EXPECTED(Tester.parseSubst("add(FOO,3)"), Succeeded()); 1146 EXPECT_THAT_EXPECTED(Tester.parseSubst("add (FOO,3)"), Succeeded()); 1147 // Valid expression with nested function call. 1148 EXPECT_THAT_EXPECTED(Tester.parseSubst("add(FOO, min(BAR,10))"), Succeeded()); 1149 // Valid expression with function call taking expression as argument. 1150 EXPECT_THAT_EXPECTED(Tester.parseSubst("add(FOO, (BAR+10) + 3)"), 1151 Succeeded()); 1152 EXPECT_THAT_EXPECTED(Tester.parseSubst("add(FOO, min (BAR,10) + 3)"), 1153 Succeeded()); 1154 // Valid expression with variable named the same as a function. 1155 EXPECT_THAT_EXPECTED(Tester.parseSubst("add"), Succeeded()); 1156 EXPECT_THAT_EXPECTED(Tester.parseSubst("add+FOO"), Succeeded()); 1157 EXPECT_THAT_EXPECTED(Tester.parseSubst("FOO+add"), Succeeded()); 1158 EXPECT_THAT_EXPECTED(Tester.parseSubst("add(add,add)+add"), Succeeded()); 1159 1160 // Malformed call syntax. 1161 expectDiagnosticError("missing ')' at end of call expression", 1162 Tester.parseSubst("add(FOO,(BAR+7)").takeError()); 1163 expectDiagnosticError("missing ')' at end of call expression", 1164 Tester.parseSubst("add(FOO,min(BAR,7)").takeError()); 1165 expectDiagnosticError("missing argument", 1166 Tester.parseSubst("add(FOO,)").takeError()); 1167 expectDiagnosticError("missing argument", 1168 Tester.parseSubst("add(,FOO)").takeError()); 1169 expectDiagnosticError("missing argument", 1170 Tester.parseSubst("add(FOO,,3)").takeError()); 1171 1172 // Valid call, but to an unknown function. 1173 expectDiagnosticError("call to undefined function 'bogus_function'", 1174 Tester.parseSubst("bogus_function(FOO,3)").takeError()); 1175 expectDiagnosticError("call to undefined function '@add'", 1176 Tester.parseSubst("@add(2,3)").takeError()); 1177 expectDiagnosticError("call to undefined function '$add'", 1178 Tester.parseSubst("$add(2,3)").takeError()); 1179 expectDiagnosticError("call to undefined function 'FOO'", 1180 Tester.parseSubst("FOO(2,3)").takeError()); 1181 expectDiagnosticError("call to undefined function 'FOO'", 1182 Tester.parseSubst("FOO (2,3)").takeError()); 1183 1184 // Valid call, but with incorrect argument count. 1185 expectDiagnosticError("function 'add' takes 2 arguments but 1 given", 1186 Tester.parseSubst("add(FOO)").takeError()); 1187 expectDiagnosticError("function 'add' takes 2 arguments but 3 given", 1188 Tester.parseSubst("add(FOO,3,4)").takeError()); 1189 1190 // Valid call, but not part of a valid expression. 1191 expectDiagnosticError("unsupported operation 'a'", 1192 Tester.parseSubst("2add(FOO,2)").takeError()); 1193 expectDiagnosticError("unsupported operation 'a'", 1194 Tester.parseSubst("FOO add(FOO,2)").takeError()); 1195 expectDiagnosticError("unsupported operation 'a'", 1196 Tester.parseSubst("add(FOO,2)add(FOO,2)").takeError()); 1197 } 1198 1199 TEST_F(FileCheckTest, ParsePattern) { 1200 PatternTester Tester; 1201 1202 // Invalid space in string substitution. 1203 EXPECT_TRUE(Tester.parsePattern("[[ BAR]]")); 1204 1205 // Invalid variable name in string substitution. 1206 EXPECT_TRUE(Tester.parsePattern("[[42INVALID]]")); 1207 1208 // Invalid string variable definition. 1209 EXPECT_TRUE(Tester.parsePattern("[[@PAT:]]")); 1210 EXPECT_TRUE(Tester.parsePattern("[[PAT+2:]]")); 1211 1212 // Collision with numeric variable. 1213 EXPECT_TRUE(Tester.parsePattern("[[FOO:]]")); 1214 1215 // Invalid use of string variable. 1216 EXPECT_TRUE(Tester.parsePattern("[[FOO-BAR]]")); 1217 1218 // Valid use of string variable. 1219 EXPECT_FALSE(Tester.parsePattern("[[BAR]]")); 1220 1221 // Valid string variable definition. 1222 EXPECT_FALSE(Tester.parsePattern("[[PAT:[0-9]+]]")); 1223 1224 // Invalid numeric substitution. 1225 EXPECT_TRUE(Tester.parsePattern("[[#42INVALID]]")); 1226 1227 // Valid numeric substitution. 1228 EXPECT_FALSE(Tester.parsePattern("[[#FOO]]")); 1229 1230 // Valid legacy @LINE expression. 1231 EXPECT_FALSE(Tester.parsePattern("[[@LINE+2]]")); 1232 1233 // Invalid legacy @LINE expression with non decimal literal. 1234 EXPECT_TRUE(Tester.parsePattern("[[@LINE+0x3]]")); 1235 } 1236 1237 TEST_F(FileCheckTest, Match) { 1238 PatternTester Tester; 1239 1240 // Check a substitution error is diagnosed. 1241 ASSERT_FALSE(Tester.parsePattern("[[#%u, -1]]")); 1242 expectDiagnosticError( 1243 "unable to substitute variable or numeric expression: overflow error", 1244 Tester.match("").takeError()); 1245 1246 // Check matching an empty expression only matches a number. 1247 Tester.initNextPattern(); 1248 ASSERT_FALSE(Tester.parsePattern("[[#]]")); 1249 expectNotFoundError(Tester.match("FAIL").takeError()); 1250 EXPECT_THAT_EXPECTED(Tester.match("18"), Succeeded()); 1251 1252 // Check matching a definition only matches a number with the right format. 1253 Tester.initNextPattern(); 1254 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR:]]")); 1255 expectNotFoundError(Tester.match("FAIL").takeError()); 1256 expectNotFoundError(Tester.match("").takeError()); 1257 EXPECT_THAT_EXPECTED(Tester.match("18"), Succeeded()); 1258 Tester.initNextPattern(); 1259 Tester.parsePattern("[[#%u,NUMVAR_UNSIGNED:]]"); 1260 expectNotFoundError(Tester.match("C").takeError()); 1261 EXPECT_THAT_EXPECTED(Tester.match("20"), Succeeded()); 1262 Tester.initNextPattern(); 1263 Tester.parsePattern("[[#%x,NUMVAR_LOWER_HEX:]]"); 1264 expectNotFoundError(Tester.match("g").takeError()); 1265 expectNotFoundError(Tester.match("C").takeError()); 1266 EXPECT_THAT_EXPECTED(Tester.match("c"), Succeeded()); 1267 Tester.initNextPattern(); 1268 Tester.parsePattern("[[#%X,NUMVAR_UPPER_HEX:]]"); 1269 expectNotFoundError(Tester.match("H").takeError()); 1270 expectNotFoundError(Tester.match("b").takeError()); 1271 EXPECT_THAT_EXPECTED(Tester.match("B"), Succeeded()); 1272 1273 // Check matching expressions with no explicit format matches the values in 1274 // the right format. 1275 Tester.initNextPattern(); 1276 Tester.parsePattern("[[#NUMVAR_UNSIGNED-5]]"); 1277 expectNotFoundError(Tester.match("f").takeError()); 1278 expectNotFoundError(Tester.match("F").takeError()); 1279 EXPECT_THAT_EXPECTED(Tester.match("15"), Succeeded()); 1280 Tester.initNextPattern(); 1281 Tester.parsePattern("[[#NUMVAR_LOWER_HEX+1]]"); 1282 expectNotFoundError(Tester.match("13").takeError()); 1283 expectNotFoundError(Tester.match("D").takeError()); 1284 EXPECT_THAT_EXPECTED(Tester.match("d"), Succeeded()); 1285 Tester.initNextPattern(); 1286 Tester.parsePattern("[[#NUMVAR_UPPER_HEX+1]]"); 1287 expectNotFoundError(Tester.match("12").takeError()); 1288 expectNotFoundError(Tester.match("c").takeError()); 1289 EXPECT_THAT_EXPECTED(Tester.match("C"), Succeeded()); 1290 1291 // Check matching an undefined variable returns a NotFound error. 1292 Tester.initNextPattern(); 1293 ASSERT_FALSE(Tester.parsePattern("100")); 1294 expectNotFoundError(Tester.match("101").takeError()); 1295 1296 // Check matching the defined variable matches the correct number only. 1297 Tester.initNextPattern(); 1298 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR]]")); 1299 EXPECT_THAT_EXPECTED(Tester.match("18"), Succeeded()); 1300 1301 // Check matching several substitutions does not match them independently. 1302 Tester.initNextPattern(); 1303 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR]] [[#NUMVAR+2]]")); 1304 expectNotFoundError(Tester.match("19 21").takeError()); 1305 expectNotFoundError(Tester.match("18 21").takeError()); 1306 EXPECT_THAT_EXPECTED(Tester.match("18 20"), Succeeded()); 1307 1308 // Check matching a numeric expression using @LINE after a match failure uses 1309 // the correct value for @LINE. 1310 Tester.initNextPattern(); 1311 ASSERT_FALSE(Tester.parsePattern("[[#@LINE]]")); 1312 // Ok, @LINE matches the current line number. 1313 EXPECT_THAT_EXPECTED(Tester.match(std::to_string(Tester.getLineNumber())), 1314 Succeeded()); 1315 Tester.initNextPattern(); 1316 // Match with substitution failure. 1317 ASSERT_FALSE(Tester.parsePattern("[[#UNKNOWN1+UNKNOWN2]]")); 1318 expectSameErrors<ErrorDiagnostic>( 1319 {"undefined variable: UNKNOWN1", "undefined variable: UNKNOWN2"}, 1320 Tester.match("FOO").takeError()); 1321 Tester.initNextPattern(); 1322 // Check that @LINE matches the later (given the calls to initNextPattern()) 1323 // line number. 1324 EXPECT_FALSE(Tester.parsePattern("[[#@LINE]]")); 1325 EXPECT_THAT_EXPECTED(Tester.match(std::to_string(Tester.getLineNumber())), 1326 Succeeded()); 1327 } 1328 1329 TEST_F(FileCheckTest, MatchParen) { 1330 PatternTester Tester; 1331 // Check simple parenthesized expressions 1332 Tester.initNextPattern(); 1333 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR:]]")); 1334 expectNotFoundError(Tester.match("FAIL").takeError()); 1335 expectNotFoundError(Tester.match("").takeError()); 1336 EXPECT_THAT_EXPECTED(Tester.match("18"), Succeeded()); 1337 1338 Tester.initNextPattern(); 1339 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR + (2 + 2)]]")); 1340 expectNotFoundError(Tester.match("21").takeError()); 1341 EXPECT_THAT_EXPECTED(Tester.match("22"), Succeeded()); 1342 Tester.initNextPattern(); 1343 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR + (2)]]")); 1344 EXPECT_THAT_EXPECTED(Tester.match("20"), Succeeded()); 1345 Tester.initNextPattern(); 1346 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR+(2)]]")); 1347 EXPECT_THAT_EXPECTED(Tester.match("20"), Succeeded()); 1348 Tester.initNextPattern(); 1349 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR+(NUMVAR)]]")); 1350 EXPECT_THAT_EXPECTED(Tester.match("36"), Succeeded()); 1351 1352 // Check nested parenthesized expressions: 1353 Tester.initNextPattern(); 1354 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR+(2+(2))]]")); 1355 EXPECT_THAT_EXPECTED(Tester.match("22"), Succeeded()); 1356 Tester.initNextPattern(); 1357 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR+(2+(NUMVAR))]]")); 1358 EXPECT_THAT_EXPECTED(Tester.match("38"), Succeeded()); 1359 Tester.initNextPattern(); 1360 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR+((((NUMVAR))))]]")); 1361 EXPECT_THAT_EXPECTED(Tester.match("36"), Succeeded()); 1362 Tester.initNextPattern(); 1363 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR+((((NUMVAR)))-1)-1]]")); 1364 EXPECT_THAT_EXPECTED(Tester.match("34"), Succeeded()); 1365 1366 // Parentheses can also be the first character after the '#': 1367 Tester.initNextPattern(); 1368 ASSERT_FALSE(Tester.parsePattern("[[#(NUMVAR)]]")); 1369 EXPECT_THAT_EXPECTED(Tester.match("18"), Succeeded()); 1370 Tester.initNextPattern(); 1371 ASSERT_FALSE(Tester.parsePattern("[[#(NUMVAR+2)]]")); 1372 EXPECT_THAT_EXPECTED(Tester.match("20"), Succeeded()); 1373 } 1374 1375 TEST_F(FileCheckTest, MatchBuiltinFunctions) { 1376 PatternTester Tester; 1377 // Esnure #NUMVAR has the expected value. 1378 Tester.initNextPattern(); 1379 ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR:]]")); 1380 expectNotFoundError(Tester.match("FAIL").takeError()); 1381 expectNotFoundError(Tester.match("").takeError()); 1382 EXPECT_THAT_EXPECTED(Tester.match("18"), Succeeded()); 1383 1384 // Check each builtin function generates the expected result. 1385 Tester.initNextPattern(); 1386 ASSERT_FALSE(Tester.parsePattern("[[#add(NUMVAR,13)]]")); 1387 EXPECT_THAT_EXPECTED(Tester.match("31"), Succeeded()); 1388 Tester.initNextPattern(); 1389 ASSERT_FALSE(Tester.parsePattern("[[#div(NUMVAR,3)]]")); 1390 EXPECT_THAT_EXPECTED(Tester.match("6"), Succeeded()); 1391 Tester.initNextPattern(); 1392 ASSERT_FALSE(Tester.parsePattern("[[#max(NUMVAR,5)]]")); 1393 EXPECT_THAT_EXPECTED(Tester.match("18"), Succeeded()); 1394 Tester.initNextPattern(); 1395 ASSERT_FALSE(Tester.parsePattern("[[#max(NUMVAR,99)]]")); 1396 EXPECT_THAT_EXPECTED(Tester.match("99"), Succeeded()); 1397 Tester.initNextPattern(); 1398 ASSERT_FALSE(Tester.parsePattern("[[#min(NUMVAR,5)]]")); 1399 EXPECT_THAT_EXPECTED(Tester.match("5"), Succeeded()); 1400 Tester.initNextPattern(); 1401 ASSERT_FALSE(Tester.parsePattern("[[#min(NUMVAR,99)]]")); 1402 EXPECT_THAT_EXPECTED(Tester.match("18"), Succeeded()); 1403 Tester.initNextPattern(); 1404 ASSERT_FALSE(Tester.parsePattern("[[#mul(NUMVAR,3)]]")); 1405 EXPECT_THAT_EXPECTED(Tester.match("54"), Succeeded()); 1406 Tester.initNextPattern(); 1407 ASSERT_FALSE(Tester.parsePattern("[[#sub(NUMVAR,7)]]")); 1408 EXPECT_THAT_EXPECTED(Tester.match("11"), Succeeded()); 1409 1410 // Check nested function calls. 1411 Tester.initNextPattern(); 1412 ASSERT_FALSE(Tester.parsePattern("[[#add(min(7,2),max(4,10))]]")); 1413 EXPECT_THAT_EXPECTED(Tester.match("12"), Succeeded()); 1414 1415 // Check function call that uses a variable of the same name. 1416 Tester.initNextPattern(); 1417 ASSERT_FALSE(Tester.parsePattern("[[#add(add,add)+min (add,3)+add]]")); 1418 EXPECT_THAT_EXPECTED(Tester.match("24"), Succeeded()); 1419 } 1420 1421 TEST_F(FileCheckTest, Substitution) { 1422 SourceMgr SM; 1423 FileCheckPatternContext Context; 1424 EXPECT_THAT_ERROR(Context.defineCmdlineVariables({"FOO=BAR"}, SM), 1425 Succeeded()); 1426 1427 // Substitution of an undefined string variable fails and error holds that 1428 // variable's name. 1429 StringSubstitution StringSubstitution(&Context, "VAR404", 42); 1430 Expected<std::string> SubstValue = StringSubstitution.getResult(); 1431 expectUndefErrors({"VAR404"}, SubstValue.takeError()); 1432 1433 // Numeric substitution blocks constituted of defined numeric variables are 1434 // substituted for the variable's value. 1435 NumericVariable NVar("N", ExpressionFormat(ExpressionFormat::Kind::Unsigned), 1436 1); 1437 NVar.setValue(ExpressionValue(10u)); 1438 auto NVarUse = std::make_unique<NumericVariableUse>("N", &NVar); 1439 auto ExpressionN = std::make_unique<Expression>( 1440 std::move(NVarUse), ExpressionFormat(ExpressionFormat::Kind::HexUpper)); 1441 NumericSubstitution SubstitutionN(&Context, "N", std::move(ExpressionN), 1442 /*InsertIdx=*/30); 1443 SubstValue = SubstitutionN.getResult(); 1444 ASSERT_THAT_EXPECTED(SubstValue, Succeeded()); 1445 EXPECT_EQ("A", *SubstValue); 1446 1447 // Substitution of an undefined numeric variable fails, error holds name of 1448 // undefined variable. 1449 NVar.clearValue(); 1450 SubstValue = SubstitutionN.getResult(); 1451 expectUndefErrors({"N"}, SubstValue.takeError()); 1452 1453 // Substitution of a defined string variable returns the right value. 1454 Pattern P(Check::CheckPlain, &Context, 1); 1455 StringSubstitution = llvm::StringSubstitution(&Context, "FOO", 42); 1456 SubstValue = StringSubstitution.getResult(); 1457 ASSERT_THAT_EXPECTED(SubstValue, Succeeded()); 1458 EXPECT_EQ("BAR", *SubstValue); 1459 } 1460 1461 TEST_F(FileCheckTest, FileCheckContext) { 1462 FileCheckPatternContext Cxt; 1463 SourceMgr SM; 1464 1465 // No definition. 1466 EXPECT_THAT_ERROR(Cxt.defineCmdlineVariables({}, SM), Succeeded()); 1467 1468 // Missing equal sign. 1469 expectDiagnosticError("missing equal sign in global definition", 1470 Cxt.defineCmdlineVariables({"LocalVar"}, SM)); 1471 expectDiagnosticError("missing equal sign in global definition", 1472 Cxt.defineCmdlineVariables({"#LocalNumVar"}, SM)); 1473 1474 // Empty variable name. 1475 expectDiagnosticError("empty variable name", 1476 Cxt.defineCmdlineVariables({"=18"}, SM)); 1477 expectDiagnosticError("empty variable name", 1478 Cxt.defineCmdlineVariables({"#=18"}, SM)); 1479 1480 // Invalid variable name. 1481 expectDiagnosticError("invalid variable name", 1482 Cxt.defineCmdlineVariables({"18LocalVar=18"}, SM)); 1483 expectDiagnosticError("invalid variable name", 1484 Cxt.defineCmdlineVariables({"#18LocalNumVar=18"}, SM)); 1485 1486 // Name conflict between pattern and numeric variable. 1487 expectDiagnosticError( 1488 "string variable with name 'LocalVar' already exists", 1489 Cxt.defineCmdlineVariables({"LocalVar=18", "#LocalVar=36"}, SM)); 1490 Cxt = FileCheckPatternContext(); 1491 expectDiagnosticError( 1492 "numeric variable with name 'LocalNumVar' already exists", 1493 Cxt.defineCmdlineVariables({"#LocalNumVar=18", "LocalNumVar=36"}, SM)); 1494 Cxt = FileCheckPatternContext(); 1495 1496 // Invalid numeric value for numeric variable. 1497 expectUndefErrors({"x"}, Cxt.defineCmdlineVariables({"#LocalNumVar=x"}, SM)); 1498 1499 // Define local variables from command-line. 1500 std::vector<StringRef> GlobalDefines; 1501 // Clear local variables to remove dummy numeric variable x that 1502 // parseNumericSubstitutionBlock would have created and stored in 1503 // GlobalNumericVariableTable. 1504 Cxt.clearLocalVars(); 1505 GlobalDefines.emplace_back("LocalVar=FOO"); 1506 GlobalDefines.emplace_back("EmptyVar="); 1507 GlobalDefines.emplace_back("#LocalNumVar1=18"); 1508 GlobalDefines.emplace_back("#%x,LocalNumVar2=LocalNumVar1+2"); 1509 GlobalDefines.emplace_back("#LocalNumVar3=0xc"); 1510 ASSERT_THAT_ERROR(Cxt.defineCmdlineVariables(GlobalDefines, SM), Succeeded()); 1511 1512 // Create @LINE pseudo numeric variable and check it is present by matching 1513 // it. 1514 size_t LineNumber = 1; 1515 Pattern P(Check::CheckPlain, &Cxt, LineNumber); 1516 FileCheckRequest Req; 1517 Cxt.createLineVariable(); 1518 ASSERT_FALSE(P.parsePattern("[[@LINE]]", "CHECK", SM, Req)); 1519 Pattern::MatchResult Res = P.match("1", SM); 1520 ASSERT_THAT_ERROR(std::move(Res.TheError), Succeeded()); 1521 1522 #ifndef NDEBUG 1523 // Recreating @LINE pseudo numeric variable fails. 1524 EXPECT_DEATH(Cxt.createLineVariable(), 1525 "@LINE pseudo numeric variable already created"); 1526 #endif 1527 1528 // Check defined variables are present and undefined ones are absent. 1529 StringRef LocalVarStr = "LocalVar"; 1530 StringRef LocalNumVar1Ref = bufferize(SM, "LocalNumVar1"); 1531 StringRef LocalNumVar2Ref = bufferize(SM, "LocalNumVar2"); 1532 StringRef LocalNumVar3Ref = bufferize(SM, "LocalNumVar3"); 1533 StringRef EmptyVarStr = "EmptyVar"; 1534 StringRef UnknownVarStr = "UnknownVar"; 1535 Expected<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr); 1536 P = Pattern(Check::CheckPlain, &Cxt, ++LineNumber); 1537 std::optional<NumericVariable *> DefinedNumericVariable; 1538 Expected<std::unique_ptr<Expression>> ExpressionPointer = 1539 P.parseNumericSubstitutionBlock(LocalNumVar1Ref, DefinedNumericVariable, 1540 /*IsLegacyLineExpr=*/false, LineNumber, 1541 &Cxt, SM); 1542 ASSERT_THAT_EXPECTED(LocalVar, Succeeded()); 1543 EXPECT_EQ(*LocalVar, "FOO"); 1544 Expected<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr); 1545 Expected<StringRef> UnknownVar = Cxt.getPatternVarValue(UnknownVarStr); 1546 ASSERT_THAT_EXPECTED(ExpressionPointer, Succeeded()); 1547 Expected<ExpressionValue> ExpressionVal = 1548 (*ExpressionPointer)->getAST()->eval(); 1549 ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded()); 1550 EXPECT_EQ(ExpressionVal->getAPIntValue().getSExtValue(), 18); 1551 ExpressionPointer = P.parseNumericSubstitutionBlock( 1552 LocalNumVar2Ref, DefinedNumericVariable, 1553 /*IsLegacyLineExpr=*/false, LineNumber, &Cxt, SM); 1554 ASSERT_THAT_EXPECTED(ExpressionPointer, Succeeded()); 1555 ExpressionVal = (*ExpressionPointer)->getAST()->eval(); 1556 ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded()); 1557 EXPECT_EQ(ExpressionVal->getAPIntValue().getSExtValue(), 20); 1558 ExpressionPointer = P.parseNumericSubstitutionBlock( 1559 LocalNumVar3Ref, DefinedNumericVariable, 1560 /*IsLegacyLineExpr=*/false, LineNumber, &Cxt, SM); 1561 ASSERT_THAT_EXPECTED(ExpressionPointer, Succeeded()); 1562 ExpressionVal = (*ExpressionPointer)->getAST()->eval(); 1563 ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded()); 1564 EXPECT_EQ(ExpressionVal->getAPIntValue().getSExtValue(), 12); 1565 ASSERT_THAT_EXPECTED(EmptyVar, Succeeded()); 1566 EXPECT_EQ(*EmptyVar, ""); 1567 expectUndefErrors({std::string(UnknownVarStr)}, UnknownVar.takeError()); 1568 1569 // Clear local variables and check they become absent. 1570 Cxt.clearLocalVars(); 1571 LocalVar = Cxt.getPatternVarValue(LocalVarStr); 1572 expectUndefErrors({std::string(LocalVarStr)}, LocalVar.takeError()); 1573 // Check a numeric expression's evaluation fails if called after clearing of 1574 // local variables, if it was created before. This is important because local 1575 // variable clearing due to --enable-var-scope happens after numeric 1576 // expressions are linked to the numeric variables they use. 1577 expectUndefErrors({"LocalNumVar3"}, 1578 (*ExpressionPointer)->getAST()->eval().takeError()); 1579 P = Pattern(Check::CheckPlain, &Cxt, ++LineNumber); 1580 ExpressionPointer = P.parseNumericSubstitutionBlock( 1581 LocalNumVar1Ref, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, 1582 LineNumber, &Cxt, SM); 1583 ASSERT_THAT_EXPECTED(ExpressionPointer, Succeeded()); 1584 ExpressionVal = (*ExpressionPointer)->getAST()->eval(); 1585 expectUndefErrors({"LocalNumVar1"}, ExpressionVal.takeError()); 1586 ExpressionPointer = P.parseNumericSubstitutionBlock( 1587 LocalNumVar2Ref, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, 1588 LineNumber, &Cxt, SM); 1589 ASSERT_THAT_EXPECTED(ExpressionPointer, Succeeded()); 1590 ExpressionVal = (*ExpressionPointer)->getAST()->eval(); 1591 expectUndefErrors({"LocalNumVar2"}, ExpressionVal.takeError()); 1592 EmptyVar = Cxt.getPatternVarValue(EmptyVarStr); 1593 expectUndefErrors({"EmptyVar"}, EmptyVar.takeError()); 1594 // Clear again because parseNumericSubstitutionBlock would have created a 1595 // dummy variable and stored it in GlobalNumericVariableTable. 1596 Cxt.clearLocalVars(); 1597 1598 // Redefine global variables and check variables are defined again. 1599 GlobalDefines.emplace_back("$GlobalVar=BAR"); 1600 GlobalDefines.emplace_back("#$GlobalNumVar=36"); 1601 ASSERT_THAT_ERROR(Cxt.defineCmdlineVariables(GlobalDefines, SM), Succeeded()); 1602 StringRef GlobalVarStr = "$GlobalVar"; 1603 StringRef GlobalNumVarRef = bufferize(SM, "$GlobalNumVar"); 1604 Expected<StringRef> GlobalVar = Cxt.getPatternVarValue(GlobalVarStr); 1605 ASSERT_THAT_EXPECTED(GlobalVar, Succeeded()); 1606 EXPECT_EQ(*GlobalVar, "BAR"); 1607 P = Pattern(Check::CheckPlain, &Cxt, ++LineNumber); 1608 ExpressionPointer = P.parseNumericSubstitutionBlock( 1609 GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, 1610 LineNumber, &Cxt, SM); 1611 ASSERT_THAT_EXPECTED(ExpressionPointer, Succeeded()); 1612 ExpressionVal = (*ExpressionPointer)->getAST()->eval(); 1613 ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded()); 1614 EXPECT_EQ(ExpressionVal->getAPIntValue().getSExtValue(), 36); 1615 1616 // Clear local variables and check global variables remain defined. 1617 Cxt.clearLocalVars(); 1618 EXPECT_THAT_EXPECTED(Cxt.getPatternVarValue(GlobalVarStr), Succeeded()); 1619 P = Pattern(Check::CheckPlain, &Cxt, ++LineNumber); 1620 ExpressionPointer = P.parseNumericSubstitutionBlock( 1621 GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, 1622 LineNumber, &Cxt, SM); 1623 ASSERT_THAT_EXPECTED(ExpressionPointer, Succeeded()); 1624 ExpressionVal = (*ExpressionPointer)->getAST()->eval(); 1625 ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded()); 1626 EXPECT_EQ(ExpressionVal->getAPIntValue().getSExtValue(), 36); 1627 } 1628 1629 TEST_F(FileCheckTest, CapturedVarDiags) { 1630 PatternTester Tester; 1631 ASSERT_FALSE(Tester.parsePattern("[[STRVAR:[a-z]+]] [[#NUMVAR:@LINE]]")); 1632 EXPECT_THAT_EXPECTED(Tester.match("foobar 2"), Succeeded()); 1633 std::vector<FileCheckDiag> Diags; 1634 Tester.printVariableDefs(FileCheckDiag::MatchFoundAndExpected, Diags); 1635 EXPECT_EQ(Diags.size(), 2ul); 1636 for (FileCheckDiag Diag : Diags) { 1637 EXPECT_EQ(Diag.CheckTy, Check::CheckPlain); 1638 EXPECT_EQ(Diag.MatchTy, FileCheckDiag::MatchFoundAndExpected); 1639 EXPECT_EQ(Diag.InputStartLine, 1u); 1640 EXPECT_EQ(Diag.InputEndLine, 1u); 1641 } 1642 EXPECT_EQ(Diags[0].InputStartCol, 1u); 1643 EXPECT_EQ(Diags[0].InputEndCol, 7u); 1644 EXPECT_EQ(Diags[1].InputStartCol, 8u); 1645 EXPECT_EQ(Diags[1].InputEndCol, 9u); 1646 EXPECT_EQ(Diags[0].Note, "captured var \"STRVAR\""); 1647 EXPECT_EQ(Diags[1].Note, "captured var \"NUMVAR\""); 1648 } 1649 } // namespace 1650