checker: fix private symbol visibility checking (fix #23518) (#23543)

This commit is contained in:
Felipe Pena 2025-01-27 06:42:27 -03:00 committed by GitHub
parent 1eaa7c81fa
commit c2e436518b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 148 additions and 51 deletions

View File

@ -236,7 +236,7 @@ fn C.sysctl(name &int, namelen u32, oldp voidptr, oldlenp voidptr, newp voidptr,
@[trusted]
fn C._fileno(int) int
type C.intptr_t = voidptr
pub type C.intptr_t = voidptr
fn C._get_osfhandle(fd int) C.intptr_t

View File

@ -7,7 +7,7 @@ pub struct VContext {
allocator int
}
type byte = u8
pub type byte = u8
// ptr_str returns the address of `ptr` as a `string`.
pub fn ptr_str(ptr voidptr) string {

View File

@ -1,6 +1,6 @@
module builtin
type byte = u8
pub type byte = u8
pub const min_i8 = i8(-128)
pub const max_i8 = i8(127)

View File

@ -1,6 +1,6 @@
module builtin
type byte = u8
pub type byte = u8
// type i32 = int

View File

@ -14,7 +14,7 @@ pub:
pub struct C.zip_t {
}
type Zip = C.zip_t
pub type Zip = C.zip_t
pub type Fn_on_extract_entry = fn (&&char, &&char) int

View File

@ -421,7 +421,7 @@ pub fn (mut cr RandomAccessReader) get_cell(cfg GetCellConfig) !string {
return cr.default_cell
}
type CellValue = f32 | int | string
pub type CellValue = f32 | int | string
// get_cellt read a single cell and return a sum type CellValue
pub fn (mut cr RandomAccessReader) get_cellt(cfg GetCellConfig) !CellValue {

View File

@ -1337,6 +1337,7 @@ pub fn (mut t Table) add_placeholder_type(name string, language Language) int {
cname: util.no_dots(name).replace_each(['&', ''])
language: language
mod: modname
is_pub: true
is_builtin: name in builtins
}
return t.register_sym(ph_type)

View File

@ -1051,43 +1051,66 @@ pub fn (mut t Table) register_builtin_type_symbols() {
// save index check, 0 will mean not found
// THE ORDER MUST BE THE SAME AS xxx_type_idx CONSTS EARLIER IN THIS FILE
t.register_sym(kind: .placeholder, name: 'reserved_0')
t.register_sym(kind: .void, name: 'void', cname: 'void', mod: 'builtin') // 1
t.register_sym(kind: .voidptr, name: 'voidptr', cname: 'voidptr', mod: 'builtin') // 2
t.register_sym(kind: .byteptr, name: 'byteptr', cname: 'byteptr', mod: 'builtin') // 3
t.register_sym(kind: .charptr, name: 'charptr', cname: 'charptr', mod: 'builtin') // 4
t.register_sym(kind: .i8, name: 'i8', cname: 'i8', mod: 'builtin') // 5
t.register_sym(kind: .i16, name: 'i16', cname: 'i16', mod: 'builtin') // 6
t.register_sym(kind: .i32, name: 'i32', cname: 'i32', mod: 'builtin') // 7
t.register_sym(kind: .int, name: 'int', cname: int_type_name, mod: 'builtin') // 8
t.register_sym(kind: .i64, name: 'i64', cname: 'i64', mod: 'builtin') // 9
t.register_sym(kind: .isize, name: 'isize', cname: 'isize', mod: 'builtin') // 10
t.register_sym(kind: .u8, name: 'u8', cname: 'u8', mod: 'builtin') // 11
t.register_sym(kind: .u16, name: 'u16', cname: 'u16', mod: 'builtin') // 12
t.register_sym(kind: .u32, name: 'u32', cname: 'u32', mod: 'builtin') // 13
t.register_sym(kind: .u64, name: 'u64', cname: 'u64', mod: 'builtin') // 14
t.register_sym(kind: .usize, name: 'usize', cname: 'usize', mod: 'builtin') // 15
t.register_sym(kind: .f32, name: 'f32', cname: 'f32', mod: 'builtin') // 16
t.register_sym(kind: .f64, name: 'f64', cname: 'f64', mod: 'builtin') // 17
t.register_sym(kind: .char, name: 'char', cname: 'char', mod: 'builtin') // 18
t.register_sym(kind: .bool, name: 'bool', cname: 'bool', mod: 'builtin') // 19
t.register_sym(kind: .none, name: 'none', cname: 'none', mod: 'builtin') // 20
t.register_sym(kind: .string, name: 'string', cname: 'string', mod: 'builtin', is_builtin: true) // 21
t.register_sym(kind: .rune, name: 'rune', cname: 'rune', mod: 'builtin') // 22
t.register_sym(kind: .array, name: 'array', cname: 'array', mod: 'builtin', is_builtin: true) // 23
t.register_sym(kind: .map, name: 'map', cname: 'map', mod: 'builtin', is_builtin: true) // 24
t.register_sym(kind: .chan, name: 'chan', cname: 'chan', mod: 'builtin') // 25
t.register_sym(kind: .any, name: 'any', cname: 'any', mod: 'builtin') // 26
t.register_sym(kind: .void, name: 'void', cname: 'void', mod: 'builtin', is_pub: true) // 1
t.register_sym(kind: .voidptr, name: 'voidptr', cname: 'voidptr', mod: 'builtin', is_pub: true) // 2
t.register_sym(kind: .byteptr, name: 'byteptr', cname: 'byteptr', mod: 'builtin', is_pub: true) // 3
t.register_sym(kind: .charptr, name: 'charptr', cname: 'charptr', mod: 'builtin', is_pub: true) // 4
t.register_sym(kind: .i8, name: 'i8', cname: 'i8', mod: 'builtin', is_pub: true) // 5
t.register_sym(kind: .i16, name: 'i16', cname: 'i16', mod: 'builtin', is_pub: true) // 6
t.register_sym(kind: .i32, name: 'i32', cname: 'i32', mod: 'builtin', is_pub: true) // 7
t.register_sym(kind: .int, name: 'int', cname: int_type_name, mod: 'builtin', is_pub: true) // 8
t.register_sym(kind: .i64, name: 'i64', cname: 'i64', mod: 'builtin', is_pub: true) // 9
t.register_sym(kind: .isize, name: 'isize', cname: 'isize', mod: 'builtin', is_pub: true) // 10
t.register_sym(kind: .u8, name: 'u8', cname: 'u8', mod: 'builtin', is_pub: true) // 11
t.register_sym(kind: .u16, name: 'u16', cname: 'u16', mod: 'builtin', is_pub: true) // 12
t.register_sym(kind: .u32, name: 'u32', cname: 'u32', mod: 'builtin', is_pub: true) // 13
t.register_sym(kind: .u64, name: 'u64', cname: 'u64', mod: 'builtin', is_pub: true) // 14
t.register_sym(kind: .usize, name: 'usize', cname: 'usize', mod: 'builtin', is_pub: true) // 15
t.register_sym(kind: .f32, name: 'f32', cname: 'f32', mod: 'builtin', is_pub: true) // 16
t.register_sym(kind: .f64, name: 'f64', cname: 'f64', mod: 'builtin', is_pub: true) // 17
t.register_sym(kind: .char, name: 'char', cname: 'char', mod: 'builtin', is_pub: true) // 18
t.register_sym(kind: .bool, name: 'bool', cname: 'bool', mod: 'builtin', is_pub: true) // 19
t.register_sym(kind: .none, name: 'none', cname: 'none', mod: 'builtin', is_pub: true) // 20
t.register_sym(
kind: .string
name: 'string'
cname: 'string'
mod: 'builtin'
is_builtin: true
is_pub: true
) // 21
t.register_sym(kind: .rune, name: 'rune', cname: 'rune', mod: 'builtin', is_pub: true) // 22
t.register_sym(
kind: .array
name: 'array'
cname: 'array'
mod: 'builtin'
is_builtin: true
is_pub: true
) // 23
t.register_sym(
kind: .map
name: 'map'
cname: 'map'
mod: 'builtin'
is_builtin: true
is_pub: true
) // 24
t.register_sym(kind: .chan, name: 'chan', cname: 'chan', mod: 'builtin', is_pub: true) // 25
t.register_sym(kind: .any, name: 'any', cname: 'any', mod: 'builtin', is_pub: true) // 26
t.register_sym(
kind: .float_literal
name: 'float literal'
cname: 'float_literal'
mod: 'builtin'
is_pub: true
) // 27
t.register_sym(
kind: .int_literal
name: 'int literal'
cname: 'int_literal'
mod: 'builtin'
is_pub: true
) // 28
t.register_sym(
kind: .thread
@ -1097,6 +1120,7 @@ pub fn (mut t Table) register_builtin_type_symbols() {
info: Thread{
return_type: void_type
}
is_pub: true
) // 29
t.register_sym(
kind: .interface
@ -1104,8 +1128,9 @@ pub fn (mut t Table) register_builtin_type_symbols() {
cname: 'IError'
mod: 'builtin'
is_builtin: true
is_pub: true
) // 30
t.register_sym(kind: .voidptr, name: 'nil', cname: 'voidptr', mod: 'builtin') // 31
t.register_sym(kind: .voidptr, name: 'nil', cname: 'voidptr', mod: 'builtin', is_pub: true) // 31
}
@[inline]

View File

@ -5293,11 +5293,28 @@ fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Pos) bool {
return false
}
sym := c.table.sym(typ)
if !c.is_builtin_mod && sym.kind == .struct && !sym.is_pub && sym.mod != c.mod {
c.error('struct `${sym.name}` was declared as private to module `${sym.mod}`, so it can not be used inside module `${c.mod}`',
if !c.is_builtin_mod && !sym.is_pub && sym.mod != c.mod && sym.mod != 'main' {
if sym.kind == .function {
fn_info := sym.info as ast.FnType
// hack: recover fn mod from func name
mut fn_mod := sym.mod
if fn_mod == '' {
fn_mod = fn_info.func.name.all_before_last('.')
if fn_mod == fn_info.func.name {
fn_mod = 'builtin'
}
}
if fn_mod != '' && fn_mod != c.mod && fn_info.func.name != '' && !fn_info.is_anon {
c.error('function type `${fn_info.func.name}` was declared as private to module `${fn_mod}`, so it can not be used inside module `${c.mod}`',
pos)
return false
}
} else if sym.mod != '' {
c.error('${sym.kind} `${sym.name}` was declared as private to module `${sym.mod}`, so it can not be used inside module `${c.mod}`',
pos)
return false
}
}
match sym.kind {
.placeholder {
// if sym.language == .c && sym.name == 'C.time_t' {

View File

@ -0,0 +1,23 @@
vlib/v/checker/tests/modules/private_symbol/main.v:10:11: error: function `priv_sym.priv` is private
8 |
9 | fn main() {
10 | priv_sym.priv()
| ~~~~~~
11 | a := priv_sym.Foo(0)
12 | dump(a)
vlib/v/checker/tests/modules/private_symbol/main.v:11:16: error: unknown type `priv_sym.Foo`.
Did you mean `priv_sym.PubFoo`?
9 | fn main() {
10 | priv_sym.priv()
11 | a := priv_sym.Foo(0)
| ~~~~~~
12 | dump(a)
13 | b := priv_sym.BarFn(t)
vlib/v/checker/tests/modules/private_symbol/main.v:13:16: error: unknown type `priv_sym.BarFn`.
Did you mean `priv_sym.PubFoo`?
11 | a := priv_sym.Foo(0)
12 | dump(a)
13 | b := priv_sym.BarFn(t)
| ~~~~~~~~
14 | dump(b)
15 | c := priv_sym.PubFoo(0)

View File

@ -0,0 +1,19 @@
module main
import priv_sym
fn t() int {
return 0
}
fn main() {
priv_sym.priv()
a := priv_sym.Foo(0)
dump(a)
b := priv_sym.BarFn(t)
dump(b)
c := priv_sym.PubFoo(0)
dump(c)
d := priv_sym.PubBarFn(t)
dump(d)
}

View File

@ -0,0 +1,12 @@
// sub module
module priv_sym
type PrivFoo = int
pub type PubFoo = int
type PrivBarFn = fn () int
pub type PubBarFn = fn () int
fn priv() {
}

View File

@ -7,7 +7,7 @@ import time
import regex
// These are all the types of dynamic values that the DTM allows to be returned in the context of a map
type DtmMultiTypeMap = f32 | f64 | i16 | i64 | i8 | int | string | u16 | u32 | u64 | u8
pub type DtmMultiTypeMap = f32 | f64 | i16 | i64 | i8 | int | string | u16 | u32 | u64 | u8
// type MiddlewareFn = fn (mut Context, string) bool