[PATCH] FileCheck: Permit CHECK-NEXT as the first directive

Alp Toker alp at nuanti.com
Mon Apr 21 23:20:14 PDT 2014


There doesn't seem to be a way to check for file start and end with 
FileCheck right now.

This has been problematic for tests under clang/test/CodeCompletion 
which currently pass silently even if the output begins or ends with 
incorrect results.

There are various ways to go about this:

1) Add new CHECK-START and CHECK-END directives
2) Support \A and \Z in the regex engine
3) Permit CHECK-NEXT as the first directive and use existing CHECK-NOT 
facilities to test for EOF.

Of the available options the attached patch implements option 3.

A corresponding clang patch is also provided demonstrating the use case.

Alp.

-- 
http://www.nuanti.com
the browser experts

-------------- next part --------------
commit ca519181a0e14e55b99b1f5017dd28b4641702c4
Author: Alp Toker <alp at nuanti.com>
Date:   Tue Apr 22 06:45:21 2014 +0100

    CHECK-NEXT

diff --git a/docs/CommandGuide/FileCheck.rst b/docs/CommandGuide/FileCheck.rst
index 5a60d60..c0cd0fb 100644
--- a/docs/CommandGuide/FileCheck.rst
+++ b/docs/CommandGuide/FileCheck.rst
@@ -171,8 +171,9 @@ For example, something like this works as you'd expect:
    }
 
 "``CHECK-NEXT:``" directives reject the input unless there is exactly one
-newline between it and the previous directive.  A "``CHECK-NEXT:``" cannot be
-the first directive in a file.
+newline between it and the previous directive.  A "``CHECK-NEXT:``"
+appearing as the first directive requires the match to be in the first line
+of input.
 
 The "CHECK-NOT:" directive
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/test/FileCheck/next-first-line.txt b/test/FileCheck/next-first-line.txt
new file mode 100644
index 0000000..7d635bb
--- /dev/null
+++ b/test/FileCheck/next-first-line.txt
@@ -0,0 +1,8 @@
+foo
+bar
+
+; RUN: FileCheck -input-file %s %s -check-prefix=T1
+; RUN: not FileCheck -input-file %s %s -check-prefix=T2
+
+; T1-NEXT: foo
+; T2-NEXT: bar
diff --git a/utils/FileCheck/FileCheck.cpp b/utils/FileCheck/FileCheck.cpp
index a124377..6e45dc3 100644
--- a/utils/FileCheck/FileCheck.cpp
+++ b/utils/FileCheck/FileCheck.cpp
@@ -889,15 +889,6 @@ static bool ReadCheckFile(SourceMgr &SM,
 
     Buffer = Buffer.substr(EOL);
 
-    // Verify that CHECK-NEXT lines have at least one CHECK line before them.
-    if ((CheckTy == Check::CheckNext) && CheckStrings.empty()) {
-      SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
-                      SourceMgr::DK_Error,
-                      "found '" + UsedPrefix + "-NEXT:' without previous '"
-                      + UsedPrefix + ": line");
-      return true;
-    }
-
     // Handle CHECK-DAG/-NOT.
     if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
       DagNotMatches.push_back(P);
@@ -1037,15 +1028,15 @@ bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
     return false;
 
   // Count the number of newlines between the previous match and this one.
-  assert(Buffer.data() !=
-         SM.getMemoryBuffer(
-           SM.FindBufferContainingLoc(
-             SMLoc::getFromPointer(Buffer.data())))->getBufferStart() &&
-         "CHECK-NEXT can't be the first check in a file");
-
   const char *FirstNewLine = 0;
   unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
 
+  // CHECK-NEXT can be the first check in a file
+  if (Buffer.data() ==
+      SM.getMemoryBuffer(SM.FindBufferContainingLoc(SMLoc::getFromPointer(
+                             Buffer.data())))->getBufferStart())
+    NumNewLines++;
+
   if (NumNewLines == 0) {
     SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix +
                     "-NEXT: is on the same line as previous match");
-------------- next part --------------
commit 3e7a01d9e885d2da2ce89729f136f413e45e6ca6
Author: Alp Toker <alp at nuanti.com>
Date:   Tue Apr 22 06:50:22 2014 +0100

    Fix code completion switch case tests
    
    They would previously pass even if incorrect completion results preceded or
    followed the expected ones.

