diff --git a/doc/docs.md b/doc/docs.md index ebf000bc70..8bf90be855 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -2668,7 +2668,7 @@ Examples of potentially memory-unsafe operations are: To mark potentially memory-unsafe operations, enclose them in an `unsafe` block: -```v failcompile +```v wip // allocate 2 uninitialized bytes & return a reference to them mut p := unsafe { malloc(2) } p[0] = `h` // Error: pointer indexing is only allowed in `unsafe` blocks diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index fc4977c3bd..c5487c5e8e 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -4135,14 +4135,13 @@ fn (c &Checker) has_return(stmts []ast.Stmt) ?bool { pub fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) table.Type { typ := c.expr(node.expr) typ_sym := c.table.get_type_symbol(typ) - // if !typ.is_number() { - if !typ_sym.is_number() { + if !typ_sym.is_number() && typ_sym.kind !in [.byteptr, .charptr] { c.error('invalid operation: $node.op.str() (non-numeric type `$typ_sym.name`)', node.pos) } else { node.auto_locked, _ = c.fail_if_immutable(node.expr) } - if (typ.is_ptr() || typ_sym.is_pointer()) && !c.inside_unsafe { + if !c.inside_unsafe && (typ.is_ptr() || typ_sym.is_pointer()) { c.warn('pointer arithmetic is only allowed in `unsafe` blocks', node.pos) } return typ diff --git a/vlib/v/tests/ptr_arithmetic_test.v b/vlib/v/tests/ptr_arithmetic_test.v index c06cd21659..2b2075cdef 100644 --- a/vlib/v/tests/ptr_arithmetic_test.v +++ b/vlib/v/tests/ptr_arithmetic_test.v @@ -28,4 +28,7 @@ fn test_ptr_arithmetic_over_byteptr() { assert q == byteptr(9) s := unsafe { q - 1 } assert s == byteptr(8) + + unsafe {q++ q++ q--} + assert q == byteptr(10) }