std::vector<StringRef> ImplicitCheckNot;
std::vector<StringRef> GlobalDefines;
bool AllowEmptyInput = false;
+ bool AllowUnusedPrefixes = false;
bool MatchFullLines = false;
bool IgnoreCase = false;
bool IsDefaultCheckPrefix = false;
#include "llvm/Support/FormatVariadic.h"
#include <cstdint>
#include <list>
+#include <set>
#include <tuple>
#include <utility>
// found.
unsigned LineNumber = 1;
- bool FoundUsedCheckPrefix = false;
- while (1) {
+ std::set<StringRef> PrefixesNotFound(Req.CheckPrefixes.begin(),
+ Req.CheckPrefixes.end());
+ const size_t DistinctPrefixes = PrefixesNotFound.size();
+ while (true) {
Check::FileCheckType CheckTy;
// See if a prefix occurs in the memory buffer.
if (UsedPrefix.empty())
break;
if (CheckTy != Check::CheckComment)
- FoundUsedCheckPrefix = true;
+ PrefixesNotFound.erase(UsedPrefix);
assert(UsedPrefix.data() == Buffer.data() &&
"Failed to move Buffer's start forward, or pointed prefix outside "
// When there are no used prefixes we report an error except in the case that
// no prefix is specified explicitly but -implicit-check-not is specified.
- if (!FoundUsedCheckPrefix &&
+ const bool NoPrefixesFound = PrefixesNotFound.size() == DistinctPrefixes;
+ const bool SomePrefixesUnexpectedlyNotUsed =
+ !Req.AllowUnusedPrefixes && !PrefixesNotFound.empty();
+ if ((NoPrefixesFound || SomePrefixesUnexpectedlyNotUsed) &&
(ImplicitNegativeChecks.empty() || !Req.IsDefaultCheckPrefix)) {
errs() << "error: no check strings found with prefix"
- << (Req.CheckPrefixes.size() > 1 ? "es " : " ");
- for (size_t I = 0, E = Req.CheckPrefixes.size(); I != E; ++I) {
- if (I != 0)
+ << (PrefixesNotFound.size() > 1 ? "es " : " ");
+ bool First = true;
+ for (StringRef MissingPrefix : PrefixesNotFound) {
+ if (!First)
errs() << ", ";
- errs() << "\'" << Req.CheckPrefixes[I] << ":'";
+ errs() << "\'" << MissingPrefix << ":'";
+ First = false;
}
errs() << '\n';
return true;
--- /dev/null
+hello
+; P1: hello
\ No newline at end of file
--- /dev/null
+; RUN: not FileCheck --allow-unused-prefixes=false --check-prefixes=P1,P2 --input-file %S/Inputs/one-check.txt %S/Inputs/one-check.txt 2>&1 | FileCheck --check-prefix=MISSING-ONE %s
+; RUN: not FileCheck --allow-unused-prefixes=false --check-prefixes=P1,P2,P3 --input-file %S/Inputs/one-check.txt %S/Inputs/one-check.txt 2>&1 | FileCheck --check-prefix=MISSING-MORE %s
+; RUN: FileCheck --allow-unused-prefixes=true --check-prefixes=P1,P2 --input-file %S/Inputs/one-check.txt %S/Inputs/one-check.txt
+
+; Note: the default will be changed to 'false', at which time this run line
+; should be changed accordingly.
+; RUN: FileCheck --check-prefixes=P1,P2 --input-file %S/Inputs/one-check.txt %S/Inputs/one-check.txt
+
+; MISSING-ONE: error: no check strings found with prefix 'P2:'
+; MISSING-MORE: error: no check strings found with prefixes 'P2:', 'P3:'
\ No newline at end of file
cl::desc("Allow the input file to be empty. This is useful when making\n"
"checks that some error message does not occur, for example."));
+static cl::opt<bool> AllowUnusedPrefixes(
+ "allow-unused-prefixes", cl::init(true),
+ cl::desc("Allow prefixes to be specified but not appear in the test."));
+
static cl::opt<bool> MatchFullLines(
"match-full-lines", cl::init(false),
cl::desc("Require all positive matches to cover an entire input line.\n"
return 2;
Req.AllowEmptyInput = AllowEmptyInput;
+ Req.AllowUnusedPrefixes = AllowUnusedPrefixes;
Req.EnableVarScope = EnableVarScope;
Req.AllowDeprecatedDagOverlap = AllowDeprecatedDagOverlap;
Req.Verbose = Verbose;