From 4b1c3d25b6b2d9c4f765b594594c88e174f625d0 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 25 Mar 2026 16:42:25 +0300 Subject: [PATCH] checker: fix undeclared c constant not being checked (fixes #15893) --- vlib/builtin/cfns.c.v | 8 ++++++++ vlib/net/http/backend_vschannel_windows.c.v | 2 ++ vlib/sync/stdatomic/1.declarations.c.v | 4 ++++ vlib/v/checker/checker.v | 5 +++++ vlib/v/checker/tests/undeclared_c_identifier_err.out | 6 ++++++ vlib/v/checker/tests/undeclared_c_identifier_err.vv | 5 +++++ vlib/v/pref/arch.c.v | 2 ++ .../array_ops_create_just_one_closure_test.c.v | 2 ++ vlib/v/tests/project_with_c_code_ct_ifs/ctimeifblock.c.v | 2 ++ 9 files changed, 36 insertions(+) create mode 100644 vlib/v/checker/tests/undeclared_c_identifier_err.out create mode 100644 vlib/v/checker/tests/undeclared_c_identifier_err.vv diff --git a/vlib/builtin/cfns.c.v b/vlib/builtin/cfns.c.v index 6de56fdaa..d4e797b2a 100644 --- a/vlib/builtin/cfns.c.v +++ b/vlib/builtin/cfns.c.v @@ -3,6 +3,14 @@ module builtin @[typedef] pub struct C.FILE {} +// Virtual C globals that are available through libc or generated C headers. +__global C.errno int +__global C.stdin &C.FILE +__global C.stdout &C.FILE +__global C.stderr &C.FILE +__global C.environ &&char +__global C._wyp &u64 + // fn C.memcpy(dest voidptr, const_src voidptr, n usize) voidptr diff --git a/vlib/net/http/backend_vschannel_windows.c.v b/vlib/net/http/backend_vschannel_windows.c.v index 88e13b930..c6ea57b71 100644 --- a/vlib/net/http/backend_vschannel_windows.c.v +++ b/vlib/net/http/backend_vschannel_windows.c.v @@ -9,6 +9,8 @@ module http pub struct C.TlsContext {} +const C.vsc_init_resp_buff_size int + fn C.new_tls_context() C.TlsContext fn vschannel_ssl_do(req &Request, port int, method Method, host_name string, path string) !Response { diff --git a/vlib/sync/stdatomic/1.declarations.c.v b/vlib/sync/stdatomic/1.declarations.c.v index 293845e52..9a8760c21 100644 --- a/vlib/sync/stdatomic/1.declarations.c.v +++ b/vlib/sync/stdatomic/1.declarations.c.v @@ -112,6 +112,10 @@ fn C.atomic_fetch_sub_u64(voidptr, u64) u64 fn C.atomic_thread_fence(i32) fn C.cpu_relax() +pub const C.memory_order_relaxed i32 +pub const C.memory_order_acquire i32 +pub const C.memory_order_release i32 + fn C.ANNOTATE_RWLOCK_CREATE(voidptr) fn C.ANNOTATE_RWLOCK_ACQUIRED(voidptr, i32) fn C.ANNOTATE_RWLOCK_RELEASED(voidptr, i32) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 2483d1b05..cf1184eef 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -5820,6 +5820,11 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type { if x := c.table.global_scope.find_const(node.name) { return x.typ } + c_name := node.name.all_after('C.') + if !c.pref.translated && !c.file.is_translated && c_name.to_upper() != c_name { + c.error('undefined C identifier: `${node.name}`', node.pos) + return ast.int_type + } return ast.int_type } if c.inside_sql { diff --git a/vlib/v/checker/tests/undeclared_c_identifier_err.out b/vlib/v/checker/tests/undeclared_c_identifier_err.out new file mode 100644 index 000000000..e8ce73d37 --- /dev/null +++ b/vlib/v/checker/tests/undeclared_c_identifier_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/undeclared_c_identifier_err.vv:4:12: error: undefined C identifier: `C.errono` + 2 | + 3 | fn main() { + 4 | println(C.errono) + | ~~~~~~ + 5 | } diff --git a/vlib/v/checker/tests/undeclared_c_identifier_err.vv b/vlib/v/checker/tests/undeclared_c_identifier_err.vv new file mode 100644 index 000000000..e17f21819 --- /dev/null +++ b/vlib/v/checker/tests/undeclared_c_identifier_err.vv @@ -0,0 +1,5 @@ +#include + +fn main() { + println(C.errono) +} diff --git a/vlib/v/pref/arch.c.v b/vlib/v/pref/arch.c.v index 19610d28c..38f2ee7bd 100644 --- a/vlib/v/pref/arch.c.v +++ b/vlib/v/pref/arch.c.v @@ -1,5 +1,7 @@ module pref +const C.__V_architecture int + pub enum Arch { _auto amd64 // aka x86_64 diff --git a/vlib/v/tests/builtin_arrays/array_ops_create_just_one_closure_test.c.v b/vlib/v/tests/builtin_arrays/array_ops_create_just_one_closure_test.c.v index 470377605..aa3a84109 100644 --- a/vlib/v/tests/builtin_arrays/array_ops_create_just_one_closure_test.c.v +++ b/vlib/v/tests/builtin_arrays/array_ops_create_just_one_closure_test.c.v @@ -2,6 +2,8 @@ struct C.builtin__closure__Closure { closure_cap int } +__global C.g_closure voidptr + fn setup(fname string) (int, int, []int) { println(fname) return unsafe { &C.builtin__closure__Closure(voidptr(&C.g_closure)).closure_cap }, 42, []int{len: 5, init: index * 5} diff --git a/vlib/v/tests/project_with_c_code_ct_ifs/ctimeifblock.c.v b/vlib/v/tests/project_with_c_code_ct_ifs/ctimeifblock.c.v index e29362e80..cfe964af4 100644 --- a/vlib/v/tests/project_with_c_code_ct_ifs/ctimeifblock.c.v +++ b/vlib/v/tests/project_with_c_code_ct_ifs/ctimeifblock.c.v @@ -6,6 +6,8 @@ $if !linux { #include "@VMODROOT/a_nonlinux.h" } +__global C.version &char + fn main() { C.printf(c'a: %s\n', C.version) } -- 2.39.5