[llvm-branch-commits] [llvm] [Support] Reject out-of-range line offsets in verify directives (PR #233305)
Alexander Richardson via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Oct 20 14:56:55 PDT 2026
https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/233305
>From 031c372506ff4bf2e940447195a1a8ce0b256f9e Mon Sep 17 00:00:00 2001
From: Alex Richardson <alexrichardson at google.com>
Date: Tue, 20 Oct 2026 14:56:15 -0700
Subject: [PATCH] [nspr] initial commit
---
.../Support/SourceMgrDiagnosticVerifier.cpp | 25 ++++++++++---
llvm/test/tools/llvm-mc/verify/basic.s | 11 +++++-
.../SourceMgrDiagnosticVerifierTest.cpp | 36 +++++++++++++++++++
3 files changed, 67 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp b/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp
index bf551f90e13d0..cd8b4c4c04730 100644
--- a/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp
+++ b/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp
@@ -188,13 +188,30 @@ SourceMgrDiagnosticVerifier::computeExpectedDiags(const MemoryBuffer *buf) {
// Get the integer value without the @ and +/- prefix.
if (offsetMatch[0] == '+' || offsetMatch[0] == '-') {
- int offset;
- offsetMatch.drop_front().getAsInteger(0, offset);
+ // Parse as decimal so that e.g. '@+08' is not treated as octal.
+ unsigned offset;
+ if (offsetMatch.drop_front().getAsInteger(10, offset)) {
+ emitError(record, "invalid line offset '" + offsetMatch + "'");
+ continue;
+ }
- if (offsetMatch.front() == '+')
+ if (offsetMatch.front() == '+') {
+ if (offset > e - record.lineNo) {
+ emitError(record, "line offset '" + offsetMatch +
+ "' is past the end of the file");
+ continue;
+ }
record.lineNo += offset;
- else
+ } else {
+ // Line 0 is allowed since MLIR uses it for the implicit top-level
+ // module.
+ if (offset > record.lineNo) {
+ emitError(record, "line offset '" + offsetMatch +
+ "' is before the start of the file");
+ continue;
+ }
record.lineNo -= offset;
+ }
} else if (offsetMatch.consume_front("unknown")) {
if (record.colNo != 0) {
emitError(record, "cannot specify a column with '@unknown'");
diff --git a/llvm/test/tools/llvm-mc/verify/basic.s b/llvm/test/tools/llvm-mc/verify/basic.s
index d79c6006f4be8..787ae59c255f7 100644
--- a/llvm/test/tools/llvm-mc/verify/basic.s
+++ b/llvm/test/tools/llvm-mc/verify/basic.s
@@ -18,9 +18,11 @@
## of a longer word such as 'uncheck'.
# RUN: llvm-mc --triple=riscv32 --verify=check,alt custom-prefix.s
-## Malformed '-re' directives fail verification.
+## Malformed '-re' directives and out-of-range line offsets fail verification.
# RUN: not llvm-mc --triple=riscv32 --verify invalid-regex.s 2>&1 \
# RUN: | FileCheck invalid-regex.s
+# RUN: not llvm-mc --triple=riscv32 --verify invalid-offset.s 2>&1 \
+# RUN: | FileCheck invalid-offset.s
## A diagnostic that matches the text but not the kind of a directive.
# RUN: not llvm-mc --triple=riscv32 --verify near-miss.s 2>&1 \
@@ -127,6 +129,13 @@ addi a0, a0, 1
# CHECK: error: found start of regex with no end '}}'
# CHECK: error: invalid regex:
+#--- invalid-offset.s
+addi a0, a0, 1
+# expected-error at -99 {{before start}}
+# expected-error at +99 {{past end}}
+# CHECK: error: line offset '-99' is before the start of the file
+# CHECK: error: line offset '+99' is past the end of the file
+
#--- near-miss.s
.foo_directive
# expected-warning at -1 {{unknown directive}}
diff --git a/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp b/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp
index a749c337dd12e..853d2394cafe6 100644
--- a/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp
+++ b/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp
@@ -188,3 +188,39 @@ TEST_F(SourceMgrDiagnosticVerifierTest, ColumnChecking) {
MatchResult::Matched);
EXPECT_FALSE(Verifier.verify());
}
+
+TEST_F(SourceMgrDiagnosticVerifierTest, LineZeroAndLeadingZeroOffsets) {
+ const MemoryBuffer *Buf =
+ addBuffer("// expected-error at +02 {{decimal leading zero}}\n"
+ "// expected-remark at -2 {{implicit module at line 0}}\n"
+ "op\n");
+ SourceMgrDiagnosticVerifier Verifier(SM, OS);
+
+ using Location = SourceMgrDiagnosticVerifier::Location;
+ EXPECT_EQ(Verifier.process(SourceMgr::DK_Remark, Location{Buf, 0, 0},
+ "implicit module at line 0"),
+ MatchResult::Matched);
+ EXPECT_EQ(Verifier.process(SourceMgr::DK_Error, Location{Buf, 3, 1},
+ "decimal leading zero"),
+ MatchResult::Matched);
+ EXPECT_TRUE(Verifier.verify());
+ EXPECT_EQ(Output, "");
+}
+
+TEST_F(SourceMgrDiagnosticVerifierTest, OutOfBoundsLineOffsets) {
+ addBuffer("op\n"
+ "# expected-error at -3 {{before start}}\n"
+ "# expected-error at +5 {{past end}}\n"
+ "# expected-error at +99999999999 {{overflow}}\n");
+ SourceMgrDiagnosticVerifier Verifier(SM, OS);
+
+ EXPECT_FALSE(Verifier.verify());
+ EXPECT_NE(StringRef(Output).find(
+ "error: line offset '-3' is before the start of the file"),
+ StringRef::npos);
+ EXPECT_NE(StringRef(Output).find(
+ "error: line offset '+5' is past the end of the file"),
+ StringRef::npos);
+ EXPECT_NE(StringRef(Output).find("error: invalid line offset '+99999999999'"),
+ StringRef::npos);
+}
More information about the llvm-branch-commits
mailing list