[compiler-rt] [compiler-rt][profile] Accept Unicode profile names on Windows (PR #202335)

William Woodruff via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 06:38:22 PDT 2026


https://github.com/woodruffw updated https://github.com/llvm/llvm-project/pull/202335

>From 96ab6d4eb83a1f30d6d580df4af7239073a9cb25 Mon Sep 17 00:00:00 2001
From: William Woodruff <william at yossarian.net>
Date: Fri, 5 Jun 2026 17:37:43 -0400
Subject: [PATCH] [compiler-rt][profile] Accept Unicode profile names on
 Windows

This addresses a small FIXME: when opening a profile file
on Windows, we now use `CreateFileW` instead of `CreateFileA`.

This fixes a relatively niche scenario in which the profile
file contains Unicode codepoints that `CreateFileA` can't handle.

I've also added a small test for `lprofOpenFileEx`
that exercises the change.

Signed-off-by: William Woodruff <william at yossarian.net>
---
 compiler-rt/lib/profile/InstrProfilingUtil.c  | 20 +++++++++++++++--
 .../Windows/instrprof-file-ex-unicode.c       | 22 +++++++++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)
 create mode 100644 compiler-rt/test/profile/Windows/instrprof-file-ex-unicode.c

diff --git a/compiler-rt/lib/profile/InstrProfilingUtil.c b/compiler-rt/lib/profile/InstrProfilingUtil.c
index a9d9df813764b..21005bc5ff87f 100644
--- a/compiler-rt/lib/profile/InstrProfilingUtil.c
+++ b/compiler-rt/lib/profile/InstrProfilingUtil.c
@@ -237,10 +237,26 @@ COMPILER_RT_VISIBILITY FILE *lprofOpenFileEx(const char *ProfileName) {
 
   f = fdopen(fd, "r+b");
 #elif defined(_WIN32)
-  // FIXME: Use the wide variants to handle Unicode filenames.
-  HANDLE h = CreateFileA(ProfileName, GENERIC_READ | GENERIC_WRITE,
+  int WideLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
+                                       ProfileName, -1, NULL, 0);
+  if (WideLength == 0)
+    return NULL;
+
+  WCHAR *WideProfileName =
+      (WCHAR *)malloc((size_t)WideLength * sizeof(*WideProfileName));
+  if (!WideProfileName)
+    return NULL;
+
+  if (MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, ProfileName, -1,
+                          WideProfileName, WideLength) == 0) {
+    free(WideProfileName);
+    return NULL;
+  }
+
+  HANDLE h = CreateFileW(WideProfileName, GENERIC_READ | GENERIC_WRITE,
                          FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_ALWAYS,
                          FILE_ATTRIBUTE_NORMAL, 0);
+  free(WideProfileName);
   if (h == INVALID_HANDLE_VALUE)
     return NULL;
 
diff --git a/compiler-rt/test/profile/Windows/instrprof-file-ex-unicode.c b/compiler-rt/test/profile/Windows/instrprof-file-ex-unicode.c
new file mode 100644
index 0000000000000..ebd3b3bc94488
--- /dev/null
+++ b/compiler-rt/test/profile/Windows/instrprof-file-ex-unicode.c
@@ -0,0 +1,22 @@
+// RUN: %clang_profgen -o %t.exe %s
+// RUN: rm -rf %t.dir
+// RUN: mkdir %t.dir
+// RUN: cd %t.dir
+// RUN: %run %t.exe
+
+#include <stdio.h>
+#include <windows.h>
+
+extern FILE *lprofOpenFileEx(const char *);
+
+int main(void) {
+  const char *Filename = "profile-\xe6\x97\xa5.dump";
+  FILE *File = lprofOpenFileEx(Filename);
+  if (!File)
+    return 1;
+
+  fputs("profile data", File);
+  fclose(File);
+
+  return GetFileAttributesW(L"profile-\u65e5.dump") == INVALID_FILE_ATTRIBUTES;
+}



More information about the llvm-commits mailing list