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 {
|
if struct_init.exprs.len > info.fields.len {
|
||||||
c.error('too many fields', struct_init.pos)
|
c.error('too many fields', struct_init.pos)
|
||||||
}
|
}
|
||||||
|
mut inited_fields := []string
|
||||||
for i, expr in struct_init.exprs {
|
for i, expr in struct_init.exprs {
|
||||||
// struct_field info.
|
// struct_field info.
|
||||||
field_name := if is_short_syntax { info.fields[i].name } else { struct_init.fields[i] }
|
field_name := if is_short_syntax { info.fields[i].name } else { struct_init.fields[i] }
|
||||||
mut field := info.fields[i]
|
mut field := info.fields[i]
|
||||||
|
inited_fields << field_name
|
||||||
mut found_field := false
|
mut found_field := false
|
||||||
for f in info.fields {
|
for f in info.fields {
|
||||||
if f.name == field_name {
|
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.expr_types << expr_type
|
||||||
struct_init.expected_types << field.typ
|
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 {}
|
else {}
|
||||||
}
|
}
|
||||||
|
@ -1166,23 +1177,41 @@ pub fn (c mut Checker) map_init(node mut ast.MapInit) table.Type {
|
||||||
return map_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) {
|
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++
|
c.nr_errors++
|
||||||
|
}
|
||||||
//if c.pref.is_verbose {
|
//if c.pref.is_verbose {
|
||||||
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
||||||
print_backtrace()
|
print_backtrace()
|
||||||
}
|
}
|
||||||
|
typ := if warn { 'warning' } else { 'error' }
|
||||||
kind := if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
kind := if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
||||||
'checker error #$c.nr_errors:'
|
'checker $typ #$c.nr_errors:'
|
||||||
} else {
|
} else {
|
||||||
'error:'
|
'$typ:'
|
||||||
}
|
}
|
||||||
ferror := util.formated_error(kind, s, c.file.path, pos)
|
ferror := util.formated_error(kind, s, c.file.path, pos)
|
||||||
c.errors << ferror
|
c.errors << ferror
|
||||||
if !(pos.line_nr in c.error_lines) {
|
if !(pos.line_nr in c.error_lines) {
|
||||||
|
if warn {
|
||||||
|
println(ferror)
|
||||||
|
} else {
|
||||||
eprintln(ferror)
|
eprintln(ferror)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if !warn {
|
||||||
c.error_lines << pos.line_nr
|
c.error_lines << pos.line_nr
|
||||||
|
}
|
||||||
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
if c.pref.verbosity.is_higher_or_equal(.level_one) {
|
||||||
println('\n\n')
|
println('\n\n')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1884,7 +1884,7 @@ fn (g mut Gen) struct_init(it ast.StructInit) {
|
||||||
g.writeln('($styp){')
|
g.writeln('($styp){')
|
||||||
}
|
}
|
||||||
mut fields := []string
|
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 {
|
if it.fields.len == 0 && it.exprs.len > 0 {
|
||||||
// Get fields for {a,b} short syntax. Fields array wasn't set in the parser.
|
// Get fields for {a,b} short syntax. Fields array wasn't set in the parser.
|
||||||
for f in info.fields {
|
for f in info.fields {
|
||||||
|
@ -2447,10 +2447,14 @@ fn (g mut Gen) fn_call(node ast.CallExpr) {
|
||||||
else {
|
else {
|
||||||
// `println(int_str(10))`
|
// `println(int_str(10))`
|
||||||
// sym := g.table.get_type_symbol(node.args[0].typ)
|
// 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(')
|
g.write('${print_method}(${styp}_str(')
|
||||||
if table.type_is_ptr(typ) {
|
if table.type_is_ptr(typ) {
|
||||||
// dereference
|
// dereference
|
||||||
g.write('*')
|
//g.write('*')
|
||||||
}
|
}
|
||||||
g.expr(node.args[0].expr)
|
g.expr(node.args[0].expr)
|
||||||
g.write('))')
|
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)
|
fmt := type_to_fmt(field.typ)
|
||||||
g.definitions.write('\t$field.name: $fmt\\n')
|
g.definitions.write('\t$field.name: $fmt\\n')
|
||||||
}
|
}
|
||||||
g.definitions.write('\\n}"')
|
g.definitions.write('}"')
|
||||||
if info.fields.len > 0 {
|
if info.fields.len > 0 {
|
||||||
g.definitions.write(', ')
|
g.definitions.write(', ')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue