diff --git a/flang/test/Semantics/modfile01.f90 b/flang/test/Semantics/modfile01.f90 --- a/flang/test/Semantics/modfile01.f90 +++ b/flang/test/Semantics/modfile01.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Check correct modfile generation for type with private component. module m integer :: i diff --git a/flang/test/Semantics/modfile02.f90 b/flang/test/Semantics/modfile02.f90 --- a/flang/test/Semantics/modfile02.f90 +++ b/flang/test/Semantics/modfile02.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Check modfile generation for private type in public API. module m diff --git a/flang/test/Semantics/modfile03.f90 b/flang/test/Semantics/modfile03.f90 --- a/flang/test/Semantics/modfile03.f90 +++ b/flang/test/Semantics/modfile03.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Check modfile generation with use-association. module m1 diff --git a/flang/test/Semantics/modfile04.f90 b/flang/test/Semantics/modfile04.f90 --- a/flang/test/Semantics/modfile04.f90 +++ b/flang/test/Semantics/modfile04.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! modfile with subprograms module m1 diff --git a/flang/test/Semantics/modfile05.f90 b/flang/test/Semantics/modfile05.f90 --- a/flang/test/Semantics/modfile05.f90 +++ b/flang/test/Semantics/modfile05.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Use-association with VOLATILE or ASYNCHRONOUS module m1 diff --git a/flang/test/Semantics/modfile06.f90 b/flang/test/Semantics/modfile06.f90 --- a/flang/test/Semantics/modfile06.f90 +++ b/flang/test/Semantics/modfile06.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Check modfile generation for external interface module m interface diff --git a/flang/test/Semantics/modfile07.f90 b/flang/test/Semantics/modfile07.f90 --- a/flang/test/Semantics/modfile07.f90 +++ b/flang/test/Semantics/modfile07.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Check modfile generation for generic interfaces module m1 interface foo diff --git a/flang/test/Semantics/modfile08.f90 b/flang/test/Semantics/modfile08.f90 --- a/flang/test/Semantics/modfile08.f90 +++ b/flang/test/Semantics/modfile08.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Check modfile generation for external declarations module m real, external :: a diff --git a/flang/test/Semantics/modfile09.f90 b/flang/test/Semantics/modfile09.f90 --- a/flang/test/Semantics/modfile09.f90 +++ b/flang/test/Semantics/modfile09.f90 @@ -1,2 +1 @@ -!RUN: %S/test_modfile.sh '%S/Inputs/modfile09-*' %t %flang_fc1 -!REQUIRES: shell +!RUN: %python %S/test_modfile.py '%S/Inputs/modfile09-*' %flang_fc1 diff --git a/flang/test/Semantics/modfile10.f90 b/flang/test/Semantics/modfile10.f90 --- a/flang/test/Semantics/modfile10.f90 +++ b/flang/test/Semantics/modfile10.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Test writing procedure bindings in a derived type. module m diff --git a/flang/test/Semantics/modfile11.f90 b/flang/test/Semantics/modfile11.f90 --- a/flang/test/Semantics/modfile11.f90 +++ b/flang/test/Semantics/modfile11.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 module m type t1(a, b, c) integer, kind :: a diff --git a/flang/test/Semantics/modfile12.f90 b/flang/test/Semantics/modfile12.f90 --- a/flang/test/Semantics/modfile12.f90 +++ b/flang/test/Semantics/modfile12.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 module m integer(8), parameter :: a = 1, b = 2_8 parameter(n=3,l=-3,e=1.0/3.0) diff --git a/flang/test/Semantics/modfile13.f90 b/flang/test/Semantics/modfile13.f90 --- a/flang/test/Semantics/modfile13.f90 +++ b/flang/test/Semantics/modfile13.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 module m character(2) :: z character(len=3) :: y diff --git a/flang/test/Semantics/modfile14.f90 b/flang/test/Semantics/modfile14.f90 --- a/flang/test/Semantics/modfile14.f90 +++ b/flang/test/Semantics/modfile14.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 module m type t1 contains diff --git a/flang/test/Semantics/modfile15.f90 b/flang/test/Semantics/modfile15.f90 --- a/flang/test/Semantics/modfile15.f90 +++ b/flang/test/Semantics/modfile15.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 module m type :: t procedure(a), pointer, pass :: c diff --git a/flang/test/Semantics/modfile16.f90 b/flang/test/Semantics/modfile16.f90 --- a/flang/test/Semantics/modfile16.f90 +++ b/flang/test/Semantics/modfile16.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 module m character(2), parameter :: prefix = 'c_' integer, bind(c, name='c_a') :: a diff --git a/flang/test/Semantics/modfile17.f90 b/flang/test/Semantics/modfile17.f90 --- a/flang/test/Semantics/modfile17.f90 +++ b/flang/test/Semantics/modfile17.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Tests parameterized derived type instantiation with KIND parameters module m diff --git a/flang/test/Semantics/modfile18.f90 b/flang/test/Semantics/modfile18.f90 --- a/flang/test/Semantics/modfile18.f90 +++ b/flang/test/Semantics/modfile18.f90 @@ -1,5 +1,5 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 + ! Tests folding of array constructors module m diff --git a/flang/test/Semantics/modfile19.f90 b/flang/test/Semantics/modfile19.f90 --- a/flang/test/Semantics/modfile19.f90 +++ b/flang/test/Semantics/modfile19.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 module m implicit complex(8)(z) real :: x diff --git a/flang/test/Semantics/modfile20.f90 b/flang/test/Semantics/modfile20.f90 --- a/flang/test/Semantics/modfile20.f90 +++ b/flang/test/Semantics/modfile20.f90 @@ -1,5 +1,5 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 + ! Test modfiles for entities with initialization module m integer, parameter :: k8 = 8 diff --git a/flang/test/Semantics/modfile21.f90 b/flang/test/Semantics/modfile21.f90 --- a/flang/test/Semantics/modfile21.f90 +++ b/flang/test/Semantics/modfile21.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 module m logical b bind(C) :: /cb2/ diff --git a/flang/test/Semantics/modfile22.f90 b/flang/test/Semantics/modfile22.f90 --- a/flang/test/Semantics/modfile22.f90 +++ b/flang/test/Semantics/modfile22.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Test character length conversions in constructors module m diff --git a/flang/test/Semantics/modfile23.f90 b/flang/test/Semantics/modfile23.f90 --- a/flang/test/Semantics/modfile23.f90 +++ b/flang/test/Semantics/modfile23.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Test that subprogram interfaces get all of the symbols that they need. module m1 diff --git a/flang/test/Semantics/modfile24.f90 b/flang/test/Semantics/modfile24.f90 --- a/flang/test/Semantics/modfile24.f90 +++ b/flang/test/Semantics/modfile24.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Test declarations with coarray-spec ! Different ways of declaring the same coarray. diff --git a/flang/test/Semantics/modfile25.f90 b/flang/test/Semantics/modfile25.f90 --- a/flang/test/Semantics/modfile25.f90 +++ b/flang/test/Semantics/modfile25.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Test compile-time analysis of shapes. module m1 diff --git a/flang/test/Semantics/modfile26.f90 b/flang/test/Semantics/modfile26.f90 --- a/flang/test/Semantics/modfile26.f90 +++ b/flang/test/Semantics/modfile26.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Intrinsics SELECTED_INT_KIND, SELECTED_REAL_KIND, PRECISION, RANGE, ! RADIX, DIGITS diff --git a/flang/test/Semantics/modfile27.f90 b/flang/test/Semantics/modfile27.f90 --- a/flang/test/Semantics/modfile27.f90 +++ b/flang/test/Semantics/modfile27.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Test folding of combined array references and structure component ! references. diff --git a/flang/test/Semantics/modfile28.f90 b/flang/test/Semantics/modfile28.f90 --- a/flang/test/Semantics/modfile28.f90 +++ b/flang/test/Semantics/modfile28.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Test UTF-8 support in character literals ! Note: Module files are encoded in UTF-8. diff --git a/flang/test/Semantics/modfile29.f90 b/flang/test/Semantics/modfile29.f90 --- a/flang/test/Semantics/modfile29.f90 +++ b/flang/test/Semantics/modfile29.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Check that implicitly typed entities get a type in the module file. module m diff --git a/flang/test/Semantics/modfile30.f90 b/flang/test/Semantics/modfile30.f90 --- a/flang/test/Semantics/modfile30.f90 +++ b/flang/test/Semantics/modfile30.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Verify miscellaneous bugs ! The function result must be declared after the dummy arguments diff --git a/flang/test/Semantics/modfile31.f90 b/flang/test/Semantics/modfile31.f90 --- a/flang/test/Semantics/modfile31.f90 +++ b/flang/test/Semantics/modfile31.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Test 7.6 enum values module m1 diff --git a/flang/test/Semantics/modfile32.f90 b/flang/test/Semantics/modfile32.f90 --- a/flang/test/Semantics/modfile32.f90 +++ b/flang/test/Semantics/modfile32.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Resolution of generic names in expressions. ! Test by using generic function in a specification expression that needs ! to be written to a .mod file. diff --git a/flang/test/Semantics/modfile33.f90 b/flang/test/Semantics/modfile33.f90 --- a/flang/test/Semantics/modfile33.f90 +++ b/flang/test/Semantics/modfile33.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -flogical-abbreviations -fxor-operator -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 -flogical-abbreviations -fxor-operator ! Resolution of user-defined operators in expressions. ! Test by using generic function in a specification expression that needs diff --git a/flang/test/Semantics/modfile34.f90 b/flang/test/Semantics/modfile34.f90 --- a/flang/test/Semantics/modfile34.f90 +++ b/flang/test/Semantics/modfile34.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Test resolution of type-bound generics. module m1 diff --git a/flang/test/Semantics/modfile35.f90 b/flang/test/Semantics/modfile35.f90 --- a/flang/test/Semantics/modfile35.f90 +++ b/flang/test/Semantics/modfile35.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 module m1 type :: t1 contains diff --git a/flang/test/Semantics/modfile36.f90 b/flang/test/Semantics/modfile36.f90 --- a/flang/test/Semantics/modfile36.f90 +++ b/flang/test/Semantics/modfile36.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Check modfile that contains import of use-assocation of another use-association. diff --git a/flang/test/Semantics/modfile37.f90 b/flang/test/Semantics/modfile37.f90 --- a/flang/test/Semantics/modfile37.f90 +++ b/flang/test/Semantics/modfile37.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Ensure that a dummy procedure's interface's imports ! appear in the module file. diff --git a/flang/test/Semantics/modfile38.f90 b/flang/test/Semantics/modfile38.f90 --- a/flang/test/Semantics/modfile38.f90 +++ b/flang/test/Semantics/modfile38.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Ensure that an interface with the same name as a derived type ! does not cause that shadowed name to be emitted later than its diff --git a/flang/test/Semantics/modfile39.f90 b/flang/test/Semantics/modfile39.f90 --- a/flang/test/Semantics/modfile39.f90 +++ b/flang/test/Semantics/modfile39.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Resolution of specification expression references to generic interfaces ! that resolve to private specific functions. diff --git a/flang/test/Semantics/modfile40.f90 b/flang/test/Semantics/modfile40.f90 --- a/flang/test/Semantics/modfile40.f90 +++ b/flang/test/Semantics/modfile40.f90 @@ -1,5 +1,4 @@ -! RUN: %S/test_modfile.sh %s %t %flang_fc1 -! REQUIRES: shell +! RUN: %python %S/test_modfile.py %s %flang_fc1 ! Ensure that intrinsics in module files retain their 'private' attribute, ! if they are private. diff --git a/flang/test/Semantics/test_modfile.py b/flang/test/Semantics/test_modfile.py new file mode 100755 --- /dev/null +++ b/flang/test/Semantics/test_modfile.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 + +"""Compiles a source file and compares generated .mod files against expected. + +Parameters: + sys.argv[1]: a source file with contains the input and expected output + sys.argv[2]: the Flang frontend driver + sys.argv[3:]: Optional arguments to the Flang frontend driver""" + +import sys +import re +import os +import tempfile +import subprocess +import glob +import common as cm + +from pathlib import Path +from difflib import unified_diff + +cm.check_args_long(sys.argv) +srcdir = Path(sys.argv[1]) +sources = list(glob.iglob(str(srcdir))) +sources = sorted(sources) +diffs = "" + +flang_fc1 = cm.set_executable(sys.argv[2]) +flang_fc_args = sys.argv[3:] +flang_fc1_options = "-fsyntax-only" + +with tempfile.TemporaryDirectory() as tmpdir: + for src in sources: + src = Path(src).resolve() + actual = "" + expect = "" + expected_files = set() + actual_files = set() + + if not src.is_file(): + cm.die(src) + + prev_files = set(os.listdir(tmpdir)) + cmd = [flang_fc1, *flang_fc_args, flang_fc1_options, str(src)] + proc = subprocess.check_output(cmd, stderr=subprocess.PIPE, + universal_newlines=True, cwd=tmpdir) + actual_files = set(os.listdir(tmpdir)).difference(prev_files) + + # The first 3 bytes of the files are an UTF-8 BOM + with open(src, 'r', encoding="utf-8", errors="strict") as f: + for line in f: + m = re.search(r"^!Expect: (.*)", line) + if m: + expected_files.add(m.group(1)) + + extra_files = actual_files.difference(expected_files) + if extra_files: + print(f"Unexpected .mod files produced: {extra_files}") + sys.exit(1) + + for mod in expected_files: + mod = Path(tmpdir).joinpath(mod) + if not mod.is_file(): + print(f"Compilation did not produce expected mod file: {mod}") + sys.exit(1) + with open(mod, 'r', encoding="utf-8", errors="strict") as f: + for line in f: + if "!mod$" in line: + continue + actual += line + + with open(src, 'r', encoding="utf-8", errors="strict") as f: + for line in f: + if f"!Expect: {mod.name}" in line: + for line in f: + if re.match(r"^$", line): + break + m = re.sub(r"^!", "", line.lstrip()) + expect += m + + diffs = "\n".join(unified_diff(actual.replace(" ", "").split("\n"), + expect.replace(" ", "").split("\n"), + fromfile=mod.name, tofile="Expect", n=999999)) + + if diffs != "": + print(diffs) + print() + print("FAIL") + sys.exit(1) + +print() +print("PASS") + diff --git a/flang/test/Semantics/test_modfile.sh b/flang/test/Semantics/test_modfile.sh deleted file mode 100755 --- a/flang/test/Semantics/test_modfile.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env bash -# Compile a source file and compare generated .mod files against expected. - -set -e -FLANG_FC1_OPTIONS="-fsyntax-only" -srcdir=$(dirname $0) -source $srcdir/common.sh - -actual=$temp/actual.mod -expect=$temp/expect.mod -actual_files=$temp/actual_files -prev_files=$temp/prev_files -diffs=$temp/diffs - -set $src - -touch $actual -for src in "$@"; do - [[ ! -f $src ]] && echo "File not found: $src" && exit 1 - path=$(git ls-files --full-name $src 2>/dev/null || echo $src) - ( - cd $temp - ls -1 *.mod > prev_files - $FLANG_FC1 $FLANG_FC1_OPTIONS $src - ls -1 *.mod | comm -13 prev_files - - ) > $actual_files - expected_files=$(sed -n 's/^!Expect: \(.*\)/\1/p' $src | sort) - extra_files=$(echo "$expected_files" | comm -23 $actual_files -) - if [[ ! -z "$extra_files" ]]; then - echo "Unexpected .mod files produced:" $extra_files - die FAIL $path - fi - for mod in $expected_files; do - if [[ ! -f $temp/$mod ]]; then - echo "Compilation did not produce expected mod file: $mod" - die FAIL $path - fi - # The first three bytes of the file are a UTF-8 BOM - sed '/^[^!]*!mod\$/d' $temp/$mod > $actual - sed '1,/^!Expect: '"$mod"'/d' $src | sed -e '/^$/,$d' -e 's/^!//' > $expect - if ! diff -w -U999999 $expect $actual > $diffs; then - echo "Module file $mod differs from expected:" - sed '1,2d' $diffs - die FAIL $path - fi - done - rm -f $actual $expect -done -echo PASS