checker: fix non-numeric type check for translated code

pull/13930/head
Alexander Medvednikov 2022-04-04 04:59:14 +03:00
parent d10135e2c4
commit cc227d8520
4 changed files with 20 additions and 7 deletions

View File

@ -651,7 +651,8 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
} }
return ast.bool_type return ast.bool_type
} }
.plus, .minus, .mul, .div, .mod, .xor, .amp, .pipe { // binary operators that expect matching types .plus, .minus, .mul, .div, .mod, .xor, .amp, .pipe {
// binary operators that expect matching types
if right_sym.info is ast.Alias && (right_sym.info as ast.Alias).language != .c if right_sym.info is ast.Alias && (right_sym.info as ast.Alias).language != .c
&& c.mod == c.table.type_to_str(right_type).split('.')[0] && c.mod == c.table.type_to_str(right_type).split('.')[0]
&& c.table.sym((right_sym.info as ast.Alias).parent_type).is_primitive() { && c.table.sym((right_sym.info as ast.Alias).parent_type).is_primitive() {
@ -3515,9 +3516,9 @@ pub fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type {
if !c.inside_unsafe && is_non_void_pointer && !node.expr.is_auto_deref_var() { if !c.inside_unsafe && is_non_void_pointer && !node.expr.is_auto_deref_var() {
c.warn('pointer arithmetic is only allowed in `unsafe` blocks', node.pos) c.warn('pointer arithmetic is only allowed in `unsafe` blocks', node.pos)
} }
if !(typ_sym.is_number() || (c.inside_unsafe && is_non_void_pointer)) { if !(typ_sym.is_number() || ((c.inside_unsafe || c.pref.translated) && is_non_void_pointer)) {
c.error('invalid operation: $node.op.str() (non-numeric type `$typ_sym.name`)', typ_str := c.table.type_to_str(typ)
node.pos) c.error('invalid operation: $node.op.str() (non-numeric type `$typ_str`)', node.pos)
} else { } else {
node.auto_locked, _ = c.fail_if_immutable(node.expr) node.auto_locked, _ = c.fail_if_immutable(node.expr)
} }

View File

@ -39,11 +39,18 @@ vlib/v/checker/tests/pointer_ops.vv:10:3: error: operator `-=` not defined on le
10 | p -= 3 10 | p -= 3
| ^ | ^
11 | _ = p[3] 11 | _ = p[3]
12 | } 12 | mut foo := &Foo{}
vlib/v/checker/tests/pointer_ops.vv:11:8: error: type `voidptr` does not support indexing vlib/v/checker/tests/pointer_ops.vv:11:8: error: type `voidptr` does not support indexing
9 | p-- 9 | p--
10 | p -= 3 10 | p -= 3
11 | _ = p[3] 11 | _ = p[3]
| ~~~ | ~~~
12 | } 12 | mut foo := &Foo{}
13 | } 13 | foo % 3
vlib/v/checker/tests/pointer_ops.vv:13:3: error: invalid operator `%` to `&Foo` and `int literal`
11 | _ = p[3]
12 | mut foo := &Foo{}
13 | foo % 3
| ~~~~~~~
14 | }
15 | }

View File

@ -9,5 +9,9 @@ fn test_voidptr() {
p-- p--
p -= 3 p -= 3
_ = p[3] _ = p[3]
mut foo := &Foo{}
foo % 3
} }
} }
struct Foo{}

View File

@ -41,6 +41,7 @@ const builtin_module_names = ['builtin', 'strconv', 'strings', 'dlmalloc']
pub fn module_is_builtin(mod string) bool { pub fn module_is_builtin(mod string) bool {
// NOTE: using util.builtin_module_parts here breaks -usecache on macos // NOTE: using util.builtin_module_parts here breaks -usecache on macos
return mod in util.builtin_module_names return mod in util.builtin_module_names
// return mod in util.builtin_module_parts
} }
pub fn tabs(n int) string { pub fn tabs(n int) string {