checker: silence "assigning 0 to a reference field" and "uninitialized fn struct fields" notices for @[translated]\nmodule ... files (#20938)

This commit is contained in:
Delyan Angelov 2024-03-02 01:33:55 +02:00 committed by GitHub
parent febc4a7eaa
commit 065e5e22cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 45 additions and 12 deletions

View File

@ -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 {

View File

@ -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)
}
}
}
}
@ -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',

View File

@ -0,0 +1,14 @@
@[translated]
module main
pub struct CType {
t int
ref &int
}
fn main() {
ctype := CType{
ref: 0
}
dump(ctype)
}

View File

@ -0,0 +1,14 @@
@[translated]
module main
type FnCb = fn ()
struct Abc {
x int
f FnCb
}
fn main() {
a := Abc{}
dump(a)
}