checker: check fn call argument mismatch (fix #23016) (#23061)

This commit is contained in:
yuyi 2024-12-04 17:52:07 +08:00 committed by GitHub
parent a40df55bf5
commit 17f3c8f813
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 65 additions and 42 deletions

View File

@ -46,9 +46,9 @@ jobs:
v retry brew install sassc libgit2
fi
- name: Test vtcc
if: runner.os == 'Linux'
run: .github/workflows/compile_v_with_vtcc.sh
## - name: Test vtcc
## if: runner.os == 'Linux'
## run: .github/workflows/compile_v_with_vtcc.sh
- name: Test vsql compilation and examples
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
@ -68,18 +68,18 @@ jobs:
echo "Run vsql/connection_test.v with -skip-unused"
v -skip-unused vsql/connection_test.v
- name: Test discord.v
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
run: |
echo "Clone https://github.com/DarpHome/discord.v"
v retry -- v install https://github.com/DarpHome/discord.v
cd ~/.vmodules/discord
echo "Checkout last known good commit"
git checkout 458261508af66fa971207c8af10ee4e1b59fbf2f
echo "Execute Tests"
v test .
echo "Execute Tests with -skip-unused"
v -skip-unused test .
## - name: Test discord.v
## if: ${{ !cancelled() && steps.build.outcome == 'success' }}
## run: |
## echo "Clone https://github.com/DarpHome/discord.v"
## v retry -- v install https://github.com/DarpHome/discord.v
## cd ~/.vmodules/discord
## echo "Checkout last known good commit"
## git checkout 458261508af66fa971207c8af10ee4e1b59fbf2f
## echo "Execute Tests"
## v test .
## echo "Execute Tests with -skip-unused"
## v -skip-unused test .
- name: Build vlang/vab
if: ${{ !cancelled() && steps.build.outcome == 'success' }}

View File

@ -383,7 +383,7 @@ pub fn (s string) replace(rep string, with string) string {
mut stack_idxs := [replace_stack_buffer_size]int{}
mut pidxs := unsafe { &stack_idxs[0] }
if pidxs_cap > replace_stack_buffer_size {
pidxs = unsafe { &int(malloc(sizeof(int) * pidxs_cap)) }
pidxs = unsafe { &int(malloc(int(sizeof(int)) * pidxs_cap)) }
}
defer {
if pidxs_cap > replace_stack_buffer_size {
@ -1277,7 +1277,7 @@ fn (s string) index_kmp(p string) int {
mut stack_prefixes := [kmp_stack_buffer_size]int{}
mut p_prefixes := unsafe { &stack_prefixes[0] }
if p.len > kmp_stack_buffer_size {
p_prefixes = unsafe { &int(vcalloc(p.len * sizeof(int))) }
p_prefixes = unsafe { &int(vcalloc(p.len * int(sizeof(int)))) }
}
defer {
if p.len > kmp_stack_buffer_size {

View File

@ -561,7 +561,7 @@ pub fn store_array[T](fname string, array []T, params CompressParams) ! {
fout.write(buf_out[..output.pos])!
// then, write the array.data to file
input.src = array.data
input.size = usize(array.len * sizeof(T))
input.size = usize(array.len * int(sizeof(T)))
input.pos = 0
output.dst = buf_out.data
output.size = buf_out_size

View File

@ -144,7 +144,7 @@ fn smix(mut block []u8, r u32, n u64, mut v_block []u8, mut temp_block []u8) {
}
for _ in 0 .. n {
j := binary.little_endian_u64_at(temp_block, ((2 * r) - 1) * 64) & (n - 1)
j := binary.little_endian_u64_at(temp_block, int(((2 * r) - 1) * 64)) & (n - 1)
v_start := j * (128 * r)
v_stop := v_start + (128 * r)
@ -226,7 +226,7 @@ pub fn scrypt(password []u8, salt []u8, n u64, r u32, p u32, dk_len u64) ![]u8 {
}
}
mut b := pbkdf2.key(password, salt, 1, 128 * r * p, sha256.new())!
mut b := pbkdf2.key(password, salt, 1, int(128 * r * p), sha256.new())!
mut xy := []u8{len: int(256 * r), cap: int(256 * r), init: 0}
mut v := []u8{len: int(128 * r * n), cap: int(128 * r * n), init: 0}
@ -235,7 +235,7 @@ pub fn scrypt(password []u8, salt []u8, n u64, r u32, p u32, dk_len u64) ![]u8 {
smix(mut b[i * 128 * r..], r, n, mut v, mut xy)
}
result := pbkdf2.key(password, b, 1, 128 * r * p, sha256.new())!
result := pbkdf2.key(password, b, 1, int(128 * r * p), sha256.new())!
return result[..dk_len]
}

View File

@ -692,7 +692,7 @@ pub fn executable() string {
mib := [C.CTL_KERN, C.KERN_PROC_ARGS, pid, C.KERN_PROC_ARGV]!
if unsafe { C.sysctl(&mib[0], mib.len, C.NULL, &bufsize, C.NULL, 0) } == 0 {
if bufsize > max_path_buffer_size {
pbuf = unsafe { &&u8(malloc(bufsize)) }
pbuf = unsafe { &&u8(malloc(int(bufsize))) }
defer {
unsafe { free(pbuf) }
}

View File

@ -103,7 +103,7 @@ fn internal_string_from_set(mut rng PRNG, charset string, len int) string {
mut buf := unsafe { malloc_noscan(len + 1) }
for i in 0 .. len {
unsafe {
buf[i] = charset[rng.u32() % charset.len]
buf[i] = charset[rng.u32() % u32(charset.len)]
}
}
unsafe {
@ -120,7 +120,7 @@ fn internal_fill_buffer_from_set(mut rng PRNG, charset string, mut buf []u8) {
blen := buf.len
for i in 0 .. blen {
unsafe {
buf[i] = charset[rng.u32() % charset.len]
buf[i] = charset[rng.u32() % u32(charset.len)]
}
}
}

View File

@ -469,7 +469,7 @@ pub fn (t &Table) find_enum_field_val(name string, field_ string) ?i64 {
}
}
}
return if enum_decl.is_flag { u64(1) << val } else { val }
return if enum_decl.is_flag { i64(u64(1) << u64(val)) } else { val }
}
pub fn (t &Table) get_enum_field_names(name string) []string {

View File

@ -398,7 +398,7 @@ pub fn (t Type) clear_flags(flags ...TypeFlag) Type {
if flags.len == 0 {
return t & 0xffffff
} else {
mut typ := int(t)
mut typ := u32(t)
for flag in flags {
typ = typ & ~(u32(flag))
}

View File

@ -735,8 +735,16 @@ fn (c &Checker) promote_num(left_type ast.Type, right_type ast.Type) ast.Type {
} else if idx_lo >= ast.i8_type_idx
&& (idx_hi <= ast.isize_type_idx || idx_hi == ast.rune_type_idx) { // both signed
return if idx_lo == ast.i64_type_idx { type_lo } else { type_hi }
} else if idx_hi - idx_lo < (ast.u8_type_idx - ast.i8_type_idx) {
return type_lo // conversion unsigned -> signed if signed type is larger
} else if idx_hi == ast.u8_type_idx && idx_lo > ast.i8_type_idx {
return type_lo // conversion unsigned u8 -> signed if signed type is larger
} else if idx_hi == ast.u16_type_idx && idx_lo > ast.i16_type_idx {
return type_lo // conversion unsigned u16 -> signed if signed type is larger
} else if idx_hi == ast.u32_type_idx && idx_lo > ast.int_type_idx {
return type_lo // conversion unsigned u32 -> signed if signed type is larger
} else if idx_hi == ast.u64_type_idx && idx_lo >= ast.i64_type_idx {
return type_lo // conversion unsigned u64 -> signed if signed type is larger
} else if idx_hi == ast.usize_type_idx && idx_lo >= ast.isize_type_idx {
return type_lo // conversion unsigned usize -> signed if signed type is larger
} else if c.pref.translated {
return type_hi
} else {

View File

@ -945,7 +945,7 @@ fn (mut c Checker) check_uninitialized_struct_fields_and_embeds(node ast.StructI
if mut field.default_expr is ast.StructInit {
idx := c.table.find_type(field.default_expr.typ_str)
if idx != 0 {
info.fields[i].default_expr_typ = ast.new_type(idx)
info.fields[i].default_expr_typ = ast.new_type(int(idx))
}
} else if field.default_expr.is_nil() {
if field.typ.is_any_kind_of_pointer() {

View File

@ -0,0 +1,6 @@
vlib/v/checker/tests/fn_call_arg_mismatch_err_e.vv:8:4: error: cannot use `u32` as `int` in argument 1 to `f`
6 | x := u32(2251797157)
7 | println(x)
8 | f(x)
| ^
9 | }

View File

@ -0,0 +1,9 @@
fn f(x int) {
println(x)
}
fn main() {
x := u32(2251797157)
println(x)
f(x)
}

View File

@ -11,7 +11,7 @@ __global (
)
struct GameObject {
id int = game.object_id++
id u32 = game.object_id++
}
fn (mut game Game) init() {

View File

@ -2451,7 +2451,7 @@ struct SumtypeCastingFn {
fn (mut g Gen) get_sumtype_casting_fn(got_ ast.Type, exp_ ast.Type) string {
mut got, exp := got_.idx_type(), exp_.idx_type()
i := got | int(u32(exp) << 17) | int(u32(exp_.has_flag(.option)) << 16)
i := int(got) | int(u32(exp) << 17) | int(u32(exp_.has_flag(.option)) << 16)
exp_sym := g.table.sym(exp)
mut got_sym := g.table.sym(got)
cname := if exp == ast.int_type_idx {

View File

@ -11,7 +11,7 @@ fn test_main() {
mut str := ''
if bs := byte_str(num) {
str = 'byte: ${bs}'
} else if ss := short_str(num) {
} else if ss := short_str(int(num)) {
str = 'short: ${ss}'
} else {
str = 'err: ${err}'

View File

@ -77,7 +77,7 @@ fn test_multi_return_sym() {
assert func.receiver_typ == 0
assert func.is_pub == false
typ := reflection.get_type(func.return_typ)?
typ := reflection.get_type(int(func.return_typ))?
assert typ.name == '(int, f64, string)'
assert typ.sym.mod == ''
assert typ.sym.language == .v

View File

@ -38,22 +38,22 @@ fn test_func_name() {
fn test_type_name() {
ret_typ := reflection.get_funcs().filter(it.name == 'test3')[0].return_typ
assert reflection.type_name(ret_typ) == 'void'
assert reflection.get_type(ret_typ)?.name == 'void'
assert reflection.get_type_symbol(ret_typ)?.name == 'void'
assert reflection.type_name(reflection.get_funcs().filter(it.name == 'test3')[0].args[0].typ) == 'Function'
assert reflection.type_name(int(ret_typ)) == 'void'
assert reflection.get_type(int(ret_typ))?.name == 'void'
assert reflection.get_type_symbol(int(ret_typ))?.name == 'void'
assert reflection.type_name(int(reflection.get_funcs().filter(it.name == 'test3')[0].args[0].typ)) == 'Function'
}
fn test_type_symbol() {
ret_typ := reflection.get_funcs().filter(it.name == 'test3')[0].return_typ
assert reflection.get_type_symbol(ret_typ)?.language == .v
assert reflection.get_type_symbol(int(ret_typ))?.language == .v
}
fn test_method() {
method := reflection.get_funcs().filter(it.name == 'get_name')[0]
assert reflection.type_name(method.return_typ) == 'string'
println(reflection.get_type(method.receiver_typ)?.name)
assert reflection.get_type(method.receiver_typ)?.name == 'User'
assert reflection.type_name(int(method.return_typ)) == 'string'
println(reflection.get_type(int(method.receiver_typ))?.name)
assert reflection.get_type(int(method.receiver_typ))?.name == 'User'
}
fn test_enum() {

View File

@ -586,7 +586,7 @@ fn (e &Encoder) encode_string(s string, mut buf []u8) ! {
buf << quote_rune
}
fn hex_digit(n int) u8 {
fn hex_digit(n u32) u8 {
if n < 10 {
return `0` + n
}