Skip to content

Commit dab25ca

Browse files
authored
cgen: remove unused code generated for unwrapping temp var from callexpr (detect unused return value from CallExpr), fix parser bugs (#22769)
1 parent 505a247 commit dab25ca

15 files changed

Lines changed: 132 additions & 54 deletions

File tree

cmd/tools/vast/vast.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,6 +1559,7 @@ fn (t Tree) call_expr(node ast.CallExpr) &Node {
15591559
obj.add('is_keep_alive', t.bool_node(node.is_keep_alive))
15601560
obj.add_terse('is_noreturn', t.bool_node(node.is_noreturn))
15611561
obj.add_terse('is_ctor_new', t.bool_node(node.is_ctor_new))
1562+
obj.add_terse('is_return_used', t.bool_node(node.is_return_used))
15621563
obj.add('should_be_skipped', t.bool_node(node.should_be_skipped))
15631564
obj.add_terse('free_receiver', t.bool_node(node.free_receiver))
15641565
obj.add('scope', t.number_node(int(node.scope)))

vlib/v/ast/ast.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,7 @@ pub mut:
827827
scope &Scope = unsafe { nil }
828828
from_embed_types []Type // holds the type of the embed that the method is called from
829829
comments []Comment
830+
is_return_used bool // return value is used for another expr
830831
//
831832
is_expand_simple_interpolation bool // true, when the function/method is marked as @[expand_simple_interpolation]
832833
// Calls to it with an interpolation argument like `b.f('x ${y}')`, will be converted to `b.f('x ')` followed by `b.f(y)`.

vlib/v/checker/assign.v

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -580,13 +580,14 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
580580
right.pos())
581581
c.note('an implicit clone of the slice was done here', right.pos())
582582
right = ast.CallExpr{
583-
name: 'clone'
584-
left: right
585-
left_type: left_type
586-
is_method: true
587-
receiver_type: left_type
588-
return_type: left_type
589-
scope: c.fn_scope
583+
name: 'clone'
584+
left: right
585+
left_type: left_type
586+
is_method: true
587+
receiver_type: left_type
588+
return_type: left_type
589+
scope: c.fn_scope
590+
is_return_used: true
590591
}
591592
right_type = c.expr(mut right)
592593
node.right[i] = right

vlib/v/checker/checker.v

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1371,7 +1371,6 @@ fn (mut c Checker) check_or_last_stmt(mut stmt ast.Stmt, ret_type ast.Type, expr
13711371
c.expected_type = ret_type
13721372
c.expected_or_type = ret_type.clear_option_and_result()
13731373
last_stmt_typ := c.expr(mut stmt.expr)
1374-
13751374
if last_stmt_typ.has_flag(.option) || last_stmt_typ == ast.none_type {
13761375
if stmt.expr in [ast.Ident, ast.SelectorExpr, ast.CallExpr, ast.None, ast.CastExpr] {
13771376
expected_type_name := c.table.type_to_str(ret_type.clear_option_and_result())

vlib/v/checker/struct.v

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -733,13 +733,14 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
733733
init_field.expr.pos())
734734
c.note('an implicit clone of the slice was done here', init_field.expr.pos())
735735
mut right := ast.CallExpr{
736-
name: 'clone'
737-
left: init_field.expr
738-
left_type: got_type
739-
is_method: true
740-
receiver_type: got_type.ref()
741-
return_type: got_type
742-
scope: c.fn_scope
736+
name: 'clone'
737+
left: init_field.expr
738+
left_type: got_type
739+
is_method: true
740+
receiver_type: got_type.ref()
741+
return_type: got_type
742+
scope: c.fn_scope
743+
is_return_used: true
743744
}
744745
got_type = c.expr(mut right)
745746
node.init_fields[i].expr = right
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
@[flag]
22
pub enum Enum {
3-
a
3+
a
44
}
55

66
@[flag]
77
pub enum Enum {
8-
a
9-
}
8+
a
9+
}

vlib/v/gen/c/assign.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,7 @@ fn (mut g Gen) gen_cross_var_assign(node &ast.AssignStmt) {
10411041
g.write(' = *(voidptr*)array_get(')
10421042
} else {
10431043
styp := g.styp(info.elem_type)
1044-
string_clone := if needs_clone { '/*1*/string_clone(' } else { '' }
1044+
string_clone := if needs_clone { 'string_clone(' } else { '' }
10451045

10461046
g.write('${styp} _var_${left.pos.pos} = ${string_clone}*(${styp}*)array_get(')
10471047
}

vlib/v/gen/c/cgen.v

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2158,7 +2158,11 @@ fn (mut g Gen) stmt(node ast.Stmt) {
21582158
eprintln('cgen: ${g.file.path:-30} | pos: ${node.pos.line_str():-39} | node: ${ntype} | ${node}')
21592159
}
21602160
}
2161+
old_inside_call := g.inside_call
21612162
g.inside_call = false
2163+
defer {
2164+
g.inside_call = old_inside_call
2165+
}
21622166
if !g.skip_stmt_pos {
21632167
g.set_current_pos_as_last_stmt_pos()
21642168
}
@@ -7140,6 +7144,10 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
71407144
&& expr_stmt.expr.or_block.kind == .absent {
71417145
g.write('${cvar_name} = ')
71427146
return_wrapped = true
7147+
} else if expr_stmt.expr is ast.CallExpr {
7148+
if expr_stmt.expr.is_return_used {
7149+
g.write('*(${cast_typ}*) ${cvar_name}.data = ')
7150+
}
71437151
} else {
71447152
g.write('*(${cast_typ}*) ${cvar_name}.data = ')
71457153
}

vlib/v/gen/c/fn.v

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,12 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
10211021
&& unwrapped_styp.starts_with('_v_') {
10221022
unwrapped_styp = unwrapped_styp[3..]
10231023
}
1024-
g.write('\n ${cur_line} (*(${unwrapped_styp}*)${tmp_opt}.data)')
1024+
if node.is_return_used {
1025+
// return value is used, so we need to write the unwrapped temporary var
1026+
g.write('\n ${cur_line} (*(${unwrapped_styp}*)${tmp_opt}.data)')
1027+
} else {
1028+
g.write('\n ${cur_line}')
1029+
}
10251030
} else {
10261031
g.write('\n ${cur_line} ${tmp_opt}')
10271032
}

vlib/v/gen/wasm/gen.v

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -631,12 +631,13 @@ pub fn (mut g Gen) call_expr(node ast.CallExpr, expected ast.Type, existing_rvar
631631
}
632632

633633
expr = ast.CallExpr{
634-
name: 'str'
635-
left: expr
636-
left_type: typ
637-
receiver_type: typ
638-
return_type: ast.string_type
639-
is_method: true
634+
name: 'str'
635+
left: expr
636+
left_type: typ
637+
receiver_type: typ
638+
return_type: ast.string_type
639+
is_method: true
640+
is_return_used: true
640641
}
641642
}
642643

0 commit comments

Comments
 (0)