checker: disallow op= and infix on a voidptr (#7175)

pull/7189/head
Nick Treleaven 2020-12-07 20:43:38 +00:00 committed by GitHub
parent ed9aa873c1
commit 63557d0d02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 68 additions and 10 deletions

View File

@ -167,7 +167,7 @@ jobs:
- name: Fixed tests
run: VJOBS=1 ./v -silent test-fixed
- name: Build examples
run: ./v -silent build-examples
run: ./v build-examples
- name: Build examples with -autofree
run: |
./v -autofree -o tetris examples/tetris/tetris.v
@ -231,7 +231,7 @@ jobs:
- name: Fixed tests (-prod)
run: ./v -o vprod -prod cmd/v && ./vprod -silent test-fixed
- name: Build examples
run: ./v -silent build-examples
run: ./v build-examples
- name: Build examples with -autofree
run: |
./v -autofree -experimental -o tetris examples/tetris/tetris.v

View File

@ -30,7 +30,7 @@ fn main() {
checksum = 0
for len in str_lens {
end_pos := start_pos + len
checksum ^= wyhash.wyhash_c(unsafe { bytepile.data + start_pos }, u64(len), 1)
checksum ^= wyhash.wyhash_c(unsafe { byteptr(bytepile.data) + start_pos }, u64(len), 1)
start_pos = end_pos
}
bhashing_1.measure('wyhash.wyhash_c | checksum: ${checksum:22}')

View File

@ -46,7 +46,7 @@ pub fn (mut ctx Context) run() ? {
// TODO: remove
fn (mut ctx Context) shift(len int) {
unsafe {
C.memmove(ctx.read_buf.data, ctx.read_buf.data + len, ctx.read_buf.cap - len)
C.memmove(ctx.read_buf.data, byteptr(ctx.read_buf.data) + len, ctx.read_buf.cap - len)
ctx.resize_arr(ctx.read_buf.len - len)
}
}

View File

@ -221,7 +221,7 @@ fn (mut ctx Context) termios_loop() {
sw.restart()
if ctx.cfg.event_fn != voidptr(0) {
unsafe {
len := C.read(C.STDIN_FILENO, ctx.read_buf.data + ctx.read_buf.len, ctx.read_buf.cap - ctx.read_buf.len)
len := C.read(C.STDIN_FILENO, byteptr(ctx.read_buf.data) + ctx.read_buf.len, ctx.read_buf.cap - ctx.read_buf.len)
ctx.resize_arr(ctx.read_buf.len + len)
}
if ctx.read_buf.len > 0 {

View File

@ -627,9 +627,13 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
mut left := c.table.get_type_symbol(left_type)
left_pos := infix_expr.left.position()
right_pos := infix_expr.right.position()
if (left_type.is_ptr() || left.is_pointer()) &&
infix_expr.op in [.plus, .minus] && !c.inside_unsafe {
c.warn('pointer arithmetic is only allowed in `unsafe` blocks', left_pos)
if (left_type.is_ptr() || left.is_pointer()) && infix_expr.op in [.plus, .minus] {
if !c.inside_unsafe {
c.warn('pointer arithmetic is only allowed in `unsafe` blocks', left_pos)
}
if left_type == table.voidptr_type {
c.error('`$infix_expr.op` cannot be used with `voidptr`', left_pos)
}
}
mut return_type := left_type
if infix_expr.op != .key_is {
@ -2228,10 +2232,10 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
c.error('invalid right operand: $left_sym.name $assign_stmt.op $right_sym.name',
right.position())
}
} else if !left_sym.is_number() && !left_sym.is_pointer() {
} else if !left_sym.is_number() && left_sym.kind !in [.byteptr, .charptr] {
c.error('operator `$assign_stmt.op` not defined on left operand type `$left_sym.name`',
left.position())
} else if !right_sym.is_number() && !right_sym.is_pointer() {
} else if !right_sym.is_number() && left_sym.kind !in [.byteptr, .charptr] {
c.error('invalid right operand: $left_sym.name $assign_stmt.op $right_sym.name',
right.position())
} else if right is ast.IntegerLiteral {

View File

@ -0,0 +1,42 @@
vlib/v/checker/tests/pointer_ops.vv:5:7: error: `+` cannot be used with `voidptr`
3 | unsafe {
4 | mut p := voidptr(0)
5 | _ = p + 1
| ^
6 | p++
7 | p += 3
vlib/v/checker/tests/pointer_ops.vv:6:4: error: invalid operation: ++ (non-numeric type `voidptr`)
4 | mut p := voidptr(0)
5 | _ = p + 1
6 | p++
| ~~
7 | p += 3
8 | _ = p - 1
vlib/v/checker/tests/pointer_ops.vv:7:3: error: operator `+=` not defined on left operand type `voidptr`
5 | _ = p + 1
6 | p++
7 | p += 3
| ^
8 | _ = p - 1
9 | p--
vlib/v/checker/tests/pointer_ops.vv:8:7: error: `-` cannot be used with `voidptr`
6 | p++
7 | p += 3
8 | _ = p - 1
| ^
9 | p--
10 | p -= 3
vlib/v/checker/tests/pointer_ops.vv:9:4: error: invalid operation: -- (non-numeric type `voidptr`)
7 | p += 3
8 | _ = p - 1
9 | p--
| ~~
10 | p -= 3
11 | }
vlib/v/checker/tests/pointer_ops.vv:10:3: error: operator `-=` not defined on left operand type `voidptr`
8 | _ = p - 1
9 | p--
10 | p -= 3
| ^
11 | }
12 | }

View File

@ -0,0 +1,12 @@
// void* arithmetic is not allowed in MSVC, so ban it
fn test_voidptr() {
unsafe {
mut p := voidptr(0)
_ = p + 1
p++
p += 3
_ = p - 1
p--
p -= 3
}
}