cgen: fix sum type assignment with pointers (#5868)

pull/5926/head
kalapalo 2020-07-21 20:28:49 -04:00 committed by GitHub
parent 0cc8d840a3
commit c3a2e9b5c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 7 deletions

View File

@ -988,12 +988,26 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type, expected_type table.Type) {
// cast to sum type
if expected_type != table.void_type {
if g.table.sumtype_has_variant(expected_type, got_type) {
got_sym := g.table.get_type_symbol(got_type)
got_styp := g.typ(got_type)
expected_is_ptr := expected_type.is_ptr()
expected_deref_type := if expected_is_ptr { expected_type.deref() } else { expected_type }
got_is_ptr := got_type.is_ptr()
got_deref_type := if got_is_ptr { got_type.deref() } else { got_type }
if g.table.sumtype_has_variant(expected_deref_type, got_deref_type) {
exp_styp := g.typ(expected_type)
got_styp := g.typ(got_type)
got_idx := got_type.idx()
if got_type.is_ptr() {
got_sym := g.table.get_type_symbol(got_type)
if expected_is_ptr && got_is_ptr {
exp_der_styp := g.typ(expected_deref_type)
g.write('/* sum type cast */ ($exp_styp) memdup(&($exp_der_styp){.obj = ')
g.expr(expr)
g.write(', .typ = $got_idx /* $got_sym.name */}, sizeof($exp_der_styp))')
} else if expected_is_ptr {
exp_der_styp := g.typ(expected_deref_type)
g.write('/* sum type cast */ ($exp_styp) memdup(&($exp_der_styp){.obj = memdup(&($got_styp[]) {')
g.expr(expr)
g.write('}, sizeof($got_styp)), .typ = $got_idx /* $got_sym.name */}, sizeof($exp_der_styp))')
} else if got_is_ptr {
g.write('/* sum type cast */ ($exp_styp) {.obj = ')
g.expr(expr)
g.write(', .typ = $got_idx /* $got_sym.name */}')
@ -2287,7 +2301,9 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
sym := g.table.get_type_symbol(node.cond_type)
// branch_sym := g.table.get_type_symbol(branch.typ)
if sym.kind == .sum_type {
g.write('.typ == ')
dot_or_ptr := if node.cond_type.is_ptr() { '->' } else { '.' }
g.write(dot_or_ptr)
g.write('typ == ')
} else if sym.kind == .interface_ {
// g.write('._interface_idx == _${sym.name}_${branch_sym} ')
g.write('._interface_idx == ')
@ -2338,7 +2354,9 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
// g.writeln('$it_type* it = ($it_type*)${tmp}.obj; // ST it')
g.write('\t$it_type* it = ($it_type*)')
g.expr(node.cond)
g.writeln('.obj; // ST it')
dot_or_ptr := if node.cond_type.is_ptr() { '->' } else { '.' }
g.write(dot_or_ptr)
g.writeln('obj; // ST it')
if node.var_name.len > 0 {
// for now we just copy it
g.writeln('\t$it_type* $node.var_name = it;')

View File

@ -652,7 +652,9 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) {
}
if !g.is_json_fn {
arg_typ_sym := g.table.get_type_symbol(arg.typ)
if arg_typ_sym.kind != .function {
expected_deref_type := if expected_type.is_ptr() { expected_type.deref() } else { expected_type }
is_sum_type := g.table.get_type_symbol(expected_deref_type).kind == .sum_type
if !((arg_typ_sym.kind == .function) || is_sum_type) {
g.write('(voidptr)&/*qq*/')
}
}