1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: add int signedness mismatch checking for function call arguments (#16750)

This commit is contained in:
Felipe Pena 2022-12-24 01:28:35 -03:00 committed by GitHub
parent 0128d2dd1c
commit 6a179a2926
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 67 additions and 9 deletions

View File

@ -251,7 +251,7 @@ fn sys_close(fd i64) Errno {
}
// 9 sys_mmap
fn sys_mmap(addr &byte, len u64, prot MemProt, flags MapFlags, fildes u64, off u64) (&byte, Errno) {
fn sys_mmap(addr &byte, len u64, prot MemProt, flags MapFlags, fildes i64, off u64) (&byte, Errno) {
rc := sys_call6(9, u64(addr), len, u64(prot), u64(flags), fildes, off)
a, e := split_int_errno(rc)
return &u8(a), e
@ -409,7 +409,7 @@ fn sys_call5(scn u64, arg1 u64, arg2 u64, arg3 u64, arg4 u64, arg5 u64) u64 {
return res
}
fn sys_call6(scn u64, arg1 u64, arg2 u64, arg3 u64, arg4 u64, arg5 u64, arg6 u64) u64 {
fn sys_call6(scn u64, arg1 u64, arg2 u64, arg3 u64, arg4 u64, arg5 i64, arg6 u64) u64 {
mut res := u64(0)
asm amd64 {
mov r10, arg4

View File

@ -17,7 +17,7 @@ fn test_integer_from_u64() {
assert big.integer_from_u64(1024).hex() == '400'
assert big.integer_from_u64(4294967295).hex() == 'ffffffff'
assert big.integer_from_u64(4398046511104).hex() == '40000000000'
max_value := big.integer_from_u64(-1)
max_value := big.integer_from_u64(u64(-1))
assert max_value.hex() == 'ffffffffffffffff'
}
@ -170,7 +170,7 @@ fn test_comparison() {
fn test_conversion() {
ten := big.integer_from_int(10)
mut n := big.integer_from_u64(-1)
mut n := big.integer_from_u64(u64(-1))
mut digits := []rune{}
for n.signum != 0 {
@ -226,7 +226,7 @@ fn test_str() {
assert big.integer_from_u64(1024).str() == '1024'
assert big.integer_from_u64(4294967295).str() == '4294967295'
assert big.integer_from_u64(4398046511104).str() == '4398046511104'
assert big.integer_from_u64(-1).str() == '18446744073709551615'
assert big.integer_from_u64(u64(-1)).str() == '18446744073709551615'
assert (big.integer_from_radix('e'.repeat(80), 16) or { panic('Cannot read hexadecimal') }).str() == '1993587900192849410235353592424915306962524220866209251950572167300738410728597846688097947807470'
}

View File

@ -267,10 +267,10 @@ fn test_write_raw_at() {
fn test_write_raw_at_negative_pos() {
mut f := os.open_file(tfile, 'w')!
if _ := f.write_raw_at(another_point, -1) {
if _ := f.write_raw_at(another_point, u64(-1)) {
assert false
}
f.write_raw_at(another_point, -234) or { assert err.msg() == 'Invalid argument' }
f.write_raw_at(another_point, u64(-1)) or { assert err.msg() == 'Invalid argument' }
f.close()
}
@ -322,10 +322,10 @@ fn test_read_raw_at() {
fn test_read_raw_at_negative_pos() {
mut f := os.open_file(tfile, 'r')!
if _ := f.read_raw_at[Point](-1) {
if _ := f.read_raw_at[Point](u64(-1)) {
assert false
}
f.read_raw_at[Point](-234) or { assert err.msg() == 'Invalid argument' }
f.read_raw_at[Point](u64(-1)) or { assert err.msg() == 'Invalid argument' }
f.close()
}

View File

@ -225,6 +225,13 @@ fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, lan
return
}
}
// check int signed/unsigned mismatch
if got == ast.int_literal_type_idx && expected in ast.unsigned_integer_type_idxs
&& arg.expr is ast.IntegerLiteral && (arg.expr as ast.IntegerLiteral).val.i64() < 0 {
expected_typ_str := c.table.type_to_str(expected.clear_flag(.variadic))
return error('cannot use literal signed integer as `${expected_typ_str}`')
}
idx_got := got.idx()
idx_expected := expected.idx()
if idx_got in [ast.byteptr_type_idx, ast.charptr_type_idx]

View File

@ -0,0 +1,35 @@
vlib/v/checker/tests/int_signess_call_arg_test.vv:5:8: error: cannot use `int` as `u64` in argument 1 to `ztest`
3 | fn test_main(){
4 | a := -1
5 | ztest(a)
| ^
6 | ztest2(-1)
7 | ztest3(-1)
vlib/v/checker/tests/int_signess_call_arg_test.vv:6:9: error: cannot use literal signed integer as `u8` in argument 1 to `ztest2`
4 | a := -1
5 | ztest(a)
6 | ztest2(-1)
| ~~
7 | ztest3(-1)
8 | ztest4(-1)
vlib/v/checker/tests/int_signess_call_arg_test.vv:7:9: error: cannot use literal signed integer as `u16` in argument 1 to `ztest3`
5 | ztest(a)
6 | ztest2(-1)
7 | ztest3(-1)
| ~~
8 | ztest4(-1)
9 | ztest5(-1)
vlib/v/checker/tests/int_signess_call_arg_test.vv:8:9: error: cannot use literal signed integer as `u32` in argument 1 to `ztest4`
6 | ztest2(-1)
7 | ztest3(-1)
8 | ztest4(-1)
| ~~
9 | ztest5(-1)
10 | }
vlib/v/checker/tests/int_signess_call_arg_test.vv:9:9: error: cannot use literal signed integer as `usize` in argument 1 to `ztest5`
7 | ztest3(-1)
8 | ztest4(-1)
9 | ztest5(-1)
| ~~
10 | }
11 |

View File

@ -0,0 +1,16 @@
module main
fn test_main(){
a := -1
ztest(a)
ztest2(-1)
ztest3(-1)
ztest4(-1)
ztest5(-1)
}
fn ztest(len u64){println(len)}
fn ztest2(len u8){println(len)}
fn ztest3(len u16){println(len)}
fn ztest4(len u32){println(len)}
fn ztest5(len usize){println(len)}