Skip to content

Commit

Permalink
parser,checker: silence more warnings for @[translated] files (#20964)
Browse files Browse the repository at this point in the history
  • Loading branch information
spytheman committed Mar 7, 2024
1 parent db252d0 commit a867ed6
Show file tree
Hide file tree
Showing 25 changed files with 157 additions and 19 deletions.
4 changes: 3 additions & 1 deletion vlib/v/checker/assign.v
Expand Up @@ -606,7 +606,9 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
if left_type.is_any_kind_of_pointer() && !left.is_auto_deref_var() {
if !c.inside_unsafe && node.op !in [.assign, .decl_assign] {
// ptr op=
c.warn('pointer arithmetic is only allowed in `unsafe` blocks', node.pos)
if !c.pref.translated && !c.file.is_translated {
c.warn('pointer arithmetic is only allowed in `unsafe` blocks', node.pos)
}
}
right_is_ptr := right_type.is_any_kind_of_pointer()
if !right_is_ptr && node.op == .assign && right_type_unwrapped.is_number() {
Expand Down
25 changes: 18 additions & 7 deletions vlib/v/checker/checker.v
Expand Up @@ -273,7 +273,9 @@ pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) {
match obj {
ast.Var {
if !obj.is_used && obj.name[0] != `_` {
c.warn('unused variable: `${obj.name}`', obj.pos)
if !c.pref.translated && !c.file.is_translated {
c.warn('unused variable: `${obj.name}`', obj.pos)
}
}
if obj.is_mut && !obj.is_changed && !c.is_builtin_mod && obj.name != 'it' {
// if obj.is_mut && !obj.is_changed && !c.is_builtin { //TODO C error bad field not checked
Expand Down Expand Up @@ -1561,8 +1563,10 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
if !c.inside_unsafe {
if sym.info is ast.Struct {
if sym.info.is_union && node.next_token !in token.assign_tokens {
c.warn('reading a union field (or its address) requires `unsafe`',
node.pos)
if !c.pref.translated && !c.file.is_translated {
c.warn('reading a union field (or its address) requires `unsafe`',
node.pos)
}
}
}
}
Expand Down Expand Up @@ -3202,7 +3206,9 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
tt := c.table.type_to_str(to_type)
c.warn('casting `${ft}` to `${tt}` is only allowed in `unsafe` code', node.pos)
} else if from_sym.kind == .array_fixed && !from_type.is_ptr() {
c.warn('cannot cast a fixed array (use e.g. `&arr[0]` instead)', node.pos)
if !c.pref.translated && !c.file.is_translated {
c.warn('cannot cast a fixed array (use e.g. `&arr[0]` instead)', node.pos)
}
} else if final_from_sym.kind == .string && final_to_sym.is_number()
&& final_to_sym.kind != .rune {
snexpr := node.expr.str()
Expand Down Expand Up @@ -4841,8 +4847,10 @@ fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Pos) bool {
pos)
return false
} else if sym.language == .c {
c.warn(util.new_suggestion(sym.name, c.table.known_type_names()).say('unknown type `${sym.name}` (all virtual C types must be defined, this will be an error soon)'),
pos)
if !c.pref.translated && !c.file.is_translated {
c.warn(util.new_suggestion(sym.name, c.table.known_type_names()).say('unknown type `${sym.name}` (all virtual C types must be defined, this will be an error soon)'),
pos)
}
// dump(sym)
// for _, t in c.table.type_symbols {
// println(t.name)
Expand Down Expand Up @@ -5011,7 +5019,10 @@ fn (mut c Checker) goto_stmt(node ast.GotoStmt) {
c.error('goto is not allowed in defer statements', node.pos)
}
if !c.inside_unsafe {
c.warn('`goto` requires `unsafe` (consider using labelled break/continue)', node.pos)
if !c.pref.translated && !c.file.is_translated {
c.warn('`goto` requires `unsafe` (consider using labelled break/continue)',
node.pos)
}
}
if c.table.cur_fn != unsafe { nil } && node.name !in c.table.cur_fn.label_names {
c.error('unknown label `${node.name}`', node.pos)
Expand Down
6 changes: 5 additions & 1 deletion vlib/v/checker/containers.v
Expand Up @@ -647,7 +647,11 @@ fn (mut c Checker) check_elements_initialized(typ ast.Type) ! {
return
}
if typ.is_any_kind_of_pointer() {
return checker.err_ref_uninitialized
if !c.pref.translated && !c.file.is_translated {
return checker.err_ref_uninitialized
} else {
return
}
}
sym := c.table.sym(typ)
if sym.kind == .interface_ {
Expand Down
10 changes: 7 additions & 3 deletions vlib/v/checker/fn.v
Expand Up @@ -1102,7 +1102,9 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
if func.is_unsafe && !c.inside_unsafe
&& (func.language != .c || (func.name[2] in [`m`, `s`] && func.mod == 'builtin')) {
// builtin C.m*, C.s* only - temp
c.warn('function `${func.name}` must be called from an `unsafe` block', node.pos)
if !c.pref.translated && !c.file.is_translated {
c.warn('function `${func.name}` must be called from an `unsafe` block', node.pos)
}
}
node.is_keep_alive = func.is_keep_alive
if func.language == .v && func.no_body && !c.pref.translated && !c.file.is_translated
Expand Down Expand Up @@ -2415,8 +2417,10 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
}
}
if method.is_unsafe && !c.inside_unsafe {
c.warn('method `${left_sym.name}.${method_name}` must be called from an `unsafe` block',
node.pos)
if !c.pref.translated && !c.file.is_translated {
c.warn('method `${left_sym.name}.${method_name}` must be called from an `unsafe` block',
node.pos)
}
}
if c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.is_deprecated && method.is_deprecated {
c.deprecate('method', '${left_sym.name}.${method.name}', method.attrs, node.pos)
Expand Down
4 changes: 3 additions & 1 deletion vlib/v/checker/infix.v
Expand Up @@ -127,7 +127,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
}
} else if node.op in [.plus, .minus] {
if !c.inside_unsafe && !node.left.is_auto_deref_var() && !node.right.is_auto_deref_var() {
c.warn('pointer arithmetic is only allowed in `unsafe` blocks', left_right_pos)
if !c.pref.translated && !c.file.is_translated {
c.warn('pointer arithmetic is only allowed in `unsafe` blocks', left_right_pos)
}
}
if (left_type == ast.voidptr_type || left_type == ast.nil_type) && !c.pref.translated {
c.error('`${node.op}` cannot be used with `voidptr`', left_pos)
Expand Down
7 changes: 3 additions & 4 deletions vlib/v/checker/postfix.v
Expand Up @@ -13,15 +13,15 @@ fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type {
} else {
'decrement', '-'
}

c.add_error_detail('try rewrite this as `${node.expr} ${bin_op_alt} 1`')
c.error('cannot ${op_kind} `${node.expr}` because it is non lvalue expression',
node.expr.pos())
}

if node.op != .question && !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)
if !c.pref.translated && !c.file.is_translated {
c.warn('pointer arithmetic is only allowed in `unsafe` blocks', node.pos)
}
}
if !(typ_sym.is_number() || ((c.inside_unsafe || c.pref.translated) && is_non_void_pointer)) {
if c.comptime.comptime_for_field_var != '' {
Expand All @@ -33,7 +33,6 @@ fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type {
return node.typ
}
}

typ_str := c.table.type_to_str(typ)
c.error('invalid operation: ${node.op.str()} (non-numeric type `${typ_str}`)',
node.pos)
Expand Down
Empty file.
9 changes: 9 additions & 0 deletions vlib/v/checker/tests/no_arrays_of_references_in_translated.vv
@@ -0,0 +1,9 @@
@[translated]
module main

fn main() {
println(*[]&int{len: 1}[0])
println([1]&int{})
_ = [][1]&int{len: 1}[0][0]
_ = []map[int]&int{len: 1}
}
Empty file.
13 changes: 13 additions & 0 deletions vlib/v/checker/tests/no_cannot_cast_a_fixed_array_in_translated.vv
@@ -0,0 +1,13 @@
@[translated]
module main

fn main() {
mut array := [3]int{}
mut arrayptr := &int(array)

for _ in 0 .. 3 {
unsafe {
*(arrayptr++) = 0
}
}
}
Empty file.
@@ -0,0 +1,8 @@
@[translated]
module main

fn main() {
mut p := C.malloc(4)
s := 'hope'
C.memcpy(p, s.str, 4)
}
Empty file.
17 changes: 17 additions & 0 deletions vlib/v/checker/tests/no_goto_requires_unsafe_in_translated.vv
@@ -0,0 +1,17 @@
@[translated]
module main

fn f() {
goto f2
goto a1
a1:
goto a1
f2:
goto a1
}

fn main() {
goto m1
m1:
println('done')
}
Empty file.
@@ -0,0 +1,12 @@
@[translated]
module main

struct S1 {}

@[unsafe]
fn (s S1) f() {}

fn main() {
s := S1{}
s.f()
}
Empty file.
@@ -0,0 +1,15 @@
@[translated]
module main

fn f(i int) {}

fn main() {
mut x := 1
_ = (x++)
x--, x-- // OK
f(x++)
a := [x, 2 * x]
dump(x)
z := a[x--]
dump(z)
}
Empty file.
@@ -0,0 +1,17 @@
@[translated]
module main

fn main() {
mut v := 5
mut p := &v
p++
p += 2
_ := v

v2 := 4
mut q2 := &v2 - 1
q2 = q2 + 3
_ := q2
_ := v2
println('done')
}
Empty file.
17 changes: 17 additions & 0 deletions vlib/v/checker/tests/no_reading_a_union_field_in_translated.vv
@@ -0,0 +1,17 @@
@[translated]
module main

union Uf32 {
mut:
f f32
u u32
}

fn main() {
mut u := Uf32{
u: 3
}
u.f = 3.3 // ok
x := u.u
dump(x)
}
Empty file.
6 changes: 6 additions & 0 deletions vlib/v/checker/tests/no_unused_variable_in_translated.vv
@@ -0,0 +1,6 @@
@[translated]
module main

fn main() {
a := 123
}
6 changes: 4 additions & 2 deletions vlib/v/parser/expr.v
Expand Up @@ -579,8 +579,10 @@ fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_ident bo
// detect `f(x++)`, `a[x++]`
if p.peek_tok.kind in [.rpar, .rsbr] {
if !p.inside_ct_if_expr {
p.warn_with_pos('`${p.tok.kind}` operator can only be used as a statement',
p.tok.pos())
if !p.pref.translated && !p.is_translated {
p.warn_with_pos('`${p.tok.kind}` operator can only be used as a statement',
p.tok.pos())
}
}
}

Expand Down

0 comments on commit a867ed6

Please sign in to comment.