Break circular dependency between FIR dialect and utilities
[llvm-project.git] / flang / test / Semantics / test_errors.py
blob5a4d8b56a23570da42b07b76b546d4ac056b801b
1 #!/usr/bin/env python3
3 """Compiles a source file and checks errors against those listed in the file.
5 Parameters:
6 sys.argv[1]: a source file with contains the input and expected output
7 sys.argv[2]: the Flang frontend driver
8 sys.argv[3:]: Optional arguments to the Flang frontend driver"""
10 import sys
11 import re
12 import tempfile
13 import subprocess
14 import common as cm
16 from difflib import unified_diff
18 cm.check_args(sys.argv)
19 srcdir = cm.set_source(sys.argv[1])
20 with open(srcdir, 'r') as f:
21 src = f.readlines()
22 actual = ""
23 expect = ""
24 diffs = ""
25 log = ""
27 flang_fc1 = cm.set_executable(sys.argv[2])
28 flang_fc1_args = sys.argv[3:]
29 flang_fc1_options = "-fsyntax-only"
31 # Compiles, and reads in the output from the compilation process
32 cmd = [flang_fc1, *flang_fc1_args, flang_fc1_options, str(srcdir)]
33 with tempfile.TemporaryDirectory() as tmpdir:
34 try:
35 proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
36 check=True, universal_newlines=True, cwd=tmpdir)
37 except subprocess.CalledProcessError as e:
38 log = e.stderr
39 if e.returncode >= 128:
40 print(f"{log}")
41 sys.exit(1)
43 # Cleans up the output from the compilation process to be easier to process
44 for line in log.split('\n'):
45 m = re.search(r"[^:]*:(\d+:).*(?:error|warning|portability|because):(.*)", line)
46 if m:
47 if re.search(r"warning: .*fold.*host", line):
48 continue # ignore host-dependent folding warnings
49 actual += m.expand(r"\1\2\n")
51 # Gets the expected errors and their line numbers
52 errors = []
53 for i, line in enumerate(src, 1):
54 m = re.search(r"(?:^\s*!\s*(?:ERROR|WARNING|PORTABILITY|BECAUSE): )(.*)", line)
55 if m:
56 errors.append(m.group(1))
57 continue
58 if errors:
59 for x in errors:
60 expect += f"{i}: {x}\n"
61 errors = []
63 # Compares the expected errors with the compiler errors
64 for line in unified_diff(actual.split("\n"), expect.split("\n"), n=0):
65 line = re.sub(r"(^\-)(\d+:)", r"\nactual at \g<2>", line)
66 line = re.sub(r"(^\+)(\d+:)", r"\nexpect at \g<2>", line)
67 diffs += line
69 if diffs != "":
70 print(diffs)
71 print()
72 print("FAIL")
73 sys.exit(1)
74 else:
75 print()
76 print("PASS")