cgen: fix print(ptr); checker: uninitialized reference error/warning
parent
436ef12730
commit
1d2de44e19
|
@ -102,10 +102,12 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
|||
if struct_init.exprs.len > info.fields.len {
|
||||
c.error('too many fields', struct_init.pos)
|
||||
}
|
||||
mut inited_fields := []string
|
||||
for i, expr in struct_init.exprs {
|
||||
// struct_field info.
|
||||
field_name := if is_short_syntax { info.fields[i].name } else { struct_init.fields[i] }
|
||||
mut field := info.fields[i]
|
||||
inited_fields << field_name
|
||||
mut found_field := false
|
||||
for f in info.fields {
|
||||
if f.name == field_name {
|
||||
|
@ -127,6 +129,15 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
|||
struct_init.expr_types << expr_type
|
||||
struct_init.expected_types << field.typ
|
||||
}
|
||||
// Check uninitialized refs
|
||||
for field in info.fields {
|
||||
if field.name in inited_fields {
|
||||
continue
|
||||
}
|
||||
if table.type_is_ptr(field.typ) {
|
||||
c.warn('reference field `Reference.value` must be initialized', struct_init.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {}
|
||||
}
|
||||
|
@ -1166,23 +1177,41 @@ pub fn (c mut Checker) map_init(node mut ast.MapInit) table.Type {
|
|||
return map_type
|
||||
}
|
||||
|
||||
pub fn (c mut Checker) warn(s string, pos token.Position) {
|
||||
allow_warnings := !c.pref.is_prod // allow warnings only in dev builds
|
||||
c.warn_or_error(s, pos, allow_warnings) // allow warnings only in dev builds
|
||||
}
|
||||
|
||||
pub fn (c mut Checker) error(s string, pos token.Position) {
|
||||
c.warn_or_error(s, pos, false)
|
||||
}
|
||||
|
||||
fn (c mut Checker) warn_or_error(s string, pos token.Position, warn bool) {
|
||||
if !warn {
|
||||
c.nr_errors++
|
||||
}
|
||||
//if c.pref.is_verbose {
|
||||
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
||||
print_backtrace()
|
||||
}
|
||||
typ := if warn { 'warning' } else { 'error' }
|
||||
kind := if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
||||
'checker error #$c.nr_errors:'
|
||||
'checker $typ #$c.nr_errors:'
|
||||
} else {
|
||||
'error:'
|
||||
'$typ:'
|
||||
}
|
||||
ferror := util.formated_error(kind, s, c.file.path, pos)
|
||||
c.errors << ferror
|
||||
if !(pos.line_nr in c.error_lines) {
|
||||
if warn {
|
||||
println(ferror)
|
||||
} else {
|
||||
eprintln(ferror)
|
||||
}
|
||||
}
|
||||
if !warn {
|
||||
c.error_lines << pos.line_nr
|
||||
}
|
||||
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
||||
println('\n\n')
|
||||
}
|
||||
|
|
|
@ -1884,7 +1884,7 @@ fn (g mut Gen) struct_init(it ast.StructInit) {
|
|||
g.writeln('($styp){')
|
||||
}
|
||||
mut fields := []string
|
||||
mut inited_fields := []string
|
||||
mut inited_fields := []string // TODO this is done in checker, move to ast node
|
||||
if it.fields.len == 0 && it.exprs.len > 0 {
|
||||
// Get fields for {a,b} short syntax. Fields array wasn't set in the parser.
|
||||
for f in info.fields {
|
||||
|
@ -2447,10 +2447,14 @@ fn (g mut Gen) fn_call(node ast.CallExpr) {
|
|||
else {
|
||||
// `println(int_str(10))`
|
||||
// sym := g.table.get_type_symbol(node.args[0].typ)
|
||||
if table.type_is_ptr(typ) {
|
||||
// ptr_str() for pointers
|
||||
styp = 'ptr'
|
||||
}
|
||||
g.write('${print_method}(${styp}_str(')
|
||||
if table.type_is_ptr(typ) {
|
||||
// dereference
|
||||
g.write('*')
|
||||
//g.write('*')
|
||||
}
|
||||
g.expr(node.args[0].expr)
|
||||
g.write('))')
|
||||
|
@ -2883,7 +2887,7 @@ fn (g mut Gen) gen_str_for_type(sym table.TypeSymbol, styp string) {
|
|||
fmt := type_to_fmt(field.typ)
|
||||
g.definitions.write('\t$field.name: $fmt\\n')
|
||||
}
|
||||
g.definitions.write('\\n}"')
|
||||
g.definitions.write('}"')
|
||||
if info.fields.len > 0 {
|
||||
g.definitions.write(', ')
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue