From 3702796f9d818a61a5b503161335e5b6ba613a12 Mon Sep 17 00:00:00 2001 From: kbkpbot Date: Tue, 13 Jan 2026 10:35:06 +0800 Subject: [PATCH] checker: fix global empty const type check (fix #26324) (#26332) --- vlib/v/checker/checker.v | 17 +++++++++++++++++ vlib/v/checker/tests/globals_error.out | 2 +- .../with_check_option/empty_global_const.out | 7 +++++++ .../with_check_option/empty_global_const.vv | 18 ++++++++++++++++++ vlib/v/parser/parser.v | 8 ++------ 5 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 vlib/v/checker/tests/with_check_option/empty_global_const.out create mode 100644 vlib/v/checker/tests/with_check_option/empty_global_const.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 46cab1265..4b97942e6 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -66,6 +66,7 @@ pub mut: expected_or_type ast.Type // fn() or { 'this type' } eg. string. expected or block type expected_expr_type ast.Type // if/match is_expr: expected_type mod string // current module name + has_globals_in_module bool // true if the current module has @[has_globals] attribute const_var &ast.ConstField = unsafe { nil } // the current constant, when checking const declarations const_deps []string const_names []string @@ -218,6 +219,7 @@ fn (mut c Checker) reset_checker_state_at_start_of_new_file() { c.inside_interface_deref = false c.inside_decl_rhs = false c.inside_if_guard = false + c.has_globals_in_module = false c.error_details.clear() } @@ -379,6 +381,14 @@ pub fn (mut c Checker) change_current_file(file &ast.File) { import_sym.alias } } + // Check if the current module has has_globals attribute + c.has_globals_in_module = false + for attr in file.mod.attrs { + if attr.name == 'has_globals' { + c.has_globals_in_module = true + break + } + } } pub fn (mut c Checker) check_files(ast_files []&ast.File) { @@ -2717,6 +2727,13 @@ fn (mut c Checker) branch_stmt(node ast.BranchStmt) { } fn (mut c Checker) global_decl(mut node ast.GlobalDecl) { + if !c.pref.enable_globals && !c.pref.is_fmt && !c.pref.is_vet && !c.pref.translated + && !c.pref.is_livemain && !c.pref.building_v && !c.is_builtin_mod + && !c.has_globals_in_module && !c.file.is_translated { + c.error('use `v -enable-globals ...` to enable globals', node.pos) + return + } + required_args_attr := ['_linker_section'] for attr_name in required_args_attr { if attr := node.attrs.find_first(attr_name) { diff --git a/vlib/v/checker/tests/globals_error.out b/vlib/v/checker/tests/globals_error.out index 72abeabd0..3c6983cb9 100644 --- a/vlib/v/checker/tests/globals_error.out +++ b/vlib/v/checker/tests/globals_error.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/globals_error.vv:1:1: error: use `v -enable-globals ...` to enable globals 1 | __global ( - | ~~~~~~~~ + | ~~~~~~~~~~ 2 | rfcnt int 3 | ) diff --git a/vlib/v/checker/tests/with_check_option/empty_global_const.out b/vlib/v/checker/tests/with_check_option/empty_global_const.out new file mode 100644 index 000000000..7745b26c7 --- /dev/null +++ b/vlib/v/checker/tests/with_check_option/empty_global_const.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/with_check_option/empty_global_const.vv:5:1: error: use `v -enable-globals ...` to enable globals + 3 | const buf_len = 256 + 4 | + 5 | __global not_used_in_code_but_helps_triggering = u64(-1) + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 6 | + 7 | struct Buffer { diff --git a/vlib/v/checker/tests/with_check_option/empty_global_const.vv b/vlib/v/checker/tests/with_check_option/empty_global_const.vv new file mode 100644 index 000000000..3668238cb --- /dev/null +++ b/vlib/v/checker/tests/with_check_option/empty_global_const.vv @@ -0,0 +1,18 @@ +module main + +const buf_len = 256 + +__global not_used_in_code_but_helps_triggering = u64(-1) + +struct Buffer { +mut: + data [256]u8 + pos int +} + +fn (mut buf Buffer) clear() { + buf.pos = 0 + for i in 0 .. buf_len { + buf.data[i] = 0 + } +} diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 969cc4a6c..8e712f929 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -2757,12 +2757,8 @@ fn (mut p Parser) global_decl() ast.GlobalDecl { } } - if !p.has_globals && !p.pref.enable_globals && !p.pref.is_fmt && !p.pref.is_vet - && !p.pref.translated && !p.is_translated && !p.pref.is_livemain && !p.pref.building_v - && !p.builtin_mod { - p.error('use `v -enable-globals ...` to enable globals') - return ast.GlobalDecl{} - } + // Parser always parses __global declarations correctly + // Checker will report an error if globals are not enabled start_pos := p.tok.pos() p.check(.key_global) if p.disallow_declarations_in_script_mode() { -- 2.39.5