From e7fd8c4e7c0c4c72fef6ff1d6ab5b7ae51346367 Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 7 Apr 2022 17:01:54 +0800 Subject: [PATCH] cgen: fix error for dereference mut interface in loop (fix #13913) (#13941) --- vlib/v/gen/c/fn.v | 18 ++++++++++++++++-- ...> dereference_mut_interface_in_loop_test.v} | 4 ++-- vlib/v/tests/known_errors/testdata/README.md | 8 ++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) rename vlib/v/tests/{known_errors/testdata/dereference_mut_interface_in_loop.vv => dereference_mut_interface_in_loop_test.v} (82%) create mode 100644 vlib/v/tests/known_errors/testdata/README.md diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 876cb53eb1..3bbd65a198 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -775,7 +775,14 @@ fn (mut g Gen) method_call(node ast.CallExpr) { left_cc_type := g.cc_type(node.left_type, false) left_type_name := util.no_dots(left_cc_type) g.write('${c_name(left_type_name)}_name_table[') - g.expr(node.left) + if node.left.is_auto_deref_var() && node.left_type.nr_muls() > 1 { + g.write('(') + g.write('*'.repeat(node.left_type.nr_muls() - 1)) + g.expr(node.left) + g.write(')') + } else { + g.expr(node.left) + } dot := if left_is_shared { '->val.' } else if node.left_type.is_ptr() { @@ -785,7 +792,14 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } mname := c_name(node.name) g.write('${dot}_typ]._method_${mname}(') - g.expr(node.left) + if node.left.is_auto_deref_var() && node.left_type.nr_muls() > 1 { + g.write('(') + g.write('*'.repeat(node.left_type.nr_muls() - 1)) + g.expr(node.left) + g.write(')') + } else { + g.expr(node.left) + } g.write('${dot}_object') if node.args.len > 0 { g.write(', ') diff --git a/vlib/v/tests/known_errors/testdata/dereference_mut_interface_in_loop.vv b/vlib/v/tests/dereference_mut_interface_in_loop_test.v similarity index 82% rename from vlib/v/tests/known_errors/testdata/dereference_mut_interface_in_loop.vv rename to vlib/v/tests/dereference_mut_interface_in_loop_test.v index 223181211d..c8b53b1855 100644 --- a/vlib/v/tests/known_errors/testdata/dereference_mut_interface_in_loop.vv +++ b/vlib/v/tests/dereference_mut_interface_in_loop_test.v @@ -4,15 +4,15 @@ import rand import rand.wyrand import rand.splitmix64 -fn main() { +fn test_deref_mut_interface_in_loop() { mut wyrand_rng := &rand.PRNG(&wyrand.WyRandRNG{}) mut splitmix_rng := &rand.PRNG(&splitmix64.SplitMix64RNG{}) mut generators := [wyrand_rng, splitmix_rng] for mut rng in generators { seed_len := rng.block_size() / 32 - // NB: `seed_len := (*rng).block_size() / 32` does compile dump(seed_len) println(rng.string(15)) + assert seed_len == 2 } } diff --git a/vlib/v/tests/known_errors/testdata/README.md b/vlib/v/tests/known_errors/testdata/README.md new file mode 100644 index 0000000000..595b5dcc08 --- /dev/null +++ b/vlib/v/tests/known_errors/testdata/README.md @@ -0,0 +1,8 @@ +## Run the tests here with: `v vlib/v/tests/known_errors/known_errors_test.v` + +The intended use of this, is for providing samples, that currently do NOT compile, +but that a future compiler improvement WILL be able to compile, and to track, +whether they were not fixed incidentally, due to an unrelated change/improvement. +For example, code that triggers generating invalid C code can go here, +and later when a bug is fixed, can be moved to a proper _test.v or .vv/.out pair, +outside of the vlib/v/tests/known_errors/testdata/ folder.