[llvm-branch-commits] [llvm] [Support] Reject out-of-range line offsets in verify directives (PR #233305)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Oct 18 15:10:44 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-support
Author: Alexander Richardson (arichardson)
<details>
<summary>Changes</summary>
`@+N` and `@-N` offsets were parsed with radix auto-detection into an
`int` without checking for errors, so `@+010` meant 8, `@+08` used an
uninitialized value, and offsets pointing outside of the file silently
wrapped around. Parse them as decimal and report invalid and
out-of-range offsets. Line 0 is still allowed since MLIR uses it for
the implicit top-level module.
Assisted-by: AI tooling
---
Full diff: https://github.com/llvm/llvm-project/pull/233305.diff
3 Files Affected:
- (modified) llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp (+21-4)
- (modified) llvm/test/tools/llvm-mc/verify/basic.s (+10-1)
- (modified) llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp (+36)
``````````diff
diff --git a/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp b/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp
index 75b0e27abe612..95b053967eca4 100644
--- a/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp
+++ b/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp
@@ -189,13 +189,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 e38d76fcc9777..82fd0a1f70bcf 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 \
@@ -118,6 +120,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 433c4d9de0291..58df0a59bf2c1 100644
--- a/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp
+++ b/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp
@@ -159,3 +159,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);
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/233305
More information about the llvm-branch-commits
mailing list