[llvm] 48c864a - [FileCheck] Handle directives at EOF without a trailing newline (#196576)
via llvm-commits
llvm-commits at lists.llvm.org
Mon May 11 11:56:47 PDT 2026
Author: savchart
Date: 2026-05-11T14:56:42-04:00
New Revision: 48c864a0bdd315f20acb1dbaf8e8bb37aab707e5
URL: https://github.com/llvm/llvm-project/commit/48c864a0bdd315f20acb1dbaf8e8bb37aab707e5
DIFF: https://github.com/llvm/llvm-project/commit/48c864a0bdd315f20acb1dbaf8e8bb37aab707e5.diff
LOG: [FileCheck] Handle directives at EOF without a trailing newline (#196576)
FileCheck could assert when a check directive ended at EOF without a
trailing newline. After parsing the directive suffix, EOF can be a valid
continuation point, so parsing now continues directly from
`AfterSuffix`.
Fixes #101582
Added:
llvm/test/FileCheck/check-eof-no-pattern.txt
Modified:
llvm/lib/FileCheck/FileCheck.cpp
llvm/test/FileCheck/check-empty-tag.txt
Removed:
################################################################################
diff --git a/llvm/lib/FileCheck/FileCheck.cpp b/llvm/lib/FileCheck/FileCheck.cpp
index 4d3ac87b9c724..38c61cd60174d 100644
--- a/llvm/lib/FileCheck/FileCheck.cpp
+++ b/llvm/lib/FileCheck/FileCheck.cpp
@@ -1881,18 +1881,18 @@ bool FileCheck::readCheckFile(
assert(UsedPrefix.data() == Buffer.data() &&
"Failed to move Buffer's start forward, or pointed prefix outside "
"of the buffer!");
+
+ const char *BufferEnd = Buffer.data() + Buffer.size();
assert(AfterSuffix.data() >= Buffer.data() &&
- AfterSuffix.data() < Buffer.data() + Buffer.size() &&
+ AfterSuffix.data() <= BufferEnd &&
"Parsing after suffix doesn't start inside of buffer!");
+ // Skip the buffer to the end of the parsed directive suffix.
+ Buffer = AfterSuffix;
+
// Location to use for error messages.
const char *UsedPrefixStart = UsedPrefix.data();
- // Skip the buffer to the end of parsed suffix (or just prefix, if no good
- // suffix was processed).
- Buffer = AfterSuffix.empty() ? Buffer.drop_front(UsedPrefix.size())
- : AfterSuffix;
-
// Complain about misspelled directives.
if (CheckTy == Check::CheckMisspelled) {
StringRef UsedDirective(UsedPrefix.data(),
diff --git a/llvm/test/FileCheck/check-empty-tag.txt b/llvm/test/FileCheck/check-empty-tag.txt
index c398bcf596fcf..462eb127e69dc 100644
--- a/llvm/test/FileCheck/check-empty-tag.txt
+++ b/llvm/test/FileCheck/check-empty-tag.txt
@@ -31,6 +31,18 @@ CHECK3B: found non-empty check string for empty check with prefix 'CHECK3A:'
CHECK4A-EMPTY:
CHECK4B: found 'CHECK4A-EMPTY' without previous 'CHECK4A: line
+; CHECK-EMPTY at EOF without trailing newline cannot be the first check.
+; RUN: printf "# CHECK-EMPTY:" > %t.no-newline-fail.chk
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck --allow-empty --input-file=/dev/null %t.no-newline-fail.chk 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK4C
+CHECK4C: found 'CHECK-EMPTY' without previous 'CHECK: line
+
+; CHECK-EMPTY at EOF without trailing newline still works after a prior check.
+; RUN: printf "foo\n\n" > %t.no-newline-success.in
+; RUN: printf "CHECK: foo\nCHECK-EMPTY:" > %t.no-newline-success.chk
+; RUN: FileCheck --input-file=%t.no-newline-success.in %t.no-newline-success.chk
+
; CHECK-EMPTY-NOT and CHECK-NOT-EMPTY rejected
; RUN: %ProtectFileCheckOutput \
; RUN: not FileCheck %s --input-file %s --check-prefixes=CHECK5A 2>&1 \
diff --git a/llvm/test/FileCheck/check-eof-no-pattern.txt b/llvm/test/FileCheck/check-eof-no-pattern.txt
new file mode 100644
index 0000000000000..b037285fcf5b8
--- /dev/null
+++ b/llvm/test/FileCheck/check-eof-no-pattern.txt
@@ -0,0 +1,7 @@
+; CHECK requires a pattern, so the no-newline EOF case must fail here.
+; RUN: printf "CHECK:" > %t.no-pattern.chk
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck --allow-empty --input-file=/dev/null %t.no-pattern.chk 2>&1 \
+; RUN: | FileCheck %s --check-prefix=ERR-EMPTY-CHECK
+
+ERR-EMPTY-CHECK: error: found empty check string
More information about the llvm-commits
mailing list