Skip to content

Commit 6b0c272

Browse files
authored
cgen: fix codegen for a fixed array init with different node types (fix #23545) (#23547)
1 parent b036a6a commit 6b0c272

2 files changed

Lines changed: 65 additions & 2 deletions

File tree

‎vlib/v/gen/c/cgen.v‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2768,10 +2768,23 @@ fn (mut g Gen) expr_with_fixed_array(expr ast.Expr, got_type_raw ast.Type, expec
27682768
g.writeln('${styp} ${tmp_var};')
27692769
// [ foo(), foo() ]!
27702770
val_typ := g.table.value_type(got_type_raw)
2771+
val_styp := g.styp(val_typ)
2772+
val_sym := g.table.final_sym(val_typ)
2773+
prefix := if val_sym.kind !in [.array, .array_fixed] { '&' } else { '' }
27712774
for i, item_expr in expr.exprs {
2772-
g.write('memcpy(${tmp_var}[${i}], ')
2775+
g.write('memcpy(${prefix}${tmp_var}[${i}], ')
2776+
needs_addr := (item_expr is ast.CallExpr && !item_expr.return_type.is_ptr()
2777+
&& g.table.final_sym(item_expr.return_type).kind !in [.array, .array_fixed])
2778+
|| (item_expr is ast.InfixExpr && !item_expr.promoted_type.is_ptr())
2779+
|| item_expr is ast.StructInit
2780+
if needs_addr {
2781+
g.write('ADDR(${val_styp}, ')
2782+
}
27732783
g.expr(item_expr)
2774-
g.writeln(', sizeof(${g.styp(val_typ)}));')
2784+
if needs_addr {
2785+
g.write(')')
2786+
}
2787+
g.writeln(', sizeof(${val_styp}));')
27752788
}
27762789
} else if expr is ast.CallExpr {
27772790
// return var.call() where returns is option/result fixed array
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
module main
2+
3+
import math.vec
4+
5+
pub struct Bezier {
6+
pub mut:
7+
points [4]vec.Vec2[f32]
8+
}
9+
10+
pub fn (b Bezier) h3() vec.Vec2[f32] {
11+
return b.points[2]
12+
}
13+
14+
pub fn (b Bezier) h4() vec.Vec2[f32] {
15+
return b.points[3]
16+
}
17+
18+
pub fn (b Bezier) end() vec.Vec2[f32] {
19+
return b.h4()
20+
}
21+
22+
pub struct Path {
23+
pub mut:
24+
segments [1024]Bezier
25+
len int // should be read-only
26+
}
27+
28+
pub fn (mut p Path) add(b Bezier) {
29+
assert p.len + 1 < 1024
30+
p.segments[p.len] = b
31+
p.len++
32+
}
33+
34+
fn test_main() {
35+
b1 := Bezier{
36+
points: [vec.Vec2[f32]{100, 100}, vec.Vec2[f32]{120, 80},
37+
vec.Vec2[f32]{200, 70}, vec.Vec2[f32]{400, 200}]!
38+
}
39+
b2 := Bezier{
40+
points: [b1.end(), b1.h3() + vec.Vec2[f32]{0, 2 * 80}, vec.Vec2[f32]{200, 70},
41+
b1.end() + vec.Vec2[f32]{400, 200}]!
42+
}
43+
44+
mut path := Path{}
45+
46+
path.add(b1)
47+
path.add(b2)
48+
49+
assert sizeof(path) == 32772
50+
}

0 commit comments

Comments
 (0)