Skip to content

Commit 514a9a7

Browse files
authored
cgen: fix assigning option of array index (fix #23451) (#23455)
1 parent 8f0242e commit 514a9a7

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

vlib/v/gen/c/cgen.v

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6718,6 +6718,12 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
67186718
if expr_stmt.expr.is_return_used {
67196719
g.write('*(${cast_typ}*) ${cvar_name}.data = ')
67206720
}
6721+
} else if g.inside_opt_or_res && return_is_option && g.inside_assign {
6722+
g.write('_option_ok(&(${cast_typ}[]) { ')
6723+
g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type.clear_option_and_result())
6724+
g.writeln(' }, (${option_name}*)&${cvar_name}, sizeof(${cast_typ}));')
6725+
g.indent--
6726+
return
67216727
} else {
67226728
g.write('*(${cast_typ}*) ${cvar_name}.data = ')
67236729
}

vlib/v/gen/c/index.v

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,11 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym ast.TypeSymbol) {
342342
g.or_block(tmp_opt, node.or_expr, elem_type)
343343
}
344344
if !g.is_amp {
345-
g.write('\n${cur_line}(*(${elem_type_str}*)${tmp_opt}.data)')
345+
if g.inside_opt_or_res && elem_type.has_flag(.option) && g.inside_assign {
346+
g.write('\n${cur_line}(*(${elem_type_str}*)&${tmp_opt})')
347+
} else {
348+
g.write('\n${cur_line}(*(${elem_type_str}*)${tmp_opt}.data)')
349+
}
346350
} else {
347351
g.write('\n${cur_line}*${tmp_opt_ptr}')
348352
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
fn make_option() ?string {
2+
return none
3+
}
4+
5+
fn test_assign_option_of_array_index() {
6+
arr := [make_option()]
7+
unwrapped := arr[99] or { 'unknown' } // <- out of bounds access!
8+
assert '${unwrapped}' == "Option('unknown')"
9+
}

0 commit comments

Comments
 (0)