diff --git a/llvm/lib/Support/FileCheck.cpp b/llvm/lib/Support/FileCheck.cpp --- a/llvm/lib/Support/FileCheck.cpp +++ b/llvm/lib/Support/FileCheck.cpp @@ -1874,33 +1874,37 @@ return StartPos; } -// A check prefix must contain only alphanumeric, hyphens and underscores. -static bool ValidateCheckPrefix(StringRef CheckPrefix) { - static const Regex Validator("^[a-zA-Z0-9_-]*$"); - return Validator.match(CheckPrefix); -} - -bool FileCheck::ValidateCheckPrefixes() { - StringSet<> PrefixSet; - - for (StringRef Prefix : Req.CheckPrefixes) { - // Reject empty prefixes. - if (Prefix.empty()) +static bool ValidatePrefixes(StringSet<> &UniquePrefixes, + ArrayRef SuppliedPrefixes) { + for (StringRef Prefix : SuppliedPrefixes) { + if (Prefix.empty()) { + errs() << "error: supplied check prefix must not be the empty string\n"; return false; - - if (!PrefixSet.insert(Prefix).second) + } + static const Regex Validator("^[a-zA-Z0-9_-]*$"); + if (!Validator.match(Prefix)) { + errs() << "error: supplied check prefix must start with a letter and " + << "contain only alphanumeric characters, hyphens, and " + << "underscores: '" << Prefix << "'\n"; return false; - - if (!ValidateCheckPrefix(Prefix)) + } + if (!UniquePrefixes.insert(Prefix).second) { + errs() << "error: supplied check prefix must be unique among check " + << "prefixes: '" << Prefix << "'\n"; return false; + } } + return true; +} +bool FileCheck::ValidateCheckPrefixes() { + StringSet<> UniquePrefixes; + if (!ValidatePrefixes(UniquePrefixes, Req.CheckPrefixes)) + return false; return true; } Regex FileCheck::buildCheckPrefixRegex() { - // I don't think there's a way to specify an initial value for cl::list, - // so if nothing was specified, add the default if (Req.CheckPrefixes.empty()) { Req.CheckPrefixes.push_back("CHECK"); Req.IsDefaultCheckPrefix = true; diff --git a/llvm/test/FileCheck/validate-check-prefix.txt b/llvm/test/FileCheck/validate-check-prefix.txt --- a/llvm/test/FileCheck/validate-check-prefix.txt +++ b/llvm/test/FileCheck/validate-check-prefix.txt @@ -1,10 +1,13 @@ // RUN: %ProtectFileCheckOutput not FileCheck -check-prefix=A! -input-file %s %s 2>&1 | FileCheck -check-prefix=BAD_PREFIX %s // RUN: FileCheck -check-prefix=A1a-B_c -input-file %s %s -// RUN: %ProtectFileCheckOutput not FileCheck -check-prefix=REPEAT -check-prefix=REPEAT -input-file %s %s 2>&1 | FileCheck -check-prefix=BAD_PREFIX %s +// RUN: %ProtectFileCheckOutput not FileCheck -check-prefix=REPEAT -check-prefix=REPEAT -input-file %s %s 2>&1 | FileCheck -check-prefix=DUPLICATE_PREFIX %s // RUN: %ProtectFileCheckOutput not FileCheck -check-prefix=VALID -check-prefix=A! -input-file %s %s 2>&1 | FileCheck -check-prefix=BAD_PREFIX %s -// RUN: %ProtectFileCheckOutput not FileCheck -check-prefix= -input-file %s %s 2>&1 | FileCheck -check-prefix=BAD_PREFIX %s +// RUN: %ProtectFileCheckOutput not FileCheck -check-prefix= -input-file %s %s 2>&1 | FileCheck -check-prefix=EMPTY_PREFIX %s foobar ; A1a-B_c: foobar -; BAD_PREFIX: Supplied check-prefix is invalid! Prefixes must be - unique and start with a letter and contain only alphanumeric characters, hyphens and underscores +; BAD_PREFIX: supplied check prefix must start with a letter and contain only alphanumeric characters, hyphens, and underscores: 'A!' + +; DUPLICATE_PREFIX: error: supplied check prefix must be unique among check prefixes: 'REPEAT' + +; EMPTY_PREFIX: error: supplied check prefix must not be the empty string diff --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp --- a/llvm/utils/FileCheck/FileCheck.cpp +++ b/llvm/utils/FileCheck/FileCheck.cpp @@ -601,12 +601,8 @@ Req.Verbose = true; FileCheck FC(Req); - if (!FC.ValidateCheckPrefixes()) { - errs() << "Supplied check-prefix is invalid! Prefixes must be unique and " - "start with a letter and contain only alphanumeric characters, " - "hyphens and underscores\n"; + if (!FC.ValidateCheckPrefixes()) return 2; - } Regex PrefixRE = FC.buildCheckPrefixRegex(); std::string REError;