Skip to content

Commit

Permalink
checker: silence "assigning 0 to a reference field" and "uninitialize…
Browse files Browse the repository at this point in the history
…d fn struct fields" notices for `@[translated]\nmodule ...` files (#20938)
  • Loading branch information
spytheman committed Mar 1, 2024
1 parent febc4a7 commit 065e5e2
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 12 deletions.
9 changes: 5 additions & 4 deletions vlib/v/checker/check_types.v
Expand Up @@ -533,10 +533,11 @@ fn (mut c Checker) check_shift(mut node ast.InfixExpr, left_type_ ast.Type, righ
// a negative value, the resulting value is implementation-defined (ID).
left_sym_final := c.table.final_sym(left_type)
left_type_final := ast.Type(left_sym_final.idx)
if node.op == .left_shift && left_type_final.is_signed() && !(c.inside_unsafe
&& c.is_generated) && !c.pref.translated && !c.file.is_translated {
c.note('shifting a value from a signed type `${left_sym_final.name}` can change the sign',
node.left.pos())
if !(c.is_generated || c.inside_unsafe || c.file.is_translated || c.pref.translated) {
if node.op == .left_shift && left_type_final.is_signed() {
c.note('shifting a value from a signed type `${left_sym_final.name}` can change the sign',
node.left.pos())
}
}
if node.ct_right_value_evaled {
if node.ct_right_value !is ast.EmptyExpr {
Expand Down
20 changes: 12 additions & 8 deletions vlib/v/checker/struct.v
Expand Up @@ -88,12 +88,14 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
// Do not allow uninitialized `fn` fields, or force `?fn`
// (allow them in `C.` structs)
if !c.is_builtin_mod && node.language == .v {
sym := c.table.sym(field.typ)
if sym.kind == .function {
if !field.typ.has_flag(.option) && !field.has_default_expr
&& field.attrs.all(it.name != 'required') {
error_msg := 'uninitialized `fn` struct fields are not allowed, since they can result in segfaults; use `?fn` or `[required]` or initialize the field with `=` (if you absolutely want to have unsafe function pointers, use `= unsafe { nil }`)'
c.note(error_msg, field.pos)
if !(c.file.is_translated || c.pref.translated) {
sym := c.table.sym(field.typ)
if sym.kind == .function {
if !field.typ.has_flag(.option) && !field.has_default_expr
&& field.attrs.all(it.name != 'required') {
error_msg := 'uninitialized `fn` struct fields are not allowed, since they can result in segfaults; use `?fn` or `[required]` or initialize the field with `=` (if you absolutely want to have unsafe function pointers, use `= unsafe { nil }`)'
c.note(error_msg, field.pos)
}
}
}
}
Expand Down Expand Up @@ -672,8 +674,10 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
&& !exp_type.has_flag(.option) {
if init_field.expr.str() == '0' {
if !c.inside_unsafe && type_sym.language == .v {
c.note('assigning `0` to a reference field is only allowed in `unsafe` blocks',
init_field.pos)
if !(c.file.is_translated || c.pref.translated) {
c.note('assigning `0` to a reference field is only allowed in `unsafe` blocks',
init_field.pos)
}
}
} else {
c.error('reference field must be initialized with reference',
Expand Down
Empty file.
@@ -0,0 +1,14 @@
@[translated]
module main

pub struct CType {
t int
ref &int
}

fn main() {
ctype := CType{
ref: 0
}
dump(ctype)
}
Empty file.
@@ -0,0 +1,14 @@
@[translated]
module main

type FnCb = fn ()

struct Abc {
x int
f FnCb
}

fn main() {
a := Abc{}
dump(a)
}

0 comments on commit 065e5e2

Please sign in to comment.