Skip to content

Commit 013ada1

Browse files
LemonBoyandrewrk
authored andcommitted
std: More type checks for Thread startFn return type
Closes #4756
1 parent dbde5df commit 013ada1

File tree

1 file changed

+45
-6
lines changed

1 file changed

+45
-6
lines changed

lib/std/thread.zig

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ const windows = std.os.windows;
66
const c = std.c;
77
const assert = std.debug.assert;
88

9+
const bad_startfn_ret = "expected return type of startFn to be 'u8', 'noreturn', 'void', or '!void'";
10+
911
pub const Thread = struct {
1012
data: Data,
1113

@@ -158,15 +160,34 @@ pub const Thread = struct {
158160
};
159161
fn threadMain(raw_arg: windows.LPVOID) callconv(.C) windows.DWORD {
160162
const arg = if (@sizeOf(Context) == 0) {} else @ptrCast(*Context, @alignCast(@alignOf(Context), raw_arg)).*;
163+
161164
switch (@typeInfo(@TypeOf(startFn).ReturnType)) {
162-
.Int => {
163-
return startFn(arg);
165+
.NoReturn => {
166+
startFn(arg);
164167
},
165168
.Void => {
166169
startFn(arg);
167170
return 0;
168171
},
169-
else => @compileError("expected return type of startFn to be 'u8', 'noreturn', 'void', or '!void'"),
172+
.Int => |info| {
173+
if (info.bits != 8) {
174+
@compileError(bad_startfn_ret);
175+
}
176+
return startFn(arg);
177+
},
178+
.ErrorUnion => |info| {
179+
if (info.payload != void) {
180+
@compileError(bad_startfn_ret);
181+
}
182+
startFn(arg) catch |err| {
183+
std.debug.warn("error: {}\n", .{@errorName(err)});
184+
if (@errorReturnTrace()) |trace| {
185+
std.debug.dumpStackTrace(trace.*);
186+
}
187+
};
188+
return 0;
189+
},
190+
else => @compileError(bad_startfn_ret),
170191
}
171192
}
172193
};
@@ -202,14 +223,32 @@ pub const Thread = struct {
202223
const arg = if (@sizeOf(Context) == 0) {} else @intToPtr(*const Context, ctx_addr).*;
203224

204225
switch (@typeInfo(@TypeOf(startFn).ReturnType)) {
205-
.Int => {
206-
return startFn(arg);
226+
.NoReturn => {
227+
startFn(arg);
207228
},
208229
.Void => {
209230
startFn(arg);
210231
return 0;
211232
},
212-
else => @compileError("expected return type of startFn to be 'u8', 'noreturn', 'void', or '!void'"),
233+
.Int => |info| {
234+
if (info.bits != 8) {
235+
@compileError(bad_startfn_ret);
236+
}
237+
return startFn(arg);
238+
},
239+
.ErrorUnion => |info| {
240+
if (info.payload != void) {
241+
@compileError(bad_startfn_ret);
242+
}
243+
startFn(arg) catch |err| {
244+
std.debug.warn("error: {}\n", .{@errorName(err)});
245+
if (@errorReturnTrace()) |trace| {
246+
std.debug.dumpStackTrace(trace.*);
247+
}
248+
};
249+
return 0;
250+
},
251+
else => @compileError(bad_startfn_ret),
213252
}
214253
}
215254
fn posixThreadMain(ctx: ?*c_void) callconv(.C) ?*c_void {

0 commit comments

Comments
 (0)