Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

checker: fix private symbol visibility checking #23543

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion vlib/builtin/cfns.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,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

Expand Down
2 changes: 1 addition & 1 deletion vlib/builtin/int.v
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion vlib/builtin/js/int.js.v
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
2 changes: 1 addition & 1 deletion vlib/builtin/wasm/wasi/int.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module builtin

type byte = u8
pub type byte = u8

// type i32 = int

Expand Down
2 changes: 1 addition & 1 deletion vlib/compress/szip/szip.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion vlib/encoding/csv/csv_reader_random_access.v
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions vlib/v/ast/table.v
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
105 changes: 65 additions & 40 deletions vlib/v/ast/types.v
Original file line number Diff line number Diff line change
Expand Up @@ -1051,61 +1051,86 @@ 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: .float_literal
name: 'float literal'
cname: 'float_literal'
mod: 'builtin'
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'
kind: .int_literal
name: 'int literal'
cname: 'int_literal'
mod: 'builtin'
is_pub: true
) // 28
t.register_sym(
kind: .thread
name: 'thread'
cname: '__v_thread'
mod: 'builtin'
info: Thread{
kind: .thread
name: 'thread'
cname: '__v_thread'
mod: 'builtin'
info: Thread{
return_type: void_type
}
is_pub: true
) // 29
t.register_sym(
kind: .interface
name: 'IError'
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]
Expand Down
25 changes: 21 additions & 4 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -5293,10 +5293,27 @@ 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}`',
pos)
return false
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 {
Expand Down
23 changes: 23 additions & 0 deletions vlib/v/checker/tests/modules/private_symbol.out
Original file line number Diff line number Diff line change
@@ -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)
19 changes: 19 additions & 0 deletions vlib/v/checker/tests/modules/private_symbol/main.v
Original file line number Diff line number Diff line change
@@ -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)
}
12 changes: 12 additions & 0 deletions vlib/v/checker/tests/modules/private_symbol/priv_sym.v
Original file line number Diff line number Diff line change
@@ -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() {
}
2 changes: 1 addition & 1 deletion vlib/x/templating/dtm/dynamic_template_manager.v
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading