checker: add a check for `ptr = Abc{}`
parent
931882d720
commit
0ba5544446
|
@ -2,27 +2,41 @@ module os
|
|||
|
||||
#include <sys/stat.h> // #include <signal.h>
|
||||
#include <errno.h>
|
||||
struct C.dirent {
|
||||
d_name [256]char
|
||||
}
|
||||
|
||||
fn C.readdir(voidptr) &C.dirent
|
||||
|
||||
fn C.readdir(voidptr) C.dirent
|
||||
fn C.getpid() int
|
||||
fn C.readlink() int
|
||||
fn C.getline(voidptr, voidptr, voidptr) int
|
||||
fn C.ftell(fp voidptr) int
|
||||
fn C.sigaction(int, voidptr, int)
|
||||
fn C.open(charptr, int, int) int
|
||||
fn C.fdopen(int, string) voidptr
|
||||
fn C.CopyFile(&u32, &u32, int) int
|
||||
fn C.fork() int
|
||||
fn C.wait() int
|
||||
//fn C.proc_pidpath(int, byteptr, int) int
|
||||
|
||||
fn C.readlink() int
|
||||
|
||||
fn C.getline(voidptr, voidptr, voidptr) int
|
||||
|
||||
fn C.ftell(fp voidptr) int
|
||||
|
||||
fn C.sigaction(int, voidptr, int)
|
||||
|
||||
fn C.open(charptr, int, int) int
|
||||
|
||||
fn C.fdopen(int, string) voidptr
|
||||
|
||||
fn C.CopyFile(&u32, &u32, int) int
|
||||
|
||||
fn C.fork() int
|
||||
|
||||
fn C.wait() int
|
||||
|
||||
// fn C.proc_pidpath(int, byteptr, int) int
|
||||
struct C.stat {
|
||||
st_size int
|
||||
st_mode u32
|
||||
st_mtime int
|
||||
}
|
||||
|
||||
struct C.DIR {}
|
||||
struct C.DIR {
|
||||
}
|
||||
|
||||
struct C.sigaction {
|
||||
mut:
|
||||
|
|
|
@ -2080,8 +2080,9 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
|||
right_type_unwrapped := c.unwrap_generic(right_type)
|
||||
left_sym := c.table.get_type_symbol(left_type_unwrapped)
|
||||
right_sym := c.table.get_type_symbol(right_type_unwrapped)
|
||||
if (left_type.is_ptr() || left_sym.is_pointer()) &&
|
||||
assign_stmt.op !in [.assign, .decl_assign] && !c.inside_unsafe {
|
||||
left_is_ptr := left_type.is_ptr() || left_sym.is_pointer()
|
||||
right_is_ptr := right_type.is_ptr() || right_sym.is_pointer()
|
||||
if left_is_ptr && assign_stmt.op !in [.assign, .decl_assign] && !c.inside_unsafe {
|
||||
// ptr op=
|
||||
c.warn('pointer arithmetic is only allowed in `unsafe` blocks', assign_stmt.pos)
|
||||
}
|
||||
|
@ -2090,6 +2091,15 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
|||
// TODO replace all c.pref.translated checks with `$if !translated` for performance
|
||||
continue
|
||||
}
|
||||
if left_is_ptr && (right is ast.StructInit || !right_is_ptr) && !right_sym.is_number() {
|
||||
left_name := c.table.type_to_str(left_type_unwrapped)
|
||||
mut rtype := right_type_unwrapped
|
||||
if rtype.is_ptr() {
|
||||
rtype = rtype.deref()
|
||||
}
|
||||
right_name := c.table.type_to_str(rtype)
|
||||
c.error('mismatched types `$left_name` and `$right_name`', assign_stmt.pos)
|
||||
}
|
||||
// Single side check
|
||||
match assign_stmt.op {
|
||||
.assign {} // No need to do single side check for =. But here put it first for speed.
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
vlib/v/checker/tests/struct_assigned_to_pointer_to_struct.vv:5:4: error: mismatched types `&Foo` and `Foo`
|
||||
3 | fn main() {
|
||||
4 | mut f := &Foo{ 10 }
|
||||
5 | f = { x: 223344 }
|
||||
| ^
|
||||
6 | f = Foo{ x: 20 }
|
||||
7 | }
|
||||
vlib/v/checker/tests/struct_assigned_to_pointer_to_struct.vv:6:4: error: mismatched types `&Foo` and `Foo`
|
||||
4 | mut f := &Foo{ 10 }
|
||||
5 | f = { x: 223344 }
|
||||
6 | f = Foo{ x: 20 }
|
||||
| ^
|
||||
7 | }
|
|
@ -0,0 +1,7 @@
|
|||
struct Foo { x int }
|
||||
|
||||
fn main() {
|
||||
mut f := &Foo{ 10 }
|
||||
f = { x: 223344 }
|
||||
f = Foo{ x: 20 }
|
||||
}
|
Loading…
Reference in New Issue