xref: /llvm-project/flang/test/Semantics/test_errors.py (revision f98ee40f4b5d7474fc67e82824bf6abbaedb7b1c)
16c1ac141SIvan Zhechev#!/usr/bin/env python3
26c1ac141SIvan Zhechev
36c1ac141SIvan Zhechev"""Compiles a source file and checks errors against those listed in the file.
46c1ac141SIvan Zhechev
56c1ac141SIvan ZhechevParameters:
66c1ac141SIvan Zhechev    sys.argv[1]: a source file with contains the input and expected output
76c1ac141SIvan Zhechev    sys.argv[2]: the Flang frontend driver
86c1ac141SIvan Zhechev    sys.argv[3:]: Optional arguments to the Flang frontend driver"""
96c1ac141SIvan Zhechev
106c1ac141SIvan Zhechevimport sys
116c1ac141SIvan Zhechevimport re
126c1ac141SIvan Zhechevimport tempfile
136c1ac141SIvan Zhechevimport subprocess
146c1ac141SIvan Zhechevimport common as cm
156c1ac141SIvan Zhechev
166c1ac141SIvan Zhechevfrom difflib import unified_diff
176c1ac141SIvan Zhechev
186c1ac141SIvan Zhechevcm.check_args(sys.argv)
196c1ac141SIvan Zhechevsrcdir = cm.set_source(sys.argv[1])
20*f98ee40fSTobias Hietawith open(srcdir, "r") as f:
216c1ac141SIvan Zhechev    src = f.readlines()
226c1ac141SIvan Zhechevactual = ""
236c1ac141SIvan Zhechevexpect = ""
246c1ac141SIvan Zhechevdiffs = ""
256c1ac141SIvan Zhechevlog = ""
266c1ac141SIvan Zhechev
276c1ac141SIvan Zhechevflang_fc1 = cm.set_executable(sys.argv[2])
286c1ac141SIvan Zhechevflang_fc1_args = sys.argv[3:]
296c1ac141SIvan Zhechevflang_fc1_options = "-fsyntax-only"
306c1ac141SIvan Zhechev
316c1ac141SIvan Zhechev# Compiles, and reads in the output from the compilation process
326c1ac141SIvan Zhechevcmd = [flang_fc1, *flang_fc1_args, flang_fc1_options, str(srcdir)]
336c1ac141SIvan Zhechevwith tempfile.TemporaryDirectory() as tmpdir:
346c1ac141SIvan Zhechev    try:
35*f98ee40fSTobias Hieta        proc = subprocess.run(
36*f98ee40fSTobias Hieta            cmd,
37*f98ee40fSTobias Hieta            stdout=subprocess.PIPE,
38*f98ee40fSTobias Hieta            stderr=subprocess.PIPE,
39*f98ee40fSTobias Hieta            check=True,
40*f98ee40fSTobias Hieta            universal_newlines=True,
41*f98ee40fSTobias Hieta            cwd=tmpdir,
42*f98ee40fSTobias Hieta        )
436c1ac141SIvan Zhechev    except subprocess.CalledProcessError as e:
446c1ac141SIvan Zhechev        log = e.stderr
456c1ac141SIvan Zhechev        if e.returncode >= 128:
466c1ac141SIvan Zhechev            print(f"{log}")
476c1ac141SIvan Zhechev            sys.exit(1)
486c1ac141SIvan Zhechev
496c1ac141SIvan Zhechev# Cleans up the output from the compilation process to be easier to process
50*f98ee40fSTobias Hietafor line in log.split("\n"):
51502e7690SPeter Klausler    m = re.search(r"[^:]*:(\d+:).*(?:error|warning|portability|because):(.*)", line)
526c1ac141SIvan Zhechev    if m:
53502e7690SPeter Klausler        if re.search(r"warning: .*fold.*host", line):
54502e7690SPeter Klausler            continue  # ignore host-dependent folding warnings
556c1ac141SIvan Zhechev        actual += m.expand(r"\1\2\n")
566c1ac141SIvan Zhechev
57502e7690SPeter Klausler# Gets the expected errors and their line numbers
586c1ac141SIvan Zhecheverrors = []
596c1ac141SIvan Zhechevfor i, line in enumerate(src, 1):
60502e7690SPeter Klausler    m = re.search(r"(?:^\s*!\s*(?:ERROR|WARNING|PORTABILITY|BECAUSE): )(.*)", line)
616c1ac141SIvan Zhechev    if m:
626c1ac141SIvan Zhechev        errors.append(m.group(1))
636c1ac141SIvan Zhechev        continue
646c1ac141SIvan Zhechev    if errors:
656c1ac141SIvan Zhechev        for x in errors:
666c1ac141SIvan Zhechev            expect += f"{i}: {x}\n"
676c1ac141SIvan Zhechev        errors = []
686c1ac141SIvan Zhechev
696c1ac141SIvan Zhechev# Compares the expected errors with the compiler errors
706c1ac141SIvan Zhechevfor line in unified_diff(actual.split("\n"), expect.split("\n"), n=0):
716c1ac141SIvan Zhechev    line = re.sub(r"(^\-)(\d+:)", r"\nactual at \g<2>", line)
726c1ac141SIvan Zhechev    line = re.sub(r"(^\+)(\d+:)", r"\nexpect at \g<2>", line)
736c1ac141SIvan Zhechev    diffs += line
746c1ac141SIvan Zhechev
756c1ac141SIvan Zhechevif diffs != "":
766c1ac141SIvan Zhechev    print(diffs)
776c1ac141SIvan Zhechev    print()
786c1ac141SIvan Zhechev    print("FAIL")
796c1ac141SIvan Zhechev    sys.exit(1)
806c1ac141SIvan Zhechevelse:
816c1ac141SIvan Zhechev    print()
826c1ac141SIvan Zhechev    print("PASS")
83