Skip to content

Commit db49874

Browse files
authored
cgen: fix printing fn call of returning c struct value (fix #23104) (#23106)
1 parent fe6658d commit db49874

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

vlib/v/gen/c/str.v

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
118118
is_dump_expr := expr is ast.DumpExpr
119119
is_var_mut := expr.is_auto_deref_var()
120120
str_fn_name := g.get_str_fn(exp_typ)
121-
temp_var_needed := expr is ast.CallExpr && expr.return_type.is_ptr()
121+
temp_var_needed := expr is ast.CallExpr
122+
&& (expr.return_type.is_ptr() || g.table.sym(expr.return_type).is_c_struct())
122123
mut tmp_var := ''
123124
if temp_var_needed {
124125
tmp_var = g.new_tmp_var()
@@ -206,6 +207,21 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
206207
str_fn_name := g.get_str_fn(typ)
207208
g.write('${str_fn_name}(')
208209
if sym.kind != .function {
210+
unwrap_option := expr is ast.Ident && expr.or_expr.kind == .propagate_option
211+
exp_typ := if unwrap_option { typ.clear_flag(.option) } else { typ }
212+
temp_var_needed := expr is ast.CallExpr
213+
&& (expr.return_type.is_ptr() || g.table.sym(expr.return_type).is_c_struct())
214+
mut tmp_var := ''
215+
if temp_var_needed {
216+
tmp_var = g.new_tmp_var()
217+
ret_typ := g.styp(exp_typ)
218+
line := g.go_before_last_stmt().trim_space()
219+
g.empty_line = true
220+
g.write('${ret_typ} ${tmp_var} = ')
221+
g.expr(expr)
222+
g.writeln(';')
223+
g.write(line)
224+
}
209225
if str_method_expects_ptr && !is_ptr && !typ.has_flag(.option) {
210226
g.write('&')
211227
} else if (!str_method_expects_ptr && is_ptr && !is_shared) || is_var_mut {
@@ -215,7 +231,11 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
215231
g.write(c_struct_ptr(sym, typ, str_method_expects_ptr))
216232
}
217233
}
218-
g.expr_with_cast(expr, typ, typ)
234+
if temp_var_needed {
235+
g.write(tmp_var)
236+
} else {
237+
g.expr_with_cast(expr, typ, typ)
238+
}
219239
} else if typ.has_flag(.option) {
220240
// only Option fn receive argument
221241
g.expr_with_cast(expr, typ, typ)

vlib/v/tests/c_structs/csize.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
struct Size {
2+
int width;
3+
int height;
4+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include "@VMODROOT/csize.h"
2+
3+
struct C.Size {
4+
width int
5+
height int
6+
}
7+
8+
type Size = C.Size
9+
10+
fn get_size() C.Size {
11+
return C.Size{11, 22}
12+
}
13+
14+
fn get_csize() Size {
15+
return Size(C.Size{11, 22})
16+
}
17+
18+
fn test_return_csize() {
19+
println(get_size())
20+
assert true
21+
println(get_csize())
22+
assert true
23+
}

0 commit comments

Comments
 (0)