Skip to content

Commit ca771c4

Browse files
committed
Change to returning nullptr rather than triggering a fatal error.
Instead of triggering a fatal error on failure, return `nullptr` and let the caller decide what to do about it. The CommandLine code should trigger a fatal error, of course. rdar://103397975
1 parent a31b1c5 commit ca771c4

File tree

3 files changed

+28
-32
lines changed

3 files changed

+28
-32
lines changed

include/swift/Runtime/Win32.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ namespace win32 {
3333
/// @returns The string, converted to UTF-8. The caller is responsible
3434
/// for freeing this string with @c free() when done with it.
3535
///
36-
/// If @a str cannot be converted to UTF-8, a fatal error occurs.
36+
/// If @a str cannot be converted to UTF-8, @c nullptr is returned.
3737
SWIFT_RUNTIME_STDLIB_INTERNAL
3838
char *copyUTF8FromWide(const wchar_t *str);
3939

@@ -44,7 +44,7 @@ char *copyUTF8FromWide(const wchar_t *str);
4444
/// @returns The string, converted to UTF-16. The caller is responsible
4545
/// for freeing this string with @c free() when done with it.
4646
///
47-
/// If @a str cannot be converted to UTF-16, a fatal error occurs.
47+
/// If @a str cannot be converted to UTF-16, @c nullptr is returned.
4848
SWIFT_RUNTIME_STDLIB_INTERNAL
4949
wchar_t *copyWideFromUTF8(const char *str);
5050

stdlib/public/CommandLineSupport/CommandLine.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,15 @@ static void swift::enumerateUnsafeArgv(const F& body) {
204204
if (LPWSTR *wargv = CommandLineToArgvW(GetCommandLineW(), &argc)) {
205205
std::for_each(wargv, wargv + argc, [=] (wchar_t *warg) {
206206
auto arg = swift::win32::copyUTF8FromWide(warg);
207+
if (!arg) {
208+
// Note that GetLastError() and errno may not be so useful here,
209+
// as in the error case we may have called free(), which might reset
210+
// either or both of them.
211+
swift::fatalError(0,
212+
"Fatal error: Unable to convert argument '%ls' to "
213+
"UTF-8: %lx, %d.\n",
214+
warg, ::GetLastError(), errno);
215+
}
207216
body(argc, arg);
208217
free(arg);
209218
});

stdlib/public/runtime/Win32.cpp

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,23 @@ swift::win32::copyUTF8FromWide(const wchar_t *str) {
2828
str, -1,
2929
nullptr, 0,
3030
nullptr, nullptr);
31-
if (len <= 0) {
32-
swift::fatalError(0, "failed to convert string '%ls' "
33-
"from wide to UTF-8: %lx\n",
34-
str, ::GetLastError());
35-
}
31+
if (len <= 0)
32+
return nullptr;
3633

3734
result = reinterpret_cast<char *>(std::malloc(len));
38-
if (!result) {
39-
swift::fatalError(0, "unable to allocate space to convert '%ls': %d\n",
40-
str, errno);
41-
}
35+
if (!result)
36+
return nullptr;
4237

4338
len = ::WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
4439
str, -1,
4540
result, len,
4641
nullptr, nullptr);
4742

48-
if (len <= 0) {
49-
swift::fatalError(0, "failed to convert string '%ls' "
50-
"from wide to UTF-8: %lx\n",
51-
str, ::GetLastError());
52-
}
43+
if (len)
44+
return result;
5345

54-
return result;
46+
free(result);
47+
return nullptr;
5548
}
5649

5750
wchar_t *
@@ -60,28 +53,22 @@ swift::win32::copyWideFromUTF8(const char *str) {
6053
int len = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
6154
str, -1,
6255
nullptr, 0);
63-
if (len <= 0) {
64-
swift::fatalError(0, "failed to convert string '%s' "
65-
"from UTF-8 to wide: %lx\n",
66-
str, ::GetLastError());
67-
}
56+
if (len <= 0)
57+
return nullptr;
6858

6959
result = reinterpret_cast<wchar_t *>(std::malloc(len * sizeof(wchar_t)));
70-
if (!result) {
71-
swift::fatalError(0, "unable to allocate space to convert '%s': %d\n",
72-
str, errno);
73-
}
60+
if (!result)
61+
return nullptr;
7462

7563
len = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
7664
str, -1,
7765
result, len);
78-
if (len <= 0) {
79-
swift::fatalError(0, "failed to convert string '%s' "
80-
"from UTF-8 to wide: %lx\n",
81-
str, ::GetLastError());
82-
}
8366

84-
return result;
67+
if (len)
68+
return result;
69+
70+
free(result);
71+
return nullptr;
8572
}
8673

8774
#endif // defined(_WIN32)

0 commit comments

Comments
 (0)