From 72038b124d65847d3f8a5705c744ccd201bdb7d6 Mon Sep 17 00:00:00 2001 From: William Woodruff 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 --- 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 +#include + +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; +}