diff --git a/test/CodeCompletion/enum-switch-case-qualified.cpp b/test/CodeCompletion/enum-switch-case-qualified.cpp
index 0f25671..b01463f 100644
--- a/test/CodeCompletion/enum-switch-case-qualified.cpp
+++ b/test/CodeCompletion/enum-switch-case-qualified.cpp
@@ -22,11 +22,11 @@ void test(enum N::C::Color color) {
   switch (color) {
   case 
     // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:23:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
-    // CHECK-CC1: Blue : [#M::N::C::Color#]N::C::Blue
+    // CHECK-CC1-NEXT: Blue : [#M::N::C::Color#]N::C::Blue
     // CHECK-CC1-NEXT: Green : [#M::N::C::Color#]N::C::Green
     // CHECK-CC1-NEXT: Indigo : [#M::N::C::Color#]N::C::Indigo
     // CHECK-CC1-NEXT: Orange : [#M::N::C::Color#]N::C::Orange
     // CHECK-CC1-NEXT: Red : [#M::N::C::Color#]N::C::Red
     // CHECK-CC1-NEXT: Violet : [#M::N::C::Color#]N::C::Violet
-    // CHECK-CC1: Yellow : [#M::N::C::Color#]N::C::Yellow
-      
+    // CHECK-CC1-NEXT: Yellow : [#M::N::C::Color#]N::C::Yellow
+    // CHECK-CC1-NOT: {{^.}}
diff --git a/test/CodeCompletion/enum-switch-case.c b/test/CodeCompletion/enum-switch-case.c
index 264f46a..e38e824 100644
--- a/test/CodeCompletion/enum-switch-case.c
+++ b/test/CodeCompletion/enum-switch-case.c
@@ -26,14 +26,15 @@ void test(enum Color color) {
   }
 
     // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:10 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
-    // CHECK-CC1: Blue
-    // CHECK-CC1-NEXT: Green
-    // CHECK-CC1-NEXT: Indigo
-    // CHECK-CC1-NEXT: Orange
-    // CHECK-CC1-NEXT: Violet
+    // CHECK-CC1-NEXT: ]Blue
+    // CHECK-CC1-NEXT: ]Green
+    // CHECK-CC1-NEXT: ]Indigo
+    // CHECK-CC1-NEXT: ]Orange
+    // CHECK-CC1-NEXT: ]Violet
+    // CHECK-CC1-NOT: {{^.}}
 
-    // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:25:10 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s      
-  // CHECK-CC2: COMPLETION: Blue : [#enum Color#]Blue
+  // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:25:10 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s      
+  // CHECK-CC2-NEXT: COMPLETION: Blue : [#enum Color#]Blue
   // CHECK-CC2-NEXT: COMPLETION: c2 : [#unsigned int#]c2
   // CHECK-CC2-NEXT: COMPLETION: color : [#enum Color#]color
   // CHECK-CC2-NEXT: COMPLETION: Green : [#enum Color#]Green
@@ -43,3 +44,4 @@ void test(enum Color color) {
   // CHECK-CC2-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
   // CHECK-CC2-NEXT: COMPLETION: Violet : [#enum Color#]Violet
   // CHECK-CC2-NEXT: COMPLETION: Yellow : [#enum Color#]Yellow
+  // CHECK-CC2-NOT: {{^.}}
diff --git a/test/CodeCompletion/enum-switch-case.cpp b/test/CodeCompletion/enum-switch-case.cpp
index 997845a..972f098 100644
--- a/test/CodeCompletion/enum-switch-case.cpp
+++ b/test/CodeCompletion/enum-switch-case.cpp
@@ -20,9 +20,9 @@ void test(enum N::Color color) {
     
   case 
     // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:21:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
-    // CHECK-CC1: Blue : [#N::Color#]N::Blue
+    // CHECK-CC1-NEXT: Blue : [#N::Color#]N::Blue
     // CHECK-CC1-NEXT: Green : [#N::Color#]N::Green
     // CHECK-CC1-NEXT: Indigo : [#N::Color#]N::Indigo
     // CHECK-CC1-NEXT: Orange : [#N::Color#]N::Orange
     // CHECK-CC1-NEXT: Violet : [#N::Color#]N::Violet
-    
+    // CHECK-CC1-NOT: {{^.}}


More information about the llvm-commits mailing list