https://github.com/boomanaiden154 updated https://github.com/llvm/llvm-project/pull/158447
>From 5bd8d4f925f3b5f82d85ef693861b6b1067d9f38 Mon Sep 17 00:00:00 2001 From: Aiden Grossman <aidengross...@google.com> Date: Sat, 13 Sep 2025 22:54:58 +0000 Subject: [PATCH 1/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.6 --- clang/test/Misc/dev-fd-fs.c | 1 - llvm/utils/lit/lit/builtin_commands/cat.py | 3 +++ llvm/utils/lit/tests/Inputs/shtest-cat/cat.txt | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/clang/test/Misc/dev-fd-fs.c b/clang/test/Misc/dev-fd-fs.c index ea94d950b0716..b989ab8a439cf 100644 --- a/clang/test/Misc/dev-fd-fs.c +++ b/clang/test/Misc/dev-fd-fs.c @@ -1,6 +1,5 @@ // Check that we can operate on files from /dev/fd. // REQUIRES: dev-fd-fs -// REQUIRES: shell // Check reading from named pipes. We cat the input here instead of redirecting // it to ensure that /dev/fd/0 is a named pipe, not just a redirected file. diff --git a/llvm/utils/lit/lit/builtin_commands/cat.py b/llvm/utils/lit/lit/builtin_commands/cat.py index ddab555662045..2797e0cbb4154 100644 --- a/llvm/utils/lit/lit/builtin_commands/cat.py +++ b/llvm/utils/lit/lit/builtin_commands/cat.py @@ -49,6 +49,9 @@ def main(argv): import os, msvcrt msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) + if len(filenames) == 0: + sys.stdout.write(sys.stdin.read()) + sys.exit(0) for filename in filenames: try: contents = None diff --git a/llvm/utils/lit/tests/Inputs/shtest-cat/cat.txt b/llvm/utils/lit/tests/Inputs/shtest-cat/cat.txt index 4014b0fca1f24..c5b5d247c2f95 100644 --- a/llvm/utils/lit/tests/Inputs/shtest-cat/cat.txt +++ b/llvm/utils/lit/tests/Inputs/shtest-cat/cat.txt @@ -70,3 +70,7 @@ # NP-CAT-OUTPUT-NEXT:M-HM-IM-JM-KM-LM-MM-NM-OM-PM-QM-RM-SM-TM-UM-VM-WM-XM-YM-ZM-[ # NP-CAT-OUTPUT-NEXT:M-\M-]M-^M-_M-`M-aM-bM-cM-dM-eM-fM-gM-hM-iM-jM-kM-lM-mM-nM-o # NP-CAT-OUTPUT-NEXT:M-pM-qM-rM-sM-tM-uM-vM-wM-xM-yM-zM-{M-|M-}M-~M-^? + +## Test that cat will pipe stdin to stdout if no other files are specified. +# RUN: echo test | cat | FileCheck --check-prefix=CAT-STDIN %s +# CAT-STDIN: test >From 572975066e843b76e51020bcf6abc7822d3dfb75 Mon Sep 17 00:00:00 2001 From: Aiden Grossman <aidengross...@google.com> Date: Sat, 13 Sep 2025 23:14:52 +0000 Subject: [PATCH 2/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20introduced=20through=20rebase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.6 [skip ci] --- clang/test/ClangScanDeps/pr61006.cppm | 3 ++- clang/test/ClangScanDeps/resource_directory.c | 9 ++++----- clang/test/Driver/env.c | 5 +++-- clang/test/Driver/program-path-priority.c | 16 +++++++-------- clang/test/Modules/relative-resource-dir.m | 6 +++--- llvm/docs/CommandGuide/lit.rst | 1 + llvm/test/tools/llvm-cgdata/empty.test | 1 + llvm/utils/lit/lit/TestRunner.py | 20 +++++++++++++++++++ .../Inputs/shtest-readfile/absolute-paths.txt | 6 ++++++ .../lit/tests/Inputs/shtest-readfile/lit.cfg | 8 ++++++++ .../Inputs/shtest-readfile/relative-paths.txt | 7 +++++++ .../Inputs/shtest-readfile/two-same-line.txt | 8 ++++++++ llvm/utils/lit/tests/shtest-readfile.py | 17 ++++++++++++++++ 13 files changed, 88 insertions(+), 19 deletions(-) create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/absolute-paths.txt create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/relative-paths.txt create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/two-same-line.txt create mode 100644 llvm/utils/lit/tests/shtest-readfile.py diff --git a/clang/test/ClangScanDeps/pr61006.cppm b/clang/test/ClangScanDeps/pr61006.cppm index f75edd38c81ba..f10bc1e673987 100644 --- a/clang/test/ClangScanDeps/pr61006.cppm +++ b/clang/test/ClangScanDeps/pr61006.cppm @@ -6,7 +6,8 @@ // RUN: mkdir -p %t // RUN: split-file %s %t // -// RUN: EXPECTED_RESOURCE_DIR=`%clang -print-resource-dir` && \ +// RUN: %clang -print-resource-dir | tr -d '\n' > %t/resource-dir +// RUN: env EXPECTED_RESOURCE_DIR=%{readfile:%t/resource-dir} && \ // RUN: ln -s %clang++ %t/clang++ && \ // RUN: sed "s|EXPECTED_RESOURCE_DIR|$EXPECTED_RESOURCE_DIR|g; s|DIR|%/t|g" %t/P1689.json.in > %t/P1689.json && \ // RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/a.cpp -DPREFIX=%/t && \ diff --git a/clang/test/ClangScanDeps/resource_directory.c b/clang/test/ClangScanDeps/resource_directory.c index 55d5d90bbcdea..6183e8aefacfa 100644 --- a/clang/test/ClangScanDeps/resource_directory.c +++ b/clang/test/ClangScanDeps/resource_directory.c @@ -12,14 +12,14 @@ // then verify `%clang-scan-deps` arrives at the same path by calling the // `Driver::GetResourcesPath` function. // -// RUN: EXPECTED_RESOURCE_DIR=`%clang -print-resource-dir` +// RUN: %clang -print-resource-dir | tr -d '\n' > %t/resource-dir // RUN: sed -e "s|CLANG|%clang|g" -e "s|DIR|%/t|g" \ // RUN: %S/Inputs/resource_directory/cdb.json.template > %t/cdb_path.json // // RUN: clang-scan-deps -compilation-database %t/cdb_path.json --format experimental-full \ // RUN: --resource-dir-recipe modify-compiler-path > %t/result_path.json // RUN: cat %t/result_path.json | sed 's:\\\\\?:/:g' \ -// RUN: | FileCheck %s --check-prefix=CHECK-PATH -DEXPECTED_RESOURCE_DIR="$EXPECTED_RESOURCE_DIR" +// RUN: | FileCheck %s --check-prefix=CHECK-PATH -DEXPECTED_RESOURCE_DIR="%{readfile:%t/resource-dir}" // CHECK-PATH: "-resource-dir" // CHECK-PATH-NEXT: "[[EXPECTED_RESOURCE_DIR]]" @@ -31,9 +31,8 @@ // Here we hard-code the expected path into `%t/compiler` and then verify // `%clang-scan-deps` arrives at the path by actually running the executable. // -// RUN: EXPECTED_RESOURCE_DIR="/custom/compiler/resources" // RUN: echo "#!/bin/sh" > %t/compiler -// RUN: echo "echo '$EXPECTED_RESOURCE_DIR'" >> %t/compiler +// RUN: echo "echo '/custom/compiler/resources'" >> %t/compiler // RUN: chmod +x %t/compiler // RUN: sed -e "s|CLANG|%/t/compiler|g" -e "s|DIR|%/t|g" \ // RUN: %S/Inputs/resource_directory/cdb.json.template > %t/cdb_invocation.json @@ -41,6 +40,6 @@ // RUN: clang-scan-deps -compilation-database %t/cdb_invocation.json --format experimental-full \ // RUN: --resource-dir-recipe invoke-compiler > %t/result_invocation.json // RUN: cat %t/result_invocation.json | sed 's:\\\\\?:/:g' \ -// RUN: | FileCheck %s --check-prefix=CHECK-PATH -DEXPECTED_RESOURCE_DIR="$EXPECTED_RESOURCE_DIR" +// RUN: | FileCheck %s --check-prefix=CHECK-PATH -DEXPECTED_RESOURCE_DIR="/custom/compiler/resources" // CHECK-INVOCATION: "-resource-dir" // CHECK-INVOCATION-NEXT: "[[EXPECTED_RESOURCE_DIR]]" diff --git a/clang/test/Driver/env.c b/clang/test/Driver/env.c index b3345ae09ffef..68ded45385702 100644 --- a/clang/test/Driver/env.c +++ b/clang/test/Driver/env.c @@ -1,13 +1,14 @@ // Some assertions in this test use Linux style (/) file paths. // UNSUPPORTED: system-windows +// RUN: bash -c env | grep LD_LIBRARY_PATH | tr -d '\n' > /tmp/ld_library_path // The PATH variable is heavily used when trying to find a linker. -// RUN: env -i LC_ALL=C LD_LIBRARY_PATH="$LD_LIBRARY_PATH" CLANG_NO_DEFAULT_CONFIG=1 \ +// RUN: env -i LC_ALL=C LD_LIBRARY_PATH="%{readfile:/tmp/ld_library_path}" CLANG_NO_DEFAULT_CONFIG=1 \ // RUN: %clang %s -### -o %t.o --target=i386-unknown-linux \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: --rtlib=platform --unwindlib=platform -no-pie \ // RUN: 2>&1 | FileCheck --check-prefix=CHECK-LD-32 %s // -// RUN: env -i LC_ALL=C PATH="" LD_LIBRARY_PATH="$LD_LIBRARY_PATH" CLANG_NO_DEFAULT_CONFIG=1 \ +// RUN: env -i LC_ALL=C PATH="" LD_LIBRARY_PATH="%{readfile:/tmp/ld_library_path}" CLANG_NO_DEFAULT_CONFIG=1 \ // RUN: %clang %s -### -o %t.o --target=i386-unknown-linux \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: --rtlib=platform --unwindlib=platform -no-pie \ diff --git a/clang/test/Driver/program-path-priority.c b/clang/test/Driver/program-path-priority.c index b88c0f29f7f33..bb434482f90d4 100644 --- a/clang/test/Driver/program-path-priority.c +++ b/clang/test/Driver/program-path-priority.c @@ -87,8 +87,8 @@ /// <default-triple>-gcc has lowest priority so <triple>-gcc /// on PATH beats default triple in program path -// RUN: DEFAULT_TRIPLE=`%t/clang --version | grep "Target:" | cut -d ' ' -f2` -// RUN: touch %t/$DEFAULT_TRIPLE-gcc && chmod +x %t/$DEFAULT_TRIPLE-gcc +// RUN: %t/clang --version | grep "Target:" | cut -d ' ' -f2 > %t.default_triple +// RUN: touch %t/%{readfile:%t.default_triple}-gcc && chmod +x %t/%{readfile:%t.default_triple}-gcc // RUN: touch %t/%target_triple-gcc && chmod +x %t/%target_triple-gcc // RUN: env "PATH=%t/env/" %t/clang -### -target notreal-none-elf %s 2>&1 | \ // RUN: FileCheck --check-prefix=DEFAULT_TRIPLE_GCC %s @@ -101,7 +101,7 @@ // DEFAULT_TRIPLE_NO_NOTREAL: env/gcc" // DEFAULT_TRIPLE_NO_NOTREAL-NOT: -gcc" -/// Pick "gcc" as a fallback. Don't pick $DEFAULT_TRIPLE-gcc. +/// Pick "gcc" as a fallback. Don't pick DEFAULT_TRIPLE-gcc. // RUN: rm %t/env/gcc // RUN: env "PATH=%t/env/" %t/clang -### -target notreal-none-elf %s 2>&1 | \ // RUN: FileCheck --check-prefix=DEFAULT_TRIPLE_NO_OTHERS %s @@ -110,9 +110,9 @@ /// -B paths are searched separately so default triple will win /// if put in one of those even if other paths have higher priority names // RUN: mkdir -p %t/prefix -/// One of these will fail when $DEFAULT_TRIPLE == %target_triple -// RUN: test -f %t/$DEFAULT_TRIPLE-gcc && \ -// RUN: mv %t/$DEFAULT_TRIPLE-gcc %t/prefix || true +/// One of these will fail when %{readfile:%t.default_triple} == %target_triple +// RUN: test -f %t/%{readfile:%t.default_triple}-gcc && \ +// RUN: mv %t/%{readfile:%t.default_triple}-gcc %t/prefix || true // RUN: test -f %t/%target_triple-gcc && \ // RUN: mv %t/%target_triple-gcc %t/prefix || true // RUN: touch %t/notreal-none-elf-gcc && chmod +x %t/notreal-none-elf-gcc @@ -123,8 +123,8 @@ // DEFAULT_TRIPLE_IN_PREFIX-NOT: notreal-none-elf-gcc" /// Only if there is nothing in the prefix will we search other paths -/// -f in case $DEFAULT_TRIPLE == %target_triple -// RUN: rm -f %t/prefix/$DEFAULT_TRIPLE-gcc %t/prefix/%target_triple-gcc %t/prefix/gcc +/// -f in case %{readfile:%t.default_triple} == %target_triple +// RUN: rm -f %t/prefix/%{readfile:%t.default_triple}-gcc %t/prefix/%target_triple-gcc %t/prefix/gcc // RUN: env "PATH=" %t/clang -### -canonical-prefixes --target=notreal-none-elf %s -B %t/prefix 2>&1 | \ // RUN: FileCheck --check-prefix=EMPTY_PREFIX_DIR1 %s // EMPTY_PREFIX_DIR1: gcc" diff --git a/clang/test/Modules/relative-resource-dir.m b/clang/test/Modules/relative-resource-dir.m index 4f88150a2ba4c..96f2d8efc7860 100644 --- a/clang/test/Modules/relative-resource-dir.m +++ b/clang/test/Modules/relative-resource-dir.m @@ -1,9 +1,9 @@ // UNSUPPORTED: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}} -// REQUIRES: shell -// RUN: EXPECTED_RESOURCE_DIR=`%clang -print-resource-dir` && \ +// RUN: %clang -print-resource-dir | tr -d '\n' > %t.resource_dir +// RUN: env EXPECTED_RESOURCE_DIR="%{readfile:%t.resource_dir}" && \ // RUN: mkdir -p %t && rm -rf %t/resource-dir && \ -// RUN: cp -R $EXPECTED_RESOURCE_DIR %t/resource-dir +// RUN: cp -R %{readfile:%t.resource_dir} %t/resource-dir // RUN: cd %t && %clang -cc1 -x objective-c -fmodules -fmodule-format=obj \ // RUN: -fimplicit-module-maps -fmodules-cache-path=%t.mcp \ // RUN: -fbuiltin-headers-in-system-modules \ diff --git a/llvm/docs/CommandGuide/lit.rst b/llvm/docs/CommandGuide/lit.rst index 15c249d8e6d31..359e0c3e81d0e 100644 --- a/llvm/docs/CommandGuide/lit.rst +++ b/llvm/docs/CommandGuide/lit.rst @@ -664,6 +664,7 @@ TestRunner.py: Otherwise, %t but with a single leading ``/`` removed. %:T On Windows, %/T but a ``:`` is removed if its the second character. Otherwise, %T but with a single leading ``/`` removed. + %{readfile:<filename>} Reads the file specified. ======================= ============== Other substitutions are provided that are variations on this base set and diff --git a/llvm/test/tools/llvm-cgdata/empty.test b/llvm/test/tools/llvm-cgdata/empty.test index 52d0dfb87623f..7e42db5ed8512 100644 --- a/llvm/test/tools/llvm-cgdata/empty.test +++ b/llvm/test/tools/llvm-cgdata/empty.test @@ -35,3 +35,4 @@ RUN: printf '\000\000\000\000' >> %t_header.cgdata RUN: printf '\040\000\000\000\000\000\000\000' >> %t_header.cgdata RUN: printf '\040\000\000\000\000\000\000\000' >> %t_header.cgdata RUN: diff %t_header.cgdata %t_emptyheader.cgdata +RUN: echo %{readfile:/tmp/test} > /tmp/test diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 90c2c6479b004..5daa8887e4c80 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -720,6 +720,23 @@ def processRedirects(cmd, stdin_source, cmd_shenv, opened_files): return std_fds +def _expandLateSubstitutions(arguments, cwd): + for i, arg in enumerate(arguments): + if not isinstance(arg, str): + continue + + def _replaceReadFile(match): + filePath = match.group(1) + if not os.path.isabs(filePath): + filePath = os.path.join(cwd, filePath) + with open(filePath) as fileHandle: + return fileHandle.read() + + arguments[i] = re.sub(r"%{readfile:([^}]*)}", _replaceReadFile, arg) + + return arguments + + def _executeShCmd(cmd, shenv, results, timeoutHelper): if timeoutHelper.timeoutReached(): # Prevent further recursion if the timeout has been hit @@ -834,6 +851,9 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper): # Ensure args[0] is hashable. args[0] = expand_glob(args[0], cmd_shenv.cwd)[0] + # Expand all late substitutions + args = _expandLateSubstitutions(args, cmd_shenv.cwd) + inproc_builtin = inproc_builtins.get(args[0], None) if inproc_builtin and (args[0] != "echo" or len(cmd.commands) == 1): # env calling an in-process builtin is useless, so we take the safe diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/absolute-paths.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/absolute-paths.txt new file mode 100644 index 0000000000000..4246064cf7bfc --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/absolute-paths.txt @@ -0,0 +1,6 @@ +## Tests that readfile works with absolute paths +# RUN: echo -n "hello" > %t +# RUN: echo %{readfile:%t} + +## Fail the test so we can assert on the output. +# RUN: not echo return diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg b/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg new file mode 100644 index 0000000000000..25651f2cd4832 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg @@ -0,0 +1,8 @@ +import lit.formats + +config.name = "shtest-readfile" +config.suffixes = [".txt"] +config.test_format = lit.formats.ShTest(execute_external=False) +config.test_source_root = None +config.test_exec_root = None +config.substitutions.append(("%{python}", '"%s"' % (sys.executable))) diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/relative-paths.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/relative-paths.txt new file mode 100644 index 0000000000000..3d203d411379d --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/relative-paths.txt @@ -0,0 +1,7 @@ +## Tests that readfile works with relative paths +# RUN: mkdir -p rel_path_test_folder +# RUN: echo -n "hello" > rel_path_test_folder/test_file +# RUN: echo %{readfile:rel_path_test_folder/test_file} + +## Fail the test so we can assert on the output. +# RUN: not echo return diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/two-same-line.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/two-same-line.txt new file mode 100644 index 0000000000000..6855d27d66d35 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/two-same-line.txt @@ -0,0 +1,8 @@ +## Tests that readfile works with two substitutions on the same line to ensure the +## regular expressions are setup correctly. +# RUN: echo -n "hello" > %t.1 +# RUN: echo -n "bye" > %t.2 +# RUN: echo %{readfile:%t.1} %{readfile:%t.2} + +## Fail the test so we can assert on the output. +# RUN: not echo return diff --git a/llvm/utils/lit/tests/shtest-readfile.py b/llvm/utils/lit/tests/shtest-readfile.py new file mode 100644 index 0000000000000..8ba8e53b32966 --- /dev/null +++ b/llvm/utils/lit/tests/shtest-readfile.py @@ -0,0 +1,17 @@ +## Tests the readfile substitution + +# RUN: not %{lit} -a -v %{inputs}/shtest-readfile | FileCheck -match-full-lines %s + +# CHECK: -- Testing: 3 tests{{.*}} + +# CHECK-LABEL: FAIL: shtest-readfile :: absolute-paths.txt ({{[^)]*}}) +# CHECK: echo hello +# CHECK: # executed command: echo '%{readfile:{{.*}}}' + +# CHECK-LABEL: FAIL: shtest-readfile :: relative-paths.txt ({{[^)]*}}) +# CHECK: echo hello +# CHECK: # executed command: echo '%{readfile:rel_path_test_folder/test_file}' + +# CHECK-LABEL: FAIL: shtest-readfile :: two-same-line.txt ({{[^)]*}}) +# CHECK: echo hello bye +# CHECK: # executed command: echo '%{readfile:{{.*}}.1}' '%{readfile:{{.*}}.2}' >From e238732d75577598668a26f5b9ab63b75da6e04a Mon Sep 17 00:00:00 2001 From: Aiden Grossman <aidengross...@google.com> Date: Sat, 13 Sep 2025 23:15:38 +0000 Subject: [PATCH 3/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20introduced=20through=20rebase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.6 [skip ci] --- clang/test/ClangScanDeps/pr61006.cppm | 3 ++- clang/test/ClangScanDeps/resource_directory.c | 9 ++++----- clang/test/Driver/env.c | 5 +++-- clang/test/Driver/program-path-priority.c | 16 +++++++-------- clang/test/Modules/relative-resource-dir.m | 6 +++--- llvm/docs/CommandGuide/lit.rst | 1 + llvm/test/tools/llvm-cgdata/empty.test | 1 + llvm/utils/lit/lit/TestRunner.py | 20 +++++++++++++++++++ .../Inputs/shtest-readfile/absolute-paths.txt | 6 ++++++ .../lit/tests/Inputs/shtest-readfile/lit.cfg | 8 ++++++++ .../Inputs/shtest-readfile/relative-paths.txt | 7 +++++++ .../Inputs/shtest-readfile/two-same-line.txt | 8 ++++++++ llvm/utils/lit/tests/shtest-readfile.py | 17 ++++++++++++++++ 13 files changed, 88 insertions(+), 19 deletions(-) create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/absolute-paths.txt create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/relative-paths.txt create mode 100644 llvm/utils/lit/tests/Inputs/shtest-readfile/two-same-line.txt create mode 100644 llvm/utils/lit/tests/shtest-readfile.py diff --git a/clang/test/ClangScanDeps/pr61006.cppm b/clang/test/ClangScanDeps/pr61006.cppm index f75edd38c81ba..f10bc1e673987 100644 --- a/clang/test/ClangScanDeps/pr61006.cppm +++ b/clang/test/ClangScanDeps/pr61006.cppm @@ -6,7 +6,8 @@ // RUN: mkdir -p %t // RUN: split-file %s %t // -// RUN: EXPECTED_RESOURCE_DIR=`%clang -print-resource-dir` && \ +// RUN: %clang -print-resource-dir | tr -d '\n' > %t/resource-dir +// RUN: env EXPECTED_RESOURCE_DIR=%{readfile:%t/resource-dir} && \ // RUN: ln -s %clang++ %t/clang++ && \ // RUN: sed "s|EXPECTED_RESOURCE_DIR|$EXPECTED_RESOURCE_DIR|g; s|DIR|%/t|g" %t/P1689.json.in > %t/P1689.json && \ // RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/a.cpp -DPREFIX=%/t && \ diff --git a/clang/test/ClangScanDeps/resource_directory.c b/clang/test/ClangScanDeps/resource_directory.c index 55d5d90bbcdea..6183e8aefacfa 100644 --- a/clang/test/ClangScanDeps/resource_directory.c +++ b/clang/test/ClangScanDeps/resource_directory.c @@ -12,14 +12,14 @@ // then verify `%clang-scan-deps` arrives at the same path by calling the // `Driver::GetResourcesPath` function. // -// RUN: EXPECTED_RESOURCE_DIR=`%clang -print-resource-dir` +// RUN: %clang -print-resource-dir | tr -d '\n' > %t/resource-dir // RUN: sed -e "s|CLANG|%clang|g" -e "s|DIR|%/t|g" \ // RUN: %S/Inputs/resource_directory/cdb.json.template > %t/cdb_path.json // // RUN: clang-scan-deps -compilation-database %t/cdb_path.json --format experimental-full \ // RUN: --resource-dir-recipe modify-compiler-path > %t/result_path.json // RUN: cat %t/result_path.json | sed 's:\\\\\?:/:g' \ -// RUN: | FileCheck %s --check-prefix=CHECK-PATH -DEXPECTED_RESOURCE_DIR="$EXPECTED_RESOURCE_DIR" +// RUN: | FileCheck %s --check-prefix=CHECK-PATH -DEXPECTED_RESOURCE_DIR="%{readfile:%t/resource-dir}" // CHECK-PATH: "-resource-dir" // CHECK-PATH-NEXT: "[[EXPECTED_RESOURCE_DIR]]" @@ -31,9 +31,8 @@ // Here we hard-code the expected path into `%t/compiler` and then verify // `%clang-scan-deps` arrives at the path by actually running the executable. // -// RUN: EXPECTED_RESOURCE_DIR="/custom/compiler/resources" // RUN: echo "#!/bin/sh" > %t/compiler -// RUN: echo "echo '$EXPECTED_RESOURCE_DIR'" >> %t/compiler +// RUN: echo "echo '/custom/compiler/resources'" >> %t/compiler // RUN: chmod +x %t/compiler // RUN: sed -e "s|CLANG|%/t/compiler|g" -e "s|DIR|%/t|g" \ // RUN: %S/Inputs/resource_directory/cdb.json.template > %t/cdb_invocation.json @@ -41,6 +40,6 @@ // RUN: clang-scan-deps -compilation-database %t/cdb_invocation.json --format experimental-full \ // RUN: --resource-dir-recipe invoke-compiler > %t/result_invocation.json // RUN: cat %t/result_invocation.json | sed 's:\\\\\?:/:g' \ -// RUN: | FileCheck %s --check-prefix=CHECK-PATH -DEXPECTED_RESOURCE_DIR="$EXPECTED_RESOURCE_DIR" +// RUN: | FileCheck %s --check-prefix=CHECK-PATH -DEXPECTED_RESOURCE_DIR="/custom/compiler/resources" // CHECK-INVOCATION: "-resource-dir" // CHECK-INVOCATION-NEXT: "[[EXPECTED_RESOURCE_DIR]]" diff --git a/clang/test/Driver/env.c b/clang/test/Driver/env.c index b3345ae09ffef..68ded45385702 100644 --- a/clang/test/Driver/env.c +++ b/clang/test/Driver/env.c @@ -1,13 +1,14 @@ // Some assertions in this test use Linux style (/) file paths. // UNSUPPORTED: system-windows +// RUN: bash -c env | grep LD_LIBRARY_PATH | tr -d '\n' > /tmp/ld_library_path // The PATH variable is heavily used when trying to find a linker. -// RUN: env -i LC_ALL=C LD_LIBRARY_PATH="$LD_LIBRARY_PATH" CLANG_NO_DEFAULT_CONFIG=1 \ +// RUN: env -i LC_ALL=C LD_LIBRARY_PATH="%{readfile:/tmp/ld_library_path}" CLANG_NO_DEFAULT_CONFIG=1 \ // RUN: %clang %s -### -o %t.o --target=i386-unknown-linux \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: --rtlib=platform --unwindlib=platform -no-pie \ // RUN: 2>&1 | FileCheck --check-prefix=CHECK-LD-32 %s // -// RUN: env -i LC_ALL=C PATH="" LD_LIBRARY_PATH="$LD_LIBRARY_PATH" CLANG_NO_DEFAULT_CONFIG=1 \ +// RUN: env -i LC_ALL=C PATH="" LD_LIBRARY_PATH="%{readfile:/tmp/ld_library_path}" CLANG_NO_DEFAULT_CONFIG=1 \ // RUN: %clang %s -### -o %t.o --target=i386-unknown-linux \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: --rtlib=platform --unwindlib=platform -no-pie \ diff --git a/clang/test/Driver/program-path-priority.c b/clang/test/Driver/program-path-priority.c index b88c0f29f7f33..bb434482f90d4 100644 --- a/clang/test/Driver/program-path-priority.c +++ b/clang/test/Driver/program-path-priority.c @@ -87,8 +87,8 @@ /// <default-triple>-gcc has lowest priority so <triple>-gcc /// on PATH beats default triple in program path -// RUN: DEFAULT_TRIPLE=`%t/clang --version | grep "Target:" | cut -d ' ' -f2` -// RUN: touch %t/$DEFAULT_TRIPLE-gcc && chmod +x %t/$DEFAULT_TRIPLE-gcc +// RUN: %t/clang --version | grep "Target:" | cut -d ' ' -f2 > %t.default_triple +// RUN: touch %t/%{readfile:%t.default_triple}-gcc && chmod +x %t/%{readfile:%t.default_triple}-gcc // RUN: touch %t/%target_triple-gcc && chmod +x %t/%target_triple-gcc // RUN: env "PATH=%t/env/" %t/clang -### -target notreal-none-elf %s 2>&1 | \ // RUN: FileCheck --check-prefix=DEFAULT_TRIPLE_GCC %s @@ -101,7 +101,7 @@ // DEFAULT_TRIPLE_NO_NOTREAL: env/gcc" // DEFAULT_TRIPLE_NO_NOTREAL-NOT: -gcc" -/// Pick "gcc" as a fallback. Don't pick $DEFAULT_TRIPLE-gcc. +/// Pick "gcc" as a fallback. Don't pick DEFAULT_TRIPLE-gcc. // RUN: rm %t/env/gcc // RUN: env "PATH=%t/env/" %t/clang -### -target notreal-none-elf %s 2>&1 | \ // RUN: FileCheck --check-prefix=DEFAULT_TRIPLE_NO_OTHERS %s @@ -110,9 +110,9 @@ /// -B paths are searched separately so default triple will win /// if put in one of those even if other paths have higher priority names // RUN: mkdir -p %t/prefix -/// One of these will fail when $DEFAULT_TRIPLE == %target_triple -// RUN: test -f %t/$DEFAULT_TRIPLE-gcc && \ -// RUN: mv %t/$DEFAULT_TRIPLE-gcc %t/prefix || true +/// One of these will fail when %{readfile:%t.default_triple} == %target_triple +// RUN: test -f %t/%{readfile:%t.default_triple}-gcc && \ +// RUN: mv %t/%{readfile:%t.default_triple}-gcc %t/prefix || true // RUN: test -f %t/%target_triple-gcc && \ // RUN: mv %t/%target_triple-gcc %t/prefix || true // RUN: touch %t/notreal-none-elf-gcc && chmod +x %t/notreal-none-elf-gcc @@ -123,8 +123,8 @@ // DEFAULT_TRIPLE_IN_PREFIX-NOT: notreal-none-elf-gcc" /// Only if there is nothing in the prefix will we search other paths -/// -f in case $DEFAULT_TRIPLE == %target_triple -// RUN: rm -f %t/prefix/$DEFAULT_TRIPLE-gcc %t/prefix/%target_triple-gcc %t/prefix/gcc +/// -f in case %{readfile:%t.default_triple} == %target_triple +// RUN: rm -f %t/prefix/%{readfile:%t.default_triple}-gcc %t/prefix/%target_triple-gcc %t/prefix/gcc // RUN: env "PATH=" %t/clang -### -canonical-prefixes --target=notreal-none-elf %s -B %t/prefix 2>&1 | \ // RUN: FileCheck --check-prefix=EMPTY_PREFIX_DIR1 %s // EMPTY_PREFIX_DIR1: gcc" diff --git a/clang/test/Modules/relative-resource-dir.m b/clang/test/Modules/relative-resource-dir.m index 4f88150a2ba4c..96f2d8efc7860 100644 --- a/clang/test/Modules/relative-resource-dir.m +++ b/clang/test/Modules/relative-resource-dir.m @@ -1,9 +1,9 @@ // UNSUPPORTED: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}} -// REQUIRES: shell -// RUN: EXPECTED_RESOURCE_DIR=`%clang -print-resource-dir` && \ +// RUN: %clang -print-resource-dir | tr -d '\n' > %t.resource_dir +// RUN: env EXPECTED_RESOURCE_DIR="%{readfile:%t.resource_dir}" && \ // RUN: mkdir -p %t && rm -rf %t/resource-dir && \ -// RUN: cp -R $EXPECTED_RESOURCE_DIR %t/resource-dir +// RUN: cp -R %{readfile:%t.resource_dir} %t/resource-dir // RUN: cd %t && %clang -cc1 -x objective-c -fmodules -fmodule-format=obj \ // RUN: -fimplicit-module-maps -fmodules-cache-path=%t.mcp \ // RUN: -fbuiltin-headers-in-system-modules \ diff --git a/llvm/docs/CommandGuide/lit.rst b/llvm/docs/CommandGuide/lit.rst index 15c249d8e6d31..359e0c3e81d0e 100644 --- a/llvm/docs/CommandGuide/lit.rst +++ b/llvm/docs/CommandGuide/lit.rst @@ -664,6 +664,7 @@ TestRunner.py: Otherwise, %t but with a single leading ``/`` removed. %:T On Windows, %/T but a ``:`` is removed if its the second character. Otherwise, %T but with a single leading ``/`` removed. + %{readfile:<filename>} Reads the file specified. ======================= ============== Other substitutions are provided that are variations on this base set and diff --git a/llvm/test/tools/llvm-cgdata/empty.test b/llvm/test/tools/llvm-cgdata/empty.test index 52d0dfb87623f..7e42db5ed8512 100644 --- a/llvm/test/tools/llvm-cgdata/empty.test +++ b/llvm/test/tools/llvm-cgdata/empty.test @@ -35,3 +35,4 @@ RUN: printf '\000\000\000\000' >> %t_header.cgdata RUN: printf '\040\000\000\000\000\000\000\000' >> %t_header.cgdata RUN: printf '\040\000\000\000\000\000\000\000' >> %t_header.cgdata RUN: diff %t_header.cgdata %t_emptyheader.cgdata +RUN: echo %{readfile:/tmp/test} > /tmp/test diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 90c2c6479b004..5daa8887e4c80 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -720,6 +720,23 @@ def processRedirects(cmd, stdin_source, cmd_shenv, opened_files): return std_fds +def _expandLateSubstitutions(arguments, cwd): + for i, arg in enumerate(arguments): + if not isinstance(arg, str): + continue + + def _replaceReadFile(match): + filePath = match.group(1) + if not os.path.isabs(filePath): + filePath = os.path.join(cwd, filePath) + with open(filePath) as fileHandle: + return fileHandle.read() + + arguments[i] = re.sub(r"%{readfile:([^}]*)}", _replaceReadFile, arg) + + return arguments + + def _executeShCmd(cmd, shenv, results, timeoutHelper): if timeoutHelper.timeoutReached(): # Prevent further recursion if the timeout has been hit @@ -834,6 +851,9 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper): # Ensure args[0] is hashable. args[0] = expand_glob(args[0], cmd_shenv.cwd)[0] + # Expand all late substitutions + args = _expandLateSubstitutions(args, cmd_shenv.cwd) + inproc_builtin = inproc_builtins.get(args[0], None) if inproc_builtin and (args[0] != "echo" or len(cmd.commands) == 1): # env calling an in-process builtin is useless, so we take the safe diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/absolute-paths.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/absolute-paths.txt new file mode 100644 index 0000000000000..4246064cf7bfc --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/absolute-paths.txt @@ -0,0 +1,6 @@ +## Tests that readfile works with absolute paths +# RUN: echo -n "hello" > %t +# RUN: echo %{readfile:%t} + +## Fail the test so we can assert on the output. +# RUN: not echo return diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg b/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg new file mode 100644 index 0000000000000..25651f2cd4832 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/lit.cfg @@ -0,0 +1,8 @@ +import lit.formats + +config.name = "shtest-readfile" +config.suffixes = [".txt"] +config.test_format = lit.formats.ShTest(execute_external=False) +config.test_source_root = None +config.test_exec_root = None +config.substitutions.append(("%{python}", '"%s"' % (sys.executable))) diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/relative-paths.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/relative-paths.txt new file mode 100644 index 0000000000000..3d203d411379d --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/relative-paths.txt @@ -0,0 +1,7 @@ +## Tests that readfile works with relative paths +# RUN: mkdir -p rel_path_test_folder +# RUN: echo -n "hello" > rel_path_test_folder/test_file +# RUN: echo %{readfile:rel_path_test_folder/test_file} + +## Fail the test so we can assert on the output. +# RUN: not echo return diff --git a/llvm/utils/lit/tests/Inputs/shtest-readfile/two-same-line.txt b/llvm/utils/lit/tests/Inputs/shtest-readfile/two-same-line.txt new file mode 100644 index 0000000000000..6855d27d66d35 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-readfile/two-same-line.txt @@ -0,0 +1,8 @@ +## Tests that readfile works with two substitutions on the same line to ensure the +## regular expressions are setup correctly. +# RUN: echo -n "hello" > %t.1 +# RUN: echo -n "bye" > %t.2 +# RUN: echo %{readfile:%t.1} %{readfile:%t.2} + +## Fail the test so we can assert on the output. +# RUN: not echo return diff --git a/llvm/utils/lit/tests/shtest-readfile.py b/llvm/utils/lit/tests/shtest-readfile.py new file mode 100644 index 0000000000000..8ba8e53b32966 --- /dev/null +++ b/llvm/utils/lit/tests/shtest-readfile.py @@ -0,0 +1,17 @@ +## Tests the readfile substitution + +# RUN: not %{lit} -a -v %{inputs}/shtest-readfile | FileCheck -match-full-lines %s + +# CHECK: -- Testing: 3 tests{{.*}} + +# CHECK-LABEL: FAIL: shtest-readfile :: absolute-paths.txt ({{[^)]*}}) +# CHECK: echo hello +# CHECK: # executed command: echo '%{readfile:{{.*}}}' + +# CHECK-LABEL: FAIL: shtest-readfile :: relative-paths.txt ({{[^)]*}}) +# CHECK: echo hello +# CHECK: # executed command: echo '%{readfile:rel_path_test_folder/test_file}' + +# CHECK-LABEL: FAIL: shtest-readfile :: two-same-line.txt ({{[^)]*}}) +# CHECK: echo hello bye +# CHECK: # executed command: echo '%{readfile:{{.*}}.1}' '%{readfile:{{.*}}.2}' _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits