Skip to content

Commit

Permalink
checker: add int signedness mismatch checking for function call argum…
Browse files Browse the repository at this point in the history
…ents (#16750)
  • Loading branch information
felipensp committed Dec 24, 2022
1 parent 0128d2d commit 6a179a2
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 9 deletions.
4 changes: 2 additions & 2 deletions vlib/builtin/linux_bare/linux_syscalls.v
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions vlib/math/big/big_test.v
Expand Up @@ -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'
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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'
}

Expand Down
8 changes: 4 additions & 4 deletions vlib/os/file_test.v
Expand Up @@ -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()
}

Expand Down Expand Up @@ -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()
}

Expand Down
7 changes: 7 additions & 0 deletions vlib/v/checker/check_types.v
Expand Up @@ -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]
Expand Down
35 changes: 35 additions & 0 deletions vlib/v/checker/tests/int_signess_call_arg_test.out
@@ -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 |
16 changes: 16 additions & 0 deletions vlib/v/checker/tests/int_signess_call_arg_test.vv
@@ -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)}

0 comments on commit 6a179a2

Please sign in to comment.