Skip to content

Commit 229fc6e

Browse files
authored
v3: keep refined C extern redeclarations in the signature tables (#27978)
1 parent 432da69 commit 229fc6e

1 file changed

Lines changed: 22 additions & 6 deletions

File tree

vlib/v3/types/checker.v

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5189,10 +5189,19 @@ fn (mut tc TypeChecker) register_fn_signature(name string, ret_type Type, params
51895189

51905190
// register_fn_name_alias updates register fn name alias state for types.
51915191
fn (mut tc TypeChecker) register_fn_name_alias(name string, ret_type Type, params []Type, shared_params []bool, is_variadic bool, implicit_veb_ctx bool) {
5192-
if owner_module := tc.fn_type_modules[name] {
5193-
if owner_module != tc.cur_module && tc.cur_module !in ['', 'main', 'builtin']
5194-
&& !name.starts_with('${tc.cur_module}.') {
5195-
return
5192+
// C externs live in one global namespace and modules routinely redeclare
5193+
// them with refined types (builtin: `C.pthread_join(thread voidptr, ...)`,
5194+
// v3.workers: `C.pthread_join(thread C.pthread_t, ...)`). The
5195+
// first-registration guard below must not drop those refinements: cgen's
5196+
// module-blind parameter lookup would then see `voidptr` and take the
5197+
// address of struct-typed handles (gen-2 compilers panicked with
5198+
// `failed to join compiler worker 0`).
5199+
if !name.starts_with('C.') {
5200+
if owner_module := tc.fn_type_modules[name] {
5201+
if owner_module != tc.cur_module && tc.cur_module !in ['', 'main', 'builtin']
5202+
&& !name.starts_with('${tc.cur_module}.') {
5203+
return
5204+
}
51965205
}
51975206
}
51985207
tc.fn_ret_types[name] = ret_type
@@ -5204,8 +5213,15 @@ fn (mut tc TypeChecker) register_fn_name_alias(name string, ret_type Type, param
52045213
tc.fn_shared_params.delete(name)
52055214
}
52065215
if tc.cur_file.len > 0 {
5207-
tc.fn_type_files[name] = tc.cur_file
5208-
tc.fn_type_modules[name] = tc.cur_module
5216+
// A refined C-extern redeclaration updates the signature tables above
5217+
// but must not steal ownership: is_builtin_unsafe_c_call keys the
5218+
// unsafe-block requirement for the C.m*/C.s* memory externs off the
5219+
// builtin owner, so a module redeclaring C.malloc (json does) would
5220+
// otherwise suppress that diagnostic program-wide.
5221+
if !name.starts_with('C.') || name !in tc.fn_type_modules {
5222+
tc.fn_type_files[name] = tc.cur_file
5223+
tc.fn_type_modules[name] = tc.cur_module
5224+
}
52095225
}
52105226
tc.fn_variadic[name] = is_variadic
52115227
if implicit_veb_ctx || tc.fn_implicit_veb_ctx.len > 0 {

0 commit comments

Comments
 (0)