From a78e13745d4ee4a42e41ebbe698159f651515fc5 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Mon, 11 May 2020 09:57:37 -0400 Subject: [PATCH] [FileCheck] Make invalid prefix diagnostics more precise This will prove especially helpful after D79276, which introduces comment prefixes. Specifically, identifying whether there's a uniqueness violation will be helpful as prefixes will be required to be unique across both check prefixes and comment prefixes. Also, remove a related comment about `cl::list` that no longer seems relevant now that FileCheck is also a library. Reviewed By: jhenderson, thopre Differential Revision: https://reviews.llvm.org/D79375 --- llvm/lib/Support/FileCheck.cpp | 40 +++++++++++++++------------ llvm/test/FileCheck/validate-check-prefix.txt | 11 +++++--- llvm/utils/FileCheck/FileCheck.cpp | 6 +--- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/llvm/lib/Support/FileCheck.cpp b/llvm/lib/Support/FileCheck.cpp index b89cdfe..369b6df 100644 --- a/llvm/lib/Support/FileCheck.cpp +++ b/llvm/lib/Support/FileCheck.cpp @@ -1874,33 +1874,37 @@ size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer, 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 index de6f126..29f352c 100644 --- 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 index 3f7d777..46821ec 100644 --- a/llvm/utils/FileCheck/FileCheck.cpp +++ b/llvm/utils/FileCheck/FileCheck.cpp @@ -601,12 +601,8 @@ int main(int argc, char **argv) { 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; -- 2.7.4