[clang] [clang][test] Fix test failures when LLVM_WINDOWS_PREFER_FORWARD_SLAS… (PR #193145)
Takuto Ikuta via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 20 22:53:07 PDT 2026
https://github.com/atetubou updated https://github.com/llvm/llvm-project/pull/193145
>From 4cf8692d602a794b0ff4e4823b403a57a5a91aaf Mon Sep 17 00:00:00 2001
From: Takuto Ikuta <tikuta at chromium.org>
Date: Tue, 14 Apr 2026 19:43:45 +0900
Subject: [PATCH] [clang][test] Fix test failures when
LLVM_WINDOWS_PREFER_FORWARD_SLASH is ON
This commit addresses several test failures in Clang that occur on Windows when
the CMake option -DLLVM_WINDOWS_PREFER_FORWARD_SLASH=ON is enabled. This option
changes the native path style to prefer forward slashes, causing mismatches in
tests that hardcode backslashes in expected output or shell commands.
Key changes:
- unit tests: Normalized expected paths to native style using llvm::sys::path::native
(Basic/FileManagerTest, Frontend/ReparseWorkingDirTest) or updated hardcoded strings
to use forward slashes which are compatible with both modes (Driver/ToolChainTest).
- regression tests: Updated FileCheck patterns to use flexible regex {{[/\\]}} or
{{[/\\]+}} to match both path separator styles.
- absolute-paths-windows.test: Replaced mklink with a Python-based wrapper because
mklink does not support forward slashes in directory paths and interprets them
as command-line switches.
---
.../test/DebugInfo/Generic/debug-prefix-map.c | 22 ++++++-----
clang/test/Driver/ps4-ps5-linker-win.c | 5 ++-
.../test/Frontend/absolute-paths-windows.test | 9 +++--
.../dependency-gen-windows-duplicates.c | 5 ++-
clang/test/Preprocessor/file_test_windows.c | 39 ++++++++++---------
clang/unittests/Basic/FileManagerTest.cpp | 8 ++++
clang/unittests/Driver/ToolChainTest.cpp | 13 +++++--
.../Frontend/ReparseWorkingDirTest.cpp | 4 ++
8 files changed, 65 insertions(+), 40 deletions(-)
diff --git a/clang/test/DebugInfo/Generic/debug-prefix-map.c b/clang/test/DebugInfo/Generic/debug-prefix-map.c
index e58909f5acaaa..e7da1abf1cfc5 100644
--- a/clang/test/DebugInfo/Generic/debug-prefix-map.c
+++ b/clang/test/DebugInfo/Generic/debug-prefix-map.c
@@ -27,27 +27,29 @@ void test_rewrite_includes(void) {
vprintf("string", argp);
}
-// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "{{/|.:\\\\}}UNLIKELY_PATH{{/|\\\\}}empty{{/|\\\\}}{{.*}}",
+// Forward or backward slashes can be used depending on LLVM_WINDOWS_PREFER_FORWARD_SLASH.
+// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "{{/|.:[/\\]+}}UNLIKELY_PATH{{/|\\\\}}empty{{/|\\\\}}{{.*}}",
// CHECK-NO-MAIN-FILE-NAME-SAME: directory: "")
-// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "{{/|.:\\\\}}UNLIKELY_PATH{{/|\\\\}}empty{{/|\\\\}}<stdin>",
-// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "{{/|.:\\\\}}UNLIKELY_PATH{{/|\\\\}}empty{{/|\\\\}}Inputs{{/|\\\\}}stdio.h",
+// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "{{/|.:[/\\]+}}UNLIKELY_PATH{{/|\\\\}}empty{{/|\\\\}}<stdin>",
+// CHECK-NO-MAIN-FILE-NAME: !DIFile(filename: "{{/|.:[/\\]+}}UNLIKELY_PATH{{/|\\\\}}empty{{/|\\\\}}Inputs{{/|\\\\}}stdio.h",
// CHECK-NO-MAIN-FILE-NAME-SAME: directory: "")
// CHECK-NO-MAIN-FILE-NAME-NOT: !DIFile(filename:
-// CHECK-EVIL: !DIFile(filename: "{{/|.:\\\\}}UNLIKELY_PATH=empty{{/|\\\\}}{{.*}}"
-// CHECK-EVIL: !DIFile(filename: "{{/|.:\\\\}}UNLIKELY_PATH=empty{{/|\\\\}}{{.*}}Inputs{{/|\\\\}}stdio.h",
+// CHECK-EVIL: !DIFile(filename: "{{/|.:[/\\]+}}UNLIKELY_PATH=empty{{/|\\\\}}{{.*}}"
+// CHECK-EVIL: !DIFile(filename: "{{/|.:[/\\]+}}UNLIKELY_PATH=empty{{/|\\\\}}{{.*}}Inputs{{/|\\\\}}stdio.h",
// CHECK-EVIL-SAME: directory: "")
// CHECK-EVIL-NOT: !DIFile(filename:
-// CHECK: !DIFile(filename: "{{/|.:\\\\}}UNLIKELY_PATH{{/|\\\\}}empty{{/|\\\\}}{{.*}}",
-// CHECK: !DIFile(filename: "{{/|.:\\\\}}UNLIKELY_PATH{{/|\\\\}}empty{{/|\\\\}}{{.*}}Inputs{{/|\\\\}}stdio.h",
+// CHECK: !DIFile(filename: "{{/|.:[/\\]+}}UNLIKELY_PATH{{/|\\\\}}empty{{/|\\\\}}{{.*}}",
+// CHECK: !DIFile(filename: "{{/|.:[/\\]+}}UNLIKELY_PATH{{/|\\\\}}empty{{/|\\\\}}{{.*}}Inputs{{/|\\\\}}stdio.h",
// CHECK-SAME: directory: ""
// CHECK-NOT: !DIFile(filename:
-// CHECK-COMPILATION-DIR: !DIFile(filename: "{{.*}}", directory: "{{/|.:\\\\}}UNLIKELY_PATH{{/|\\\\}}empty")
-// CHECK-COMPILATION-DIR: !DIFile(filename: "{{.*}}Inputs{{/|\\\\}}stdio.h", directory: "{{/|.:\\\\}}UNLIKELY_PATH{{/|\\\\}}empty")
+// CHECK-COMPILATION-DIR: !DIFile(filename: "{{.*}}", directory: "{{/|.:[/\\]+}}UNLIKELY_PATH{{/|\\\\}}empty")
+// CHECK-COMPILATION-DIR: !DIFile(filename: "{{.*}}Inputs{{/|\\\\}}stdio.h", directory: "{{/|.:[/\\]+}}UNLIKELY_PATH{{/|\\\\}}empty")
// CHECK-COMPILATION-DIR-NOT: !DIFile(filename:
-// CHECK-SYSROOT: !DICompileUnit({{.*}}sysroot: "{{/|.:\\\\}}UNLIKELY_PATH{{/|\\\\}}empty"
+// CHECK-SYSROOT: !DICompileUnit({{.*}}sysroot: "{{/|.:[/\\]+}}UNLIKELY_PATH{{/|\\\\}}empty"
+
// CHECK-REL: !DIFile(filename: "./UNLIKELY_PATH/empty{{/|\\\\}}{{.*}}",
// CHECK-REL: !DIFile(filename: "./UNLIKELY_PATH/empty{{/|\\\\}}{{.*}}Inputs/stdio.h",
diff --git a/clang/test/Driver/ps4-ps5-linker-win.c b/clang/test/Driver/ps4-ps5-linker-win.c
index fcb203c26fb62..9e7fdef4ced2d 100644
--- a/clang/test/Driver/ps4-ps5-linker-win.c
+++ b/clang/test/Driver/ps4-ps5-linker-win.c
@@ -16,8 +16,9 @@
// RUN: env "PATH=%t;%PATH%;" %clang -target x86_64-sie-ps5 %s -shared -### 2>&1 \
// RUN: | FileCheck --check-prefixes=CHECK-PS5-LINKER,SHARED %s
-// CHECK-PS4-LINKER: \\orbis-ld
-// CHECK-PS5-LINKER: \\prospero-lld
+// Forward or backward slashes can be used depending on LLVM_WINDOWS_PREFER_FORWARD_SLASH.
+// CHECK-PS4-LINKER: {{/|\\\\}}orbis-ld
+// CHECK-PS5-LINKER: {{/|\\\\}}prospero-lld
// SHARED: "--shared"
// RUN: env "PATH=%t;%PATH%;" not %clang --target=x86_64-scei-ps4 %s -fuse-ld=gold -### 2>&1 \
diff --git a/clang/test/Frontend/absolute-paths-windows.test b/clang/test/Frontend/absolute-paths-windows.test
index 10741d56452b3..edb4e80fa7e81 100644
--- a/clang/test/Frontend/absolute-paths-windows.test
+++ b/clang/test/Frontend/absolute-paths-windows.test
@@ -1,9 +1,12 @@
// REQUIRES: system-windows
// RUN: rm -rf %t.dir
// RUN: mkdir -p %t.dir\real
-// RUN: cmd /c mklink /j %t.dir\junc %t.dir\real
+// When LLVM_WINDOWS_PREFER_FORWARD_SLASH is on, %t.dir contains forward slashes.
+// mklink /j does not support forward slashes.
+// Use python to replace forward slashes with backslashes and call mklink.
+// RUN: %python -c "import subprocess; p1 = r'%t.dir/junc'.replace('/', '\\\\'); p2 = r'%t.dir/real'.replace('/', '\\\\'); subprocess.run(['cmd', '/c', 'mklink', '/j', p1, p2], check=True)"
// RUN: echo "wrong code" > %t.dir\real\foo.cpp
// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-absolute-paths %t.dir\junc\foo.cpp 2>&1 | FileCheck %s
-// CHECK-NOT: .dir\real\foo.cpp
-// CHECK: .dir\junc\foo.cpp
+// CHECK-NOT: .dir{{[/\\]}}real{{[/\\]}}foo.cpp
+// CHECK: .dir{{[/\\]}}junc{{[/\\]}}foo.cpp
diff --git a/clang/test/Frontend/dependency-gen-windows-duplicates.c b/clang/test/Frontend/dependency-gen-windows-duplicates.c
index abd351377dc33..a43eef0270ae7 100644
--- a/clang/test/Frontend/dependency-gen-windows-duplicates.c
+++ b/clang/test/Frontend/dependency-gen-windows-duplicates.c
@@ -8,8 +8,9 @@
// RUN: %clang -MD -MF - %t.dir/test.c -fsyntax-only -I %t.dir/subdir | FileCheck %s
// CHECK: test.o:
-// CHECK-NEXT: \test.c
-// CHECK-NEXT: \SubDir\X.h
+// Forward or backward slashes can be used depending on LLVM_WINDOWS_PREFER_FORWARD_SLASH.
+// CHECK-NEXT: {{[/\\]}}test.c \
+// CHECK-NEXT: {{[/\\]}}SubDir{{[/\\]}}X.h
// File x.h must appear only once (case insensitive check).
// CHECK-NOT: {{\\|/}}{{x|X}}.{{h|H}}
diff --git a/clang/test/Preprocessor/file_test_windows.c b/clang/test/Preprocessor/file_test_windows.c
index 89324001330e2..6af5c0b6f5a93 100644
--- a/clang/test/Preprocessor/file_test_windows.c
+++ b/clang/test/Preprocessor/file_test_windows.c
@@ -24,19 +24,20 @@
filename: __FILE__
#include "Inputs/include-file-test/file_test.h"
-// CHECK: filename: "A:\\UNLIKELY_PATH\\empty\\file_test_windows.c"
-// CHECK: filename: "A:\\UNLIKELY_PATH\\empty\\Inputs/include-file-test/file_test.h"
-// CHECK: basefile: "A:\\UNLIKELY_PATH\\empty\\file_test_windows.c"
+// Forward or backward slashes can be used depending on LLVM_WINDOWS_PREFER_FORWARD_SLASH.
+// CHECK: filename: "A:{{[/\\]+}}UNLIKELY_PATH{{[/\\]+}}empty{{[/\\]+}}file_test_windows.c"
+// CHECK: filename: "A:{{[/\\]+}}UNLIKELY_PATH{{[/\\]+}}empty{{[/\\]+}}Inputs/include-file-test/file_test.h"
+// CHECK: basefile: "A:{{[/\\]+}}UNLIKELY_PATH{{[/\\]+}}empty{{[/\\]+}}file_test_windows.c"
// CHECK-NOT: filename:
-// CHECK-EVIL: filename: "A:\\UNLIKELY_PATH=empty\\file_test_windows.c"
-// CHECK-EVIL: filename: "A:\\UNLIKELY_PATH=empty\\Inputs/include-file-test/file_test.h"
-// CHECK-EVIL: basefile: "A:\\UNLIKELY_PATH=empty\\file_test_windows.c"
+// CHECK-EVIL: filename: "A:{{[/\\]+}}UNLIKELY_PATH=empty{{[/\\]+}}file_test_windows.c"
+// CHECK-EVIL: filename: "A:{{[/\\]+}}UNLIKELY_PATH=empty{{[/\\]+}}Inputs/include-file-test/file_test.h"
+// CHECK-EVIL: basefile: "A:{{[/\\]+}}UNLIKELY_PATH=empty{{[/\\]+}}file_test_windows.c"
// CHECK-EVIL-NOT: filename:
-// CHECK-CASE: filename: "A:\\UNLIKELY_PATH_BASE\\file_test_windows.c"
-// CHECK-CASE: filename: "A:\\UNLIKELY_PATH_INC\\include-file-test/file_test.h"
-// CHECK-CASE: basefile: "A:\\UNLIKELY_PATH_BASE\\file_test_windows.c"
+// CHECK-CASE: filename: "A:{{[/\\]+}}UNLIKELY_PATH_BASE{{[/\\]+}}file_test_windows.c"
+// CHECK-CASE: filename: "A:{{[/\\]+}}UNLIKELY_PATH_INC{{[/\\]+}}include-file-test/file_test.h"
+// CHECK-CASE: basefile: "A:{{[/\\]+}}UNLIKELY_PATH_BASE{{[/\\]+}}file_test_windows.c"
// CHECK-CASE-NOT: filename:
// CHECK-REMOVE: filename: "file_test_windows.c"
@@ -44,23 +45,23 @@ filename: __FILE__
// CHECK-REMOVE: basefile: "file_test_windows.c"
// CHECK-REMOVE-NOT: filename:
-// CHECK-REPRODUCIBLE: filename: "A:\\UNLIKELY_PATH\\empty\\file_test_windows.c"
-// CHECK-REPRODUCIBLE: filename: "A:\\UNLIKELY_PATH\\empty\\Inputs\\include-file-test\\file_test.h"
-// CHECK-REPRODUCIBLE: basefile: "A:\\UNLIKELY_PATH\\empty\\file_test_windows.c"
+// CHECK-REPRODUCIBLE: filename: "A:{{[/\\]+}}UNLIKELY_PATH{{[/\\]+}}empty{{[/\\]+}}file_test_windows.c"
+// CHECK-REPRODUCIBLE: filename: "A:{{[/\\]+}}UNLIKELY_PATH{{[/\\]+}}empty{{[/\\]+}}Inputs{{[/\\]+}}include-file-test{{[/\\]+}}file_test.h"
+// CHECK-REPRODUCIBLE: basefile: "A:{{[/\\]+}}UNLIKELY_PATH{{[/\\]+}}empty{{[/\\]+}}file_test_windows.c"
// CHECK-REPRODUCIBLE-NOT: filename:
-// CHECK-EVIL-REPRODUCIBLE: filename: "A:\\UNLIKELY_PATH=empty\\file_test_windows.c"
-// CHECK-EVIL-REPRODUCIBLE: filename: "A:\\UNLIKELY_PATH=empty\\Inputs\\include-file-test\\file_test.h"
-// CHECK-EVIL-REPRODUCIBLE: basefile: "A:\\UNLIKELY_PATH=empty\\file_test_windows.c"
+// CHECK-EVIL-REPRODUCIBLE: filename: "A:{{[/\\]+}}UNLIKELY_PATH=empty{{[/\\]+}}file_test_windows.c"
+// CHECK-EVIL-REPRODUCIBLE: filename: "A:{{[/\\]+}}UNLIKELY_PATH=empty{{[/\\]+}}Inputs{{[/\\]+}}include-file-test{{[/\\]+}}file_test.h"
+// CHECK-EVIL-REPRODUCIBLE: basefile: "A:{{[/\\]+}}UNLIKELY_PATH=empty{{[/\\]+}}file_test_windows.c"
// CHECK-EVIL-REPRODUCIBLE-NOT: filename:
-// CHECK-CASE-REPRODUCIBLE: filename: "A:\\UNLIKELY_PATH_BASE\\file_test_windows.c"
-// CHECK-CASE-REPRODUCIBLE: filename: "A:\\UNLIKELY_PATH_INC\\include-file-test\\file_test.h"
-// CHECK-CASE-REPRODUCIBLE: basefile: "A:\\UNLIKELY_PATH_BASE\\file_test_windows.c"
+// CHECK-CASE-REPRODUCIBLE: filename: "A:{{[/\\]+}}UNLIKELY_PATH_BASE{{[/\\]+}}file_test_windows.c"
+// CHECK-CASE-REPRODUCIBLE: filename: "A:{{[/\\]+}}UNLIKELY_PATH_INC{{[/\\]+}}include-file-test{{[/\\]+}}file_test.h"
+// CHECK-CASE-REPRODUCIBLE: basefile: "A:{{[/\\]+}}UNLIKELY_PATH_BASE{{[/\\]+}}file_test_windows.c"
// CHECK-CASE-REPRODUCIBLE-NOT: filename:
// CHECK-REMOVE-REPRODUCIBLE: filename: "file_test_windows.c"
-// CHECK-REMOVE-REPRODUCIBLE: filename: "Inputs\\include-file-test\\file_test.h"
+// CHECK-REMOVE-REPRODUCIBLE: filename: "Inputs{{[/\\]+}}include-file-test{{[/\\]+}}file_test.h"
// CHECK-REMOVE-REPRODUCIBLE: basefile: "file_test_windows.c"
// CHECK-REMOVE-REPRODUCIBLE-NOT: filename:
diff --git a/clang/unittests/Basic/FileManagerTest.cpp b/clang/unittests/Basic/FileManagerTest.cpp
index 7b3e8bc9313ca..e54d3f8f9e416 100644
--- a/clang/unittests/Basic/FileManagerTest.cpp
+++ b/clang/unittests/Basic/FileManagerTest.cpp
@@ -493,6 +493,10 @@ TEST_F(FileManagerTest, getVirtualFileFillsRealPathName) {
SmallString<64> ExpectedResult = CustomWorkingDir;
llvm::sys::path::append(ExpectedResult, "tmp", "test");
+ // Normalize to native path style to match tryGetRealPathName()
+ // which uses native style (potentially forward slashes on Windows
+ // if LLVM_WINDOWS_PREFER_FORWARD_SLASH is on).
+ llvm::sys::path::native(ExpectedResult);
EXPECT_EQ(file.getFileEntry().tryGetRealPathName(), ExpectedResult);
}
@@ -519,6 +523,10 @@ TEST_F(FileManagerTest, getFileDontOpenRealPath) {
SmallString<64> ExpectedResult = CustomWorkingDir;
llvm::sys::path::append(ExpectedResult, "tmp", "test");
+ // Normalize to native path style to match tryGetRealPathName()
+ // which uses native style (potentially forward slashes on Windows
+ // if LLVM_WINDOWS_PREFER_FORWARD_SLASH is on).
+ llvm::sys::path::native(ExpectedResult);
EXPECT_EQ(file->getFileEntry().tryGetRealPathName(), ExpectedResult);
}
diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp
index 8f533790ec501..845420625e0ee 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -820,8 +820,11 @@ TEST(ToolChainTest, ConfigInexistentInclude) {
#ifdef _WIN32
const char *TestRoot = "C:\\";
-#define USERCONFIG "C:\\home\\user\\test.cfg"
-#define UNEXISTENT "C:\\home\\user\\file.rsp"
+ // Forward slashes are consistently used by Clang's path handling in these
+ // diagnostics when LLVM_WINDOWS_PREFER_FORWARD_SLASH is on.
+ // They are also generally supported on Windows in these components.
+#define USERCONFIG "C:/home/user/test.cfg"
+#define UNEXISTENT "C:/home/user/file.rsp"
#else
const char *TestRoot = "/";
#define USERCONFIG "/home/user/test.cfg"
@@ -860,8 +863,10 @@ TEST(ToolChainTest, ConfigRecursiveInclude) {
#ifdef _WIN32
const char *TestRoot = "C:\\";
-#define USERCONFIG "C:\\home\\user\\test.cfg"
-#define INCLUDED1 "C:\\home\\user\\file1.cfg"
+ // Forward slashes are consistently used by Clang's path handling in these
+ // diagnostics when LLVM_WINDOWS_PREFER_FORWARD_SLASH is on.
+#define USERCONFIG "C:/home/user/test.cfg"
+#define INCLUDED1 "C:/home/user/file1.cfg"
#else
const char *TestRoot = "/";
#define USERCONFIG "/home/user/test.cfg"
diff --git a/clang/unittests/Frontend/ReparseWorkingDirTest.cpp b/clang/unittests/Frontend/ReparseWorkingDirTest.cpp
index 6b34b967a731c..b599bcc90dc3d 100644
--- a/clang/unittests/Frontend/ReparseWorkingDirTest.cpp
+++ b/clang/unittests/Frontend/ReparseWorkingDirTest.cpp
@@ -90,6 +90,10 @@ TEST_F(ReparseWorkingDirTest, ReparseWorkingDir) {
WorkingDir = "/";
#endif
llvm::sys::path::append(WorkingDir, "root");
+ // Normalize to native path style to match FileManager's WorkingDir
+ // which uses native style (potentially forward slashes on Windows
+ // if LLVM_WINDOWS_PREFER_FORWARD_SLASH is on).
+ llvm::sys::path::native(WorkingDir);
setWorkingDirectory(WorkingDir);
SmallString<32> Header;
More information about the cfe-commits
mailing list