618 lines · cpp
1//===- unittest/Support/YAMLRemarksParsingTest.cpp - OptTable 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm-c/Remarks.h"10#include "llvm/Remarks/Remark.h"11#include "llvm/Remarks/RemarkParser.h"12#include "gtest/gtest.h"13#include <optional>14 15using namespace llvm;16 17template <size_t N> void parseGood(const char (&Buf)[N]) {18 Expected<std::unique_ptr<remarks::RemarkParser>> MaybeParser =19 remarks::createRemarkParser(remarks::Format::YAML, {Buf, N - 1});20 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));21 EXPECT_TRUE(*MaybeParser != nullptr);22 23 remarks::RemarkParser &Parser = **MaybeParser;24 Expected<std::unique_ptr<remarks::Remark>> Remark = Parser.next();25 EXPECT_FALSE(errorToBool(Remark.takeError())); // Check for parsing errors.26 EXPECT_TRUE(*Remark != nullptr); // At least one remark.27 Remark = Parser.next();28 Error E = Remark.takeError();29 EXPECT_TRUE(E.isA<remarks::EndOfFileError>());30 EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.31}32 33void parseGoodMeta(StringRef Buf) {34 Expected<std::unique_ptr<remarks::RemarkParser>> MaybeParser =35 remarks::createRemarkParserFromMeta(remarks::Format::YAML, Buf);36 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));37 EXPECT_TRUE(*MaybeParser != nullptr);38 39 remarks::RemarkParser &Parser = **MaybeParser;40 Expected<std::unique_ptr<remarks::Remark>> Remark = Parser.next();41 EXPECT_FALSE(errorToBool(Remark.takeError())); // Check for parsing errors.42 EXPECT_TRUE(*Remark != nullptr); // At least one remark.43 Remark = Parser.next();44 Error E = Remark.takeError();45 EXPECT_TRUE(E.isA<remarks::EndOfFileError>());46 EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.47}48 49template <size_t N>50bool parseExpectError(const char (&Buf)[N], const char *Error) {51 Expected<std::unique_ptr<remarks::RemarkParser>> MaybeParser =52 remarks::createRemarkParser(remarks::Format::YAML, {Buf, N - 1});53 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));54 EXPECT_TRUE(*MaybeParser != nullptr);55 56 remarks::RemarkParser &Parser = **MaybeParser;57 Expected<std::unique_ptr<remarks::Remark>> Remark = Parser.next();58 EXPECT_FALSE(Remark); // Check for parsing errors.59 60 std::string ErrorStr;61 raw_string_ostream Stream(ErrorStr);62 handleAllErrors(Remark.takeError(),63 [&](const ErrorInfoBase &EIB) { EIB.log(Stream); });64 return StringRef(Stream.str()).contains(Error);65}66 67enum class CmpType {68 Equal,69 Contains70};71 72void parseExpectErrorMeta(73 StringRef Buf, const char *Error, CmpType Cmp,74 std::optional<StringRef> ExternalFilePrependPath = std::nullopt) {75 std::string ErrorStr;76 raw_string_ostream Stream(ErrorStr);77 78 Expected<std::unique_ptr<remarks::RemarkParser>> MaybeParser =79 remarks::createRemarkParserFromMeta(remarks::Format::YAML, Buf,80 std::move(ExternalFilePrependPath));81 handleAllErrors(MaybeParser.takeError(),82 [&](const ErrorInfoBase &EIB) { EIB.log(Stream); });83 84 // Use a case insensitive comparision due to case differences in error strings85 // for different OSs.86 if (Cmp == CmpType::Equal) {87 EXPECT_EQ(StringRef(Stream.str()).lower(), StringRef(Error).lower());88 }89 90 if (Cmp == CmpType::Contains) {91 EXPECT_TRUE(StringRef(Stream.str()).contains(StringRef(Error)));92 }93}94 95TEST(YAMLRemarks, ParsingEmpty) {96 EXPECT_TRUE(parseExpectError("\n\n", "document root is not of mapping type."));97}98 99TEST(YAMLRemarks, ParsingNotYAML) {100 EXPECT_TRUE(101 parseExpectError("\x01\x02\x03\x04\x05\x06", "Got empty plain scalar"));102}103 104TEST(YAMLRemarks, ParsingGood) {105 parseGood("\n"106 "--- !Missed\n"107 "Pass: inline\n"108 "Name: NoDefinition\n"109 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"110 "Function: foo\n"111 "Args:\n"112 " - Callee: bar\n"113 " - String: ' will not be inlined into '\n"114 " - Caller: foo\n"115 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"116 " - String: ' because its definition is unavailable'\n"117 "");118 119 // No debug loc should also pass.120 parseGood("\n"121 "--- !Missed\n"122 "Pass: inline\n"123 "Name: NoDefinition\n"124 "Function: foo\n"125 "Args:\n"126 " - Callee: bar\n"127 " - String: ' will not be inlined into '\n"128 " - Caller: foo\n"129 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"130 " - String: ' because its definition is unavailable'\n"131 "");132 133 // No args is also ok.134 parseGood("\n"135 "--- !Missed\n"136 "Pass: inline\n"137 "Name: NoDefinition\n"138 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"139 "Function: foo\n"140 "");141 142 // Different order.143 parseGood("\n"144 "--- !Missed\n"145 "DebugLoc: { Line: 3, Column: 12, File: file.c }\n"146 "Function: foo\n"147 "Name: NoDefinition\n"148 "Args:\n"149 " - Callee: bar\n"150 " - String: ' will not be inlined into '\n"151 " - Caller: foo\n"152 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"153 " - String: ' because its definition is unavailable'\n"154 "Pass: inline\n"155 "");156 157 // Block Remark.158 parseGood("\n"159 "--- !Missed\n"160 "Function: foo\n"161 "Name: NoDefinition\n"162 "Args:\n"163 " - String: |\n \n \n blocks\n"164 "Pass: inline\n"165 "");166}167 168// Mandatory common part of a remark.169#define COMMON_REMARK "\nPass: inline\nName: NoDefinition\nFunction: foo\n\n"170// Test all the types.171TEST(YAMLRemarks, ParsingTypes) {172 // Type: Passed173 parseGood("--- !Passed" COMMON_REMARK);174 // Type: Missed175 parseGood("--- !Missed" COMMON_REMARK);176 // Type: Analysis177 parseGood("--- !Analysis" COMMON_REMARK);178 // Type: AnalysisFPCommute179 parseGood("--- !AnalysisFPCommute" COMMON_REMARK);180 // Type: AnalysisAliasing181 parseGood("--- !AnalysisAliasing" COMMON_REMARK);182 // Type: Failure183 parseGood("--- !Failure" COMMON_REMARK);184}185#undef COMMON_REMARK186 187TEST(YAMLRemarks, ParsingMissingFields) {188 // No type.189 EXPECT_TRUE(parseExpectError("\n"190 "---\n"191 "Pass: inline\n"192 "Name: NoDefinition\n"193 "Function: foo\n"194 "",195 "expected a remark tag."));196 // No pass.197 EXPECT_TRUE(parseExpectError("\n"198 "--- !Missed\n"199 "Name: NoDefinition\n"200 "Function: foo\n"201 "",202 "Type, Pass, Name or Function missing."));203 // No name.204 EXPECT_TRUE(parseExpectError("\n"205 "--- !Missed\n"206 "Pass: inline\n"207 "Function: foo\n"208 "",209 "Type, Pass, Name or Function missing."));210 // No function.211 EXPECT_TRUE(parseExpectError("\n"212 "--- !Missed\n"213 "Pass: inline\n"214 "Name: NoDefinition\n"215 "",216 "Type, Pass, Name or Function missing."));217 // Debug loc but no file.218 EXPECT_TRUE(parseExpectError("\n"219 "--- !Missed\n"220 "Pass: inline\n"221 "Name: NoDefinition\n"222 "Function: foo\n"223 "DebugLoc: { Line: 3, Column: 12 }\n"224 "",225 "DebugLoc node incomplete."));226 // Debug loc but no line.227 EXPECT_TRUE(parseExpectError("\n"228 "--- !Missed\n"229 "Pass: inline\n"230 "Name: NoDefinition\n"231 "Function: foo\n"232 "DebugLoc: { File: file.c, Column: 12 }\n"233 "",234 "DebugLoc node incomplete."));235 // Debug loc but no column.236 EXPECT_TRUE(parseExpectError("\n"237 "--- !Missed\n"238 "Pass: inline\n"239 "Name: NoDefinition\n"240 "Function: foo\n"241 "DebugLoc: { File: file.c, Line: 3 }\n"242 "",243 "DebugLoc node incomplete."));244}245 246TEST(YAMLRemarks, ParsingWrongTypes) {247 // Wrong debug loc type.248 EXPECT_TRUE(parseExpectError("\n"249 "--- !Missed\n"250 "Pass: inline\n"251 "Name: NoDefinition\n"252 "Function: foo\n"253 "DebugLoc: foo\n"254 "",255 "expected a value of mapping type."));256 // Wrong line type.257 EXPECT_TRUE(parseExpectError("\n"258 "--- !Missed\n"259 "Pass: inline\n"260 "Name: NoDefinition\n"261 "Function: foo\n"262 "DebugLoc: { File: file.c, Line: b, Column: 12 }\n"263 "",264 "expected a value of integer type."));265 // Wrong column type.266 EXPECT_TRUE(parseExpectError("\n"267 "--- !Missed\n"268 "Pass: inline\n"269 "Name: NoDefinition\n"270 "Function: foo\n"271 "DebugLoc: { File: file.c, Line: 3, Column: c }\n"272 "",273 "expected a value of integer type."));274 // Wrong args type.275 EXPECT_TRUE(parseExpectError("\n"276 "--- !Missed\n"277 "Pass: inline\n"278 "Name: NoDefinition\n"279 "Function: foo\n"280 "Args: foo\n"281 "",282 "wrong value type for key."));283 // Wrong key type.284 EXPECT_TRUE(parseExpectError("\n"285 "--- !Missed\n"286 "{ A: a }: inline\n"287 "Name: NoDefinition\n"288 "Function: foo\n"289 "",290 "key is not a string."));291 // Debug loc with unknown entry.292 EXPECT_TRUE(parseExpectError("\n"293 "--- !Missed\n"294 "Pass: inline\n"295 "Name: NoDefinition\n"296 "Function: foo\n"297 "DebugLoc: { File: file.c, Column: 12, Unknown: 12 }\n"298 "",299 "unknown entry in DebugLoc map."));300 // Unknown entry.301 EXPECT_TRUE(parseExpectError("\n"302 "--- !Missed\n"303 "Unknown: inline\n"304 "",305 "unknown key."));306 // Not a scalar.307 EXPECT_TRUE(parseExpectError("\n"308 "--- !Missed\n"309 "Pass: { File: a, Line: 1, Column: 2 }\n"310 "Name: NoDefinition\n"311 "Function: foo\n"312 "",313 "expected a value of scalar type."));314 // Not a string file in debug loc.315 EXPECT_TRUE(parseExpectError("\n"316 "--- !Missed\n"317 "Pass: inline\n"318 "Name: NoDefinition\n"319 "Function: foo\n"320 "DebugLoc: { File: { a: b }, Column: 12, Line: 12 }\n"321 "",322 "expected a value of scalar type."));323 // Not a integer column in debug loc.324 EXPECT_TRUE(parseExpectError("\n"325 "--- !Missed\n"326 "Pass: inline\n"327 "Name: NoDefinition\n"328 "Function: foo\n"329 "DebugLoc: { File: file.c, Column: { a: b }, Line: 12 }\n"330 "",331 "expected a value of scalar type."));332 // Not a integer line in debug loc.333 EXPECT_TRUE(parseExpectError("\n"334 "--- !Missed\n"335 "Pass: inline\n"336 "Name: NoDefinition\n"337 "Function: foo\n"338 "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"339 "",340 "expected a value of scalar type."));341 // Not a mapping type value for args.342 EXPECT_TRUE(parseExpectError("\n"343 "--- !Missed\n"344 "Pass: inline\n"345 "Name: NoDefinition\n"346 "Function: foo\n"347 "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"348 "",349 "expected a value of scalar type."));350}351 352TEST(YAMLRemarks, ParsingWrongArgs) {353 // Multiple debug locs per arg.354 EXPECT_TRUE(parseExpectError("\n"355 "--- !Missed\n"356 "Pass: inline\n"357 "Name: NoDefinition\n"358 "Function: foo\n"359 "Args:\n"360 " - Str: string\n"361 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"362 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"363 "",364 "only one DebugLoc entry is allowed per argument."));365 // Multiple strings per arg.366 EXPECT_TRUE(parseExpectError("\n"367 "--- !Missed\n"368 "Pass: inline\n"369 "Name: NoDefinition\n"370 "Function: foo\n"371 "Args:\n"372 " - Str: string\n"373 " Str2: string\n"374 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"375 "",376 "only one string entry is allowed per argument."));377 // No arg value.378 EXPECT_TRUE(parseExpectError("\n"379 "--- !Missed\n"380 "Pass: inline\n"381 "Name: NoDefinition\n"382 "Function: foo\n"383 "Args:\n"384 " - DebugLoc: { File: a, Line: 1, Column: 2 }\n"385 "",386 "argument key is missing."));387}388 389static inline StringRef checkStr(StringRef Str, unsigned ExpectedLen) {390 const char *StrData = Str.data();391 unsigned StrLen = Str.size();392 EXPECT_EQ(StrLen, ExpectedLen);393 return StringRef(StrData, StrLen);394}395 396TEST(YAMLRemarks, Contents) {397 StringRef Buf = "\n"398 "--- !Missed\n"399 "Pass: inline\n"400 "Name: NoDefinition\n"401 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"402 "Function: foo\n"403 "Hotness: 4\n"404 "Args:\n"405 " - Callee: bar\n"406 " - String: ' will not be inlined into '\n"407 " - Caller: foo\n"408 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"409 " - String: ' because its definition is unavailable'\n"410 "\n";411 412 Expected<std::unique_ptr<remarks::RemarkParser>> MaybeParser =413 remarks::createRemarkParser(remarks::Format::YAML, Buf);414 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));415 EXPECT_TRUE(*MaybeParser != nullptr);416 417 remarks::RemarkParser &Parser = **MaybeParser;418 Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();419 EXPECT_FALSE(420 errorToBool(MaybeRemark.takeError())); // Check for parsing errors.421 EXPECT_TRUE(*MaybeRemark != nullptr); // At least one remark.422 423 const remarks::Remark &Remark = **MaybeRemark;424 EXPECT_EQ(Remark.RemarkType, remarks::Type::Missed);425 EXPECT_EQ(checkStr(Remark.PassName, 6), "inline");426 EXPECT_EQ(checkStr(Remark.RemarkName, 12), "NoDefinition");427 EXPECT_EQ(checkStr(Remark.FunctionName, 3), "foo");428 EXPECT_TRUE(Remark.Loc);429 const remarks::RemarkLocation &RL = *Remark.Loc;430 EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");431 EXPECT_EQ(RL.SourceLine, 3U);432 EXPECT_EQ(RL.SourceColumn, 12U);433 EXPECT_TRUE(Remark.Hotness);434 EXPECT_EQ(*Remark.Hotness, 4U);435 EXPECT_EQ(Remark.Args.size(), 4U);436 437 unsigned ArgID = 0;438 for (const remarks::Argument &Arg : Remark.Args) {439 switch (ArgID) {440 case 0:441 EXPECT_EQ(checkStr(Arg.Key, 6), "Callee");442 EXPECT_EQ(checkStr(Arg.Val, 3), "bar");443 EXPECT_FALSE(Arg.Loc);444 break;445 case 1:446 EXPECT_EQ(checkStr(Arg.Key, 6), "String");447 EXPECT_EQ(checkStr(Arg.Val, 26), " will not be inlined into ");448 EXPECT_FALSE(Arg.Loc);449 break;450 case 2: {451 EXPECT_EQ(checkStr(Arg.Key, 6), "Caller");452 EXPECT_EQ(checkStr(Arg.Val, 3), "foo");453 EXPECT_TRUE(Arg.Loc);454 const remarks::RemarkLocation &RL = *Arg.Loc;455 EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");456 EXPECT_EQ(RL.SourceLine, 2U);457 EXPECT_EQ(RL.SourceColumn, 0U);458 break;459 }460 case 3:461 EXPECT_EQ(checkStr(Arg.Key, 6), "String");462 EXPECT_EQ(checkStr(Arg.Val, 38),463 " because its definition is unavailable");464 EXPECT_FALSE(Arg.Loc);465 break;466 default:467 break;468 }469 ++ArgID;470 }471 472 MaybeRemark = Parser.next();473 Error E = MaybeRemark.takeError();474 EXPECT_TRUE(E.isA<remarks::EndOfFileError>());475 EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.476}477 478static inline StringRef checkStr(LLVMRemarkStringRef Str,479 unsigned ExpectedLen) {480 const char *StrData = LLVMRemarkStringGetData(Str);481 unsigned StrLen = LLVMRemarkStringGetLen(Str);482 EXPECT_EQ(StrLen, ExpectedLen);483 return StringRef(StrData, StrLen);484}485 486TEST(YAMLRemarks, ContentsCAPI) {487 StringRef Buf = "\n"488 "--- !Missed\n"489 "Pass: inline\n"490 "Name: NoDefinition\n"491 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"492 "Function: foo\n"493 "Args:\n"494 " - Callee: bar\n"495 " - String: ' will not be inlined into '\n"496 " - Caller: foo\n"497 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"498 " - String: ' because its definition is unavailable'\n"499 "\n";500 501 LLVMRemarkParserRef Parser =502 LLVMRemarkParserCreateYAML(Buf.data(), Buf.size());503 LLVMRemarkEntryRef Remark = LLVMRemarkParserGetNext(Parser);504 EXPECT_FALSE(Remark == nullptr);505 EXPECT_EQ(LLVMRemarkEntryGetType(Remark), LLVMRemarkTypeMissed);506 EXPECT_EQ(checkStr(LLVMRemarkEntryGetPassName(Remark), 6), "inline");507 EXPECT_EQ(checkStr(LLVMRemarkEntryGetRemarkName(Remark), 12), "NoDefinition");508 EXPECT_EQ(checkStr(LLVMRemarkEntryGetFunctionName(Remark), 3), "foo");509 LLVMRemarkDebugLocRef DL = LLVMRemarkEntryGetDebugLoc(Remark);510 EXPECT_EQ(checkStr(LLVMRemarkDebugLocGetSourceFilePath(DL), 6), "file.c");511 EXPECT_EQ(LLVMRemarkDebugLocGetSourceLine(DL), 3U);512 EXPECT_EQ(LLVMRemarkDebugLocGetSourceColumn(DL), 12U);513 EXPECT_EQ(LLVMRemarkEntryGetHotness(Remark), 0U);514 EXPECT_EQ(LLVMRemarkEntryGetNumArgs(Remark), 4U);515 516 unsigned ArgID = 0;517 LLVMRemarkArgRef Arg = LLVMRemarkEntryGetFirstArg(Remark);518 do {519 switch (ArgID) {520 case 0:521 EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "Callee");522 EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 3), "bar");523 EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);524 break;525 case 1:526 EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "String");527 EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 26),528 " will not be inlined into ");529 EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);530 break;531 case 2: {532 EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "Caller");533 EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 3), "foo");534 LLVMRemarkDebugLocRef DL = LLVMRemarkArgGetDebugLoc(Arg);535 EXPECT_EQ(checkStr(LLVMRemarkDebugLocGetSourceFilePath(DL), 6), "file.c");536 EXPECT_EQ(LLVMRemarkDebugLocGetSourceLine(DL), 2U);537 EXPECT_EQ(LLVMRemarkDebugLocGetSourceColumn(DL), 0U);538 break;539 }540 case 3:541 EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "String");542 EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 38),543 " because its definition is unavailable");544 EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);545 break;546 default:547 break;548 }549 ++ArgID;550 } while ((Arg = LLVMRemarkEntryGetNextArg(Arg, Remark)));551 552 LLVMRemarkEntryDispose(Remark);553 554 EXPECT_EQ(LLVMRemarkParserGetNext(Parser), nullptr);555 556 EXPECT_FALSE(LLVMRemarkParserHasError(Parser));557 LLVMRemarkParserDispose(Parser);558}559 560TEST(YAMLRemarks, ParsingGoodMeta) {561 // No metadata should also work.562 parseGoodMeta("--- !Missed\n"563 "Pass: inline\n"564 "Name: NoDefinition\n"565 "Function: foo\n");566 567 // No string table.568 parseGoodMeta(StringRef("REMARKS\0"569 "\0\0\0\0\0\0\0\0"570 "\0\0\0\0\0\0\0\0"571 "--- !Missed\n"572 "Pass: inline\n"573 "Name: NoDefinition\n"574 "Function: foo\n",575 82));576}577 578TEST(YAMLRemarks, ParsingBadMeta) {579 parseExpectErrorMeta(StringRef("REMARKSS", 9),580 "Expecting \\0 after magic number.", CmpType::Equal);581 582 parseExpectErrorMeta(StringRef("REMARKS\0", 8), "Expecting version number.",583 CmpType::Equal);584 585 parseExpectErrorMeta(StringRef("REMARKS\0"586 "\x09\0\0\0\0\0\0\0",587 16),588 "Mismatching remark version. Got 9, expected 0.",589 CmpType::Equal);590 591 parseExpectErrorMeta(StringRef("REMARKS\0"592 "\0\0\0\0\0\0\0\0",593 16),594 "Expecting string table size.", CmpType::Equal);595 596 parseExpectErrorMeta(StringRef("REMARKS\0"597 "\0\0\0\0\0\0\0\0"598 "\x01\0\0\0\0\0\0\0",599 24),600 "String table unsupported for YAML format.",601 CmpType::Equal);602 603 parseExpectErrorMeta(StringRef("REMARKS\0"604 "\0\0\0\0\0\0\0\0"605 "\0\0\0\0\0\0\0\0"606 "/path/",607 30),608 "'/path/'", CmpType::Contains);609 610 parseExpectErrorMeta(StringRef("REMARKS\0"611 "\0\0\0\0\0\0\0\0"612 "\0\0\0\0\0\0\0\0"613 "/path/",614 30),615 "'/baddir/path/'", CmpType::Contains,616 StringRef("/baddir/"));617}618