From 067c5b64868a9562a69447e994d2c8e65eb3d4ac Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 26 Oct 2024 02:26:41 -0300 Subject: [PATCH] cgen,ast: fix interface conversion codegen race issue (fix #22640, #17943) (#22655) --- vlib/v/ast/types.v | 2 +- vlib/v/gen/c/cgen.v | 10 ++++++---- vlib/v/gen/c/infix.v | 25 +++++++++++++------------ 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index 52bce80016..df595c661f 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -191,7 +191,7 @@ pub mut: methods []Fn embeds []Type // `I1 is I2` conversions - conversions map[int][]Type + conversions shared map[int][]Type // generic interface support is_generic bool generic_types []Type diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index dcef21b112..28aa4ff4fa 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -7598,10 +7598,12 @@ fn (mut g Gen) as_cast(node ast.AsCast) { g.write(')') mut info := expr_type_sym.info as ast.Interface - if node.typ !in info.conversions { - left_variants := g.table.iface_types[expr_type_sym.name] - right_variants := g.table.iface_types[sym.name] - info.conversions[node.typ] = left_variants.filter(it in right_variants) + lock info.conversions { + if node.typ !in info.conversions { + left_variants := g.table.iface_types[expr_type_sym.name] + right_variants := g.table.iface_types[sym.name] + info.conversions[node.typ] = left_variants.filter(it in right_variants) + } } expr_type_sym.info = info } else if mut expr_type_sym.info is ast.Interface && node.expr_type != node.typ { diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index f215776cc7..17ceba36b3 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -776,18 +776,19 @@ fn (mut g Gen) gen_interface_is_op(node ast.InfixExpr) { right_sym := g.table.sym(node.right_type) mut info := left_sym.info as ast.Interface - - common_variants := info.conversions[node.right_type] or { - left_variants := g.table.iface_types[left_sym.name] - right_variants := g.table.iface_types[right_sym.name] - c := left_variants.filter(it in right_variants) - info.conversions[node.right_type] = c - c - } - left_sym.info = info - if common_variants.len == 0 { - g.write('false') - return + lock info.conversions { + common_variants := info.conversions[node.right_type] or { + left_variants := g.table.iface_types[left_sym.name] + right_variants := g.table.iface_types[right_sym.name] + c := left_variants.filter(it in right_variants) + info.conversions[node.right_type] = c + c + } + left_sym.info = info + if common_variants.len == 0 { + g.write('false') + return + } } g.write('I_${left_sym.cname}_is_I_${right_sym.cname}(') if node.left_type.is_ptr() {