diff --git a/test/FileCheck/no-multi-suffixes.txt b/test/FileCheck/no-multi-suffixes.txt new file mode 100644 index 00000000000..812a2956cd2 --- /dev/null +++ b/test/FileCheck/no-multi-suffixes.txt @@ -0,0 +1,28 @@ +; RUN: not FileCheck -check-prefix=DAGNOT -input-file %s %s 2>&1 | FileCheck -check-prefix=ERROR -check-prefix=DAGNOT-ERROR %s +; RUN: not FileCheck -check-prefix=NOTDAG -input-file %s %s 2>&1 | FileCheck -check-prefix=ERROR -check-prefix=NOTDAG-ERROR %s +; RUN: not FileCheck -check-prefix=NEXTNOT -input-file %s %s 2>&1 | FileCheck -check-prefix=ERROR -check-prefix=NEXTNOT-ERROR %s +; RUN: not FileCheck -check-prefix=NOTNEXT -input-file %s %s 2>&1 | FileCheck -check-prefix=ERROR -check-prefix=NOTNEXT-ERROR %s +; RUN: not FileCheck -check-prefix=SAMENOT -input-file %s %s 2>&1 | FileCheck -check-prefix=ERROR -check-prefix=SAMENOT-ERROR %s +; RUN: not FileCheck -check-prefix=NOTSAME -input-file %s %s 2>&1 | FileCheck -check-prefix=ERROR -check-prefix=NOTSAME-ERROR %s + +foo +; DAGNOT: foo +; DAGNOT-DAG-NOT: bar +; NOTDAG: foo +; NOTDAG-NOT-DAG: bar +; NEXTNOT: foo +; NEXTNOT-NEXT-NOT: bar +; NOTNEXT: foo +; NOTNEXT-NOT-NEXT: bar +; SAMENOT: foo +; SAMENOT-SAME-NOT: bar +; NOTSAME: foo +; NOTSAME-NOT-SAME: bar + +; ERROR: error: unsupported -NOT combo on prefix +; DAGNOT-ERROR-SAME: 'DAGNOT' +; NOTDAG-ERROR-SAME: 'NOTDAG' +; NEXTNOT-ERROR-SAME: 'NEXTNOT' +; NOTNEXT-ERROR-SAME: 'NOTNEXT' +; SAMENOT-ERROR-SAME: 'SAMENOT' +; NOTSAME-ERROR-SAME: 'NOTSAME' diff --git a/utils/FileCheck/FileCheck.cpp b/utils/FileCheck/FileCheck.cpp index 593ea9f441b..69f93020317 100644 --- a/utils/FileCheck/FileCheck.cpp +++ b/utils/FileCheck/FileCheck.cpp @@ -86,7 +86,9 @@ namespace Check { /// MatchEOF - When set, this pattern only matches the end of file. This is /// used for trailing CHECK-NOTs. - CheckEOF + CheckEOF, + /// CheckBadNot - Found -NOT combined with another CHECK suffix. + CheckBadNot }; } @@ -693,6 +695,7 @@ static bool IsPartOfWord(char c) { static size_t CheckTypeSize(Check::CheckType Ty) { switch (Ty) { case Check::CheckNone: + case Check::CheckBadNot: return 0; case Check::CheckPlain: @@ -746,6 +749,12 @@ static Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) { if (Rest.startswith("LABEL:")) return Check::CheckLabel; + // You can't combine -NOT with another suffix. + if (Rest.startswith("DAG-NOT:") || Rest.startswith("NOT-DAG:") || + Rest.startswith("NEXT-NOT:") || Rest.startswith("NOT-NEXT:") || + Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:")) + return Check::CheckBadNot; + return Check::CheckNone; } @@ -914,6 +923,14 @@ static bool ReadCheckFile(SourceMgr &SM, // PrefixLoc is to the start of the prefix. Skip to the end. Buffer = Buffer.drop_front(UsedPrefix.size() + CheckTypeSize(CheckTy)); + // Complain about useful-looking but unsupported suffixes. + if (CheckTy == Check::CheckBadNot) { + SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), + SourceMgr::DK_Error, + "unsupported -NOT combo on prefix '" + UsedPrefix + "'"); + return true; + } + // Okay, we found the prefix, yay. Remember the rest of the line, but ignore // leading and trailing whitespace. Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));