checker: only allow passing integer *literal* to non-integer pointer method parameter (#8825)

pull/8833/head
Nick Treleaven 2021-02-19 12:14:40 +00:00 committed by GitHub
parent a153ec5951
commit bcb35e15f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 31 deletions

View File

@ -32,7 +32,7 @@ pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool {
return true return true
} }
// allow pointers to be initialized with 0. TODO: use none instead // allow pointers to be initialized with 0. TODO: use none instead
if expected.is_ptr() && got_.idx() == table.int_type_idx { if expected.is_ptr() && got_ == table.int_literal_type {
return true return true
} }
// TODO: use sym so it can be absorbed into below [.voidptr, .any] logic // TODO: use sym so it can be absorbed into below [.voidptr, .any] logic

View File

@ -5312,7 +5312,7 @@ pub fn (mut c Checker) offset_of(node ast.OffsetOf) table.Type {
c.error('first argument of __offsetof must be struct', node.pos) c.error('first argument of __offsetof must be struct', node.pos)
return table.u32_type return table.u32_type
} }
if !c.table.struct_has_field(node.struct_type, node.field) { if !c.table.struct_has_field(sym, node.field) {
c.error('struct `$sym.name` has no field called `$node.field`', node.pos) c.error('struct `$sym.name` has no field called `$node.field`', node.pos)
} }
return table.u32_type return table.u32_type

View File

@ -1,19 +1,28 @@
vlib/v/checker/tests/fn_args.vv:6:5: error: cannot use `&int` as `byte` in argument 1 to `ptr` vlib/v/checker/tests/fn_args.vv:7:5: error: cannot use `&int` as `byte` in argument 1 to `u8`
4 | 5 | fn basic() {
5 | v := 4 6 | v := 4
6 | ptr(&v) 7 | u8(&v)
| ~~ | ~~
7 | arr([5]!) 8 | arr([5]!)
8 | fun(fn(i &int){}) 9 | fun(fn(i &int){})
vlib/v/checker/tests/fn_args.vv:7:5: error: cannot use `[1]int` as `[]int` in argument 1 to `arr` vlib/v/checker/tests/fn_args.vv:8:6: error: cannot use `[1]int` as `[]int` in argument 1 to `arr`
5 | v := 4 6 | v := 4
6 | ptr(&v) 7 | u8(&v)
7 | arr([5]!) 8 | arr([5]!)
| ~~~~ | ~~~~
8 | fun(fn(i &int){}) 9 | fun(fn(i &int){})
vlib/v/checker/tests/fn_args.vv:8:5: error: cannot use `fn (&int)` as `fn (int)` in argument 1 to `fun` 10 | }
6 | ptr(&v) vlib/v/checker/tests/fn_args.vv:9:6: error: cannot use `fn (&int)` as `fn (int)` in argument 1 to `fun`
7 | arr([5]!) 7 | u8(&v)
8 | fun(fn(i &int){}) 8 | arr([5]!)
| ~~~~~~~~~~~~ 9 | fun(fn(i &int){})
| ~~~~~~~~~~~~
10 | }
11 |
Details: ``'s expected fn argument: `` is NOT a pointer, but the passed fn argument: `i` is a pointer Details: ``'s expected fn argument: `` is NOT a pointer, but the passed fn argument: `i` is a pointer
vlib/v/checker/tests/fn_args.vv:18:4: error: cannot use `int` as `&S1` in argument 1 to `f`
16 | fn ptr() {
17 | v := 4
18 | f(v)
| ^
19 | }

View File

@ -1,8 +1,19 @@
fn ptr(a byte) {} fn u8(a byte) {}
fn arr(a []int) {} fn arr(a []int) {}
fn fun(a fn(int)) {} fn fun(a fn(int)) {}
v := 4 fn basic() {
ptr(&v) v := 4
arr([5]!) u8(&v)
fun(fn(i &int){}) arr([5]!)
fun(fn(i &int){})
}
struct S1 {
}
fn f(p &S1) {}
fn ptr() {
v := 4
f(v)
}

View File

@ -1,6 +1,13 @@
vlib/v/checker/tests/method_wrong_arg_type.vv:8:4: error: cannot use `MyEnum` as `string` in argument 1 to `Sss.info` vlib/v/checker/tests/method_wrong_arg_type.vv:10:4: error: cannot use `MyEnum` as `string` in argument 1 to `Sss.info`
6 | e := MyEnum.x 8 | e := MyEnum.x
7 | s := Sss{} 9 | s := Sss{}
8 | s.info(e) 10 | s.info(e)
| ~~~~~~~ | ~~~~~~~
9 | } 11 | }
12 |
vlib/v/checker/tests/method_wrong_arg_type.vv:18:4: error: cannot use `int` as `&Sss` in argument 1 to `Sss.ptr`
16 | s := Sss{}
17 | v := 4
18 | s.ptr(v)
| ~~~~~~
19 | }

View File

@ -1,9 +1,19 @@
enum MyEnum { x y z } enum MyEnum { x y z }
pub fn (e MyEnum) str() string { return int(e).str() } pub fn (e MyEnum) str() string { return int(e).str() }
struct Sss { } struct Sss { }
fn (s Sss) info(msg string) { println(msg) } fn (s Sss) info(msg string) { println(msg) }
fn main() {
fn enum_str() {
e := MyEnum.x e := MyEnum.x
s := Sss{} s := Sss{}
s.info(e) s.info(e)
} }
fn (s Sss) ptr(p &Sss) {}
fn ptr_arg() {
s := Sss{}
v := 4
s.ptr(v)
}