[flang-commits] [flang] [flang] Reorder messages wrt line number before diff(actual, expect) (PR #186812)
Krzysztof Parzyszek via flang-commits
flang-commits at lists.llvm.org
Mon Mar 16 07:48:02 PDT 2026
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/186812
When messages are attached together, the source locations to which they refer are not necessarily monotonically increasing. For example
```
error: foo.f90:10: There is a problem here # line 10
because: foo.f90:12: This thing is invalid # line 12 (attached)
error: foo.f90:11: There is another problem here # line 11
```
There is no way to represent that in the source flle via ERROR annotations, so before running unified_diff "canonicalize" the list of messages into an order that corresponds to the line numbers.
>From 466dba8948313acebe744024750ba973257ddef4 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Mon, 16 Mar 2026 09:28:02 -0500
Subject: [PATCH] [flang] Reorder messages wrt line number before diff(actual,
expect)
When messages are attached together, the source locations to which they
refer are not necessarily monotonically increasing. For example
```
error: foo.f90:10: There is a problem here # line 10
because: foo.f90:12: This thing is invalid # line 12 (attached)
error: foo.f90:11: There is another problem here # line 11
```
There is no way to represent that in the source flle via ERROR annotations,
so before running unified_diff "canonicalize" the list of messages into an
order that corresponds to the line numbers.
---
flang/test/Semantics/test_errors.py | 55 +++++++++++++++++++++++++----
1 file changed, 49 insertions(+), 6 deletions(-)
diff --git a/flang/test/Semantics/test_errors.py b/flang/test/Semantics/test_errors.py
index 45684764a00e4..95d974954b7d1 100755
--- a/flang/test/Semantics/test_errors.py
+++ b/flang/test/Semantics/test_errors.py
@@ -15,12 +15,46 @@
from difflib import unified_diff
+# When messages are attached together, the source locations to which they
+# refer are not necessarily monotonically increasing. For example
+# error: foo.f90:10: There is a problem here # line 10
+# because: foo.f90:12: This thing is invalid # line 12 (attached)
+# error: foo.f90:11: There is another problem here # line 11
+# There is no way to represent that in the source flle via ERROR annotations,
+# so before running unified_diff "canonicalize" the list of messages into an
+# order that corresponds to the line numbers.
+#
+# This also eliminates the issue with multiple messages emitted for the same
+# line: they can now be "expected" in the test file in any order, e.g.
+# !ERROR: Not enough arguments in a call to foo
+# !ERROR: `foo` is a subroutine, not a function
+# a = foo()
+# has the same effect as:
+# !ERROR: `foo` is a subroutine, not a function
+# !ERROR: Not enough arguments in a call to foo
+# a = foo()
+
+
+def join_per_line_map(m):
+ """Take a map {"line_no:": [message1, message2, ...], ...} and convert
+ it into a newline-separated string that follows the line ordering.
+ """
+ # Sort messages for each line, and prepend the line number to each
+ # message. Use numeric values of line numbers as keys to allow them
+ # to be sorted numerically.
+ sorted_lines_map = {
+ int(k.rstrip(":")): [k + s for s in sorted(m[k])] for k in m.keys()
+ }
+
+ joined_lines_list = []
+ for line in sorted(sorted_lines_map.keys()):
+ joined_lines_list.append("\n".join(sorted_lines_map[line]))
+ return "\n".join(joined_lines_list)
+
cm.check_args(sys.argv)
srcdir = cm.set_source(sys.argv[1])
with open(srcdir, "r", encoding="utf-8") as f:
src = f.readlines()
-actual = ""
-expect = ""
diffs = ""
log = ""
@@ -48,14 +82,21 @@
sys.exit(1)
# Cleans up the output from the compilation process to be easier to process
+actual_per_line = dict()
for line in log.split("\n"):
- m = re.search(r"[^:]*:(\d+:).*(?:error|warning|portability|because):(.*)", line)
+ m = re.search(
+ r"[^:]*:(\d+:).*(?:error|warning|portability|because):(.*)", line
+ )
if m:
if re.search(r"warning: .*fold.*host", line):
continue # ignore host-dependent folding warnings
- actual += m.expand(r"\1\2\n")
+ line_colon = m.expand(r"\1")
+ actual_per_line[line_colon] = actual_per_line.get(line_colon, []) + [
+ m.expand(r"\2")
+ ]
# Gets the expected errors and their line numbers
+expect_per_line = dict()
errors = []
for i, line in enumerate(src, 1):
m = re.search(r"(?:^\s*!\s*(?:ERROR|WARNING|PORTABILITY|BECAUSE): )(.*)", line)
@@ -63,10 +104,12 @@
errors.append(m.group(1))
continue
if errors:
- for x in errors:
- expect += f"{i}: {x}\n"
+ expect_per_line[f"{i}:"] = [f" {x}" for x in errors]
errors = []
+actual = join_per_line_map(actual_per_line)
+expect = join_per_line_map(expect_per_line)
+
# Compares the expected errors with the compiler errors
for line in unified_diff(actual.split("\n"), expect.split("\n"), n=0):
line = re.sub(r"(^\-)(\d+:)", r"\nactual at \g<2>", line)
More information about the flang-commits
mailing list