From 90ae3c82c97b507534840db8781571be706f910d Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 2 Feb 2023 15:31:11 +0800 Subject: [PATCH] cgen: fix sumtype as cast with calling twice (fix #17156) (#17183) --- cmd/tools/vtest-self.v | 1 + vlib/v/gen/c/cgen.v | 72 ++++++++++++++++++++++------- vlib/v/tests/sumtype_as_cast_test.v | 18 ++++++++ 3 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 vlib/v/tests/sumtype_as_cast_test.v diff --git a/cmd/tools/vtest-self.v b/cmd/tools/vtest-self.v index b4c680837f..7d00689650 100644 --- a/cmd/tools/vtest-self.v +++ b/cmd/tools/vtest-self.v @@ -230,6 +230,7 @@ const ( 'do_not_remove', 'vlib/v/tests/const_fixed_array_containing_references_to_itself_test.v', // error C2099: initializer is not a constant 'vlib/v/tests/const_and_global_with_same_name_test.v', // error C2099: initializer is not a constant + 'vlib/v/tests/sumtype_as_cast_test.v', // error: Compound statement expression cannot support ] skip_on_windows = [ 'do_not_remove', diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index ed1dcb59cb..4e877ae5d0 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -6088,23 +6088,63 @@ fn (mut g Gen) as_cast(node ast.AsCast) { mut expr_type_sym := g.table.sym(g.unwrap_generic(node.expr_type)) if mut expr_type_sym.info is ast.SumType { dot := if node.expr_type.is_ptr() { '->' } else { '.' } - if sym.info is ast.FnType { - g.write('/* as */ (${styp})__as_cast(') - } else { - g.write('/* as */ *(${styp}*)__as_cast(') + $if !msvc { + if node.expr is ast.CallExpr { + tmp_var := g.new_tmp_var() + expr_styp := g.typ(node.expr_type) + g.write('({ ${expr_styp} ${tmp_var} = ') + g.expr(node.expr) + g.write('; ') + if sym.info is ast.FnType { + g.write('/* as */ (${styp})__as_cast(') + } else { + g.write('/* as */ *(${styp}*)__as_cast(') + } + g.write(tmp_var) + g.write(dot) + g.write('_${sym.cname},') + g.write(tmp_var) + g.write(dot) + sidx := g.type_sidx(unwrapped_node_typ) + g.write('_typ, ${sidx}); }) /*expected idx: ${sidx}, name: ${sym.name} */ ') + } else { + if sym.info is ast.FnType { + g.write('/* as */ (${styp})__as_cast(') + } else { + g.write('/* as */ *(${styp}*)__as_cast(') + } + g.write('(') + g.expr(node.expr) + g.write(')') + g.write(dot) + g.write('_${sym.cname},') + g.write('(') + g.expr(node.expr) + g.write(')') + g.write(dot) + // g.write('typ, /*expected:*/$node.typ)') + sidx := g.type_sidx(unwrapped_node_typ) + g.write('_typ, ${sidx}) /*expected idx: ${sidx}, name: ${sym.name} */ ') + } + } $else { + if sym.info is ast.FnType { + g.write('/* as */ (${styp})__as_cast(') + } else { + g.write('/* as */ *(${styp}*)__as_cast(') + } + g.write('(') + g.expr(node.expr) + g.write(')') + g.write(dot) + g.write('_${sym.cname},') + g.write('(') + g.expr(node.expr) + g.write(')') + g.write(dot) + // g.write('typ, /*expected:*/$node.typ)') + sidx := g.type_sidx(unwrapped_node_typ) + g.write('_typ, ${sidx}) /*expected idx: ${sidx}, name: ${sym.name} */ ') } - g.write('(') - g.expr(node.expr) - g.write(')') - g.write(dot) - g.write('_${sym.cname},') - g.write('(') - g.expr(node.expr) - g.write(')') - g.write(dot) - // g.write('typ, /*expected:*/$node.typ)') - sidx := g.type_sidx(unwrapped_node_typ) - g.write('_typ, ${sidx}) /*expected idx: ${sidx}, name: ${sym.name} */ ') // fill as cast name table for variant in expr_type_sym.info.variants { diff --git a/vlib/v/tests/sumtype_as_cast_test.v b/vlib/v/tests/sumtype_as_cast_test.v new file mode 100644 index 0000000000..a0a7569111 --- /dev/null +++ b/vlib/v/tests/sumtype_as_cast_test.v @@ -0,0 +1,18 @@ +type Sum = int | string + +struct Count { +mut: + count int +} + +fn (mut c Count) ret_sum() Sum { + c.count++ + return c.count +} + +fn test_sumtype_as_cast() { + mut cnt := Count{22} + _ := cnt.ret_sum() as int + println(cnt) + assert cnt.count == 23 +}