From a9c2045dbde178f6654c515246fdc1856ab7223d Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 15 Feb 2021 21:51:57 +0800 Subject: [PATCH] cgen: fix var name clash of array/map (fix #1994) (#8765) --- vlib/v/checker/checker.v | 2 +- vlib/v/gen/c/array.v | 4 +- vlib/v/gen/c/auto_str_methods.v | 3 +- vlib/v/gen/c/cgen.v | 8 +- vlib/v/gen/c/json.v | 10 +-- vlib/v/gen/c/sql.v | 2 +- vlib/v/table/table.v | 6 +- .../clash_var_name_of_array_and_map_test.v | 78 +++++++++++++++++++ 8 files changed, 96 insertions(+), 17 deletions(-) create mode 100644 vlib/v/tests/clash_var_name_of_array_and_map_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 9d4ea0b301..a83119c3db 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -5478,7 +5478,7 @@ pub fn (mut c Checker) error(message string, pos token.Position) { if c.pref.is_verbose { print_backtrace() } - msg := message.replace('`array_', '`[]') + msg := message.replace('`Array_', '`[]') c.warn_or_error(msg, pos, false) } diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index 12d8d59f41..bde6ddcc1a 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -437,7 +437,7 @@ fn (mut g Gen) gen_array_contains_method(left_type table.Type) string { mut elem_type_str := g.typ(left_info.elem_type) elem_sym := g.table.get_type_symbol(left_info.elem_type) if elem_sym.kind == .function { - left_type_str = 'array_voidptr' + left_type_str = 'Array_voidptr' elem_type_str = 'voidptr' } g.type_definitions.writeln('static bool ${fn_name}($left_type_str a, $elem_type_str v); // auto') @@ -500,7 +500,7 @@ fn (mut g Gen) gen_array_index_method(left_type table.Type) string { mut elem_type_str := g.typ(info.elem_type) elem_sym := g.table.get_type_symbol(info.elem_type) if elem_sym.kind == .function { - left_type_str = 'array_voidptr' + left_type_str = 'Array_voidptr' elem_type_str = 'voidptr' } g.type_definitions.writeln('static int ${fn_name}($left_type_str a, $elem_type_str v); // auto') diff --git a/vlib/v/gen/c/auto_str_methods.v b/vlib/v/gen/c/auto_str_methods.v index e45fedb67e..a867e74326 100644 --- a/vlib/v/gen/c/auto_str_methods.v +++ b/vlib/v/gen/c/auto_str_methods.v @@ -470,7 +470,8 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string, str_fn_name st // TODO: this is a bit hacky. styp shouldn't be even parsed with _T_ // use something different than g.typ for styp clean_struct_v_type_name = - clean_struct_v_type_name.replace('_T_', '<').replace('_', ', ') + '>' + clean_struct_v_type_name.replace('_T_', '<').replace('_', ', ').replace('Array', 'array') + + '>' } clean_struct_v_type_name = util.strip_main_name(clean_struct_v_type_name) // generate ident / indent length = 4 spaces diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index f2f5c211ae..6484df5dc9 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3795,7 +3795,7 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) { } } chan_array := g.new_tmp_var() - g.write('array_sync__Channel_ptr $chan_array = new_array_from_c_array($n_channels, $n_channels, sizeof(sync__Channel*), _MOV((sync__Channel*[$n_channels]){') + g.write('Array_sync__Channel_ptr $chan_array = new_array_from_c_array($n_channels, $n_channels, sizeof(sync__Channel*), _MOV((sync__Channel*[$n_channels]){') for i in 0 .. n_channels { if i > 0 { g.write(', ') @@ -3806,7 +3806,7 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) { } g.writeln('}));') directions_array := g.new_tmp_var() - g.write('array_sync__Direction $directions_array = new_array_from_c_array($n_channels, $n_channels, sizeof(sync__Direction), _MOV((sync__Direction[$n_channels]){') + g.write('Array_sync__Direction $directions_array = new_array_from_c_array($n_channels, $n_channels, sizeof(sync__Direction), _MOV((sync__Direction[$n_channels]){') for i in 0 .. n_channels { if i > 0 { g.write(', ') @@ -3819,7 +3819,7 @@ fn (mut g Gen) select_expr(node ast.SelectExpr) { } g.writeln('}));') objs_array := g.new_tmp_var() - g.write('array_voidptr $objs_array = new_array_from_c_array($n_channels, $n_channels, sizeof(voidptr), _MOV((voidptr[$n_channels]){') + g.write('Array_voidptr $objs_array = new_array_from_c_array($n_channels, $n_channels, sizeof(voidptr), _MOV((voidptr[$n_channels]){') for i in 0 .. n_channels { g.write(if i > 0 { ', &' } else { '&' }) if tmp_objs[i] == '' { @@ -4795,7 +4795,7 @@ fn (mut g Gen) const_decl_init_later(mod string, name string, val string, typ ta } } if g.is_autofree { - if styp.starts_with('array_') { + if styp.starts_with('Array_') { g.cleanups[mod].writeln('\tarray_free(&$cname);') } if styp == 'string' { diff --git a/vlib/v/gen/c/json.v b/vlib/v/gen/c/json.v index 118fb266f7..6492bc5684 100644 --- a/vlib/v/gen/c/json.v +++ b/vlib/v/gen/c/json.v @@ -218,7 +218,7 @@ fn (mut g Gen) decode_array(value_type table.Type) string { Option_$styp val2 = $fn_name (jsval); if(!val2.ok) { array_free(&res); - return *(Option_array_$styp*)&val2; + return *(Option_Array_$styp*)&val2; } $styp val = *($styp*)val2.data; ' @@ -226,7 +226,7 @@ fn (mut g Gen) decode_array(value_type table.Type) string { return ' if(root && !cJSON_IsArray(root) && !cJSON_IsNull(root)) { Option err = v_error( string_add(_SLIT("Json element is not an array: "), tos2(cJSON_PrintUnformatted(root))) ); - return *(Option_array_$styp *)&err; + return *(Option_Array_$styp *)&err; } res = __new_array(0, 0, sizeof($styp)); const cJSON *jsval = NULL; @@ -263,7 +263,7 @@ fn (mut g Gen) decode_map(key_type table.Type, value_type table.Type) string { Option_$styp_v val2 = $fn_name_v (js_get(root, jsval->string)); if(!val2.ok) { map_free(&res); - return *(Option_map_${styp}_$styp_v*)&val2; + return *(Option_Map_${styp}_$styp_v*)&val2; } $styp_v val = *($styp_v*)val2.data; ' @@ -271,7 +271,7 @@ fn (mut g Gen) decode_map(key_type table.Type, value_type table.Type) string { return ' if(!cJSON_IsObject(root) && !cJSON_IsNull(root)) { Option err = v_error( string_add(_SLIT("Json element is not an object: "), tos2(cJSON_PrintUnformatted(root))) ); - return *(Option_map_${styp}_$styp_v *)&err; + return *(Option_Map_${styp}_$styp_v *)&err; } res = new_map_2(sizeof($styp), sizeof($styp_v), $hash_fn, $key_eq_fn, $clone_fn, $free_fn); cJSON *jsval = NULL; @@ -299,7 +299,7 @@ fn (mut g Gen) encode_map(key_type table.Type, value_type table.Type) string { } return ' o = cJSON_CreateObject(); - array_$styp $keys_tmp = map_keys(&val); + Array_$styp $keys_tmp = map_keys(&val); for (int i = 0; i < ${keys_tmp}.len; ++i) { $key cJSON_AddItemToObject(o, (char*) key.str, $fn_name_v ( *($styp_v*) map_get_1(&val, &key, &($styp_v[]) { $zero } ) ) ); diff --git a/vlib/v/gen/c/sql.v b/vlib/v/gen/c/sql.v index a28a52c4ff..5be666b8aa 100644 --- a/vlib/v/gen/c/sql.v +++ b/vlib/v/gen/c/sql.v @@ -87,7 +87,7 @@ fn (mut g Gen) sql_stmt(node ast.SqlStmt) { g.sql_stmt(expr) g.sql_stmt_name = tmp_sql_stmt_name // get last inserted id - g.writeln('array_sqlite__Row rows = sqlite__DB_exec($db_name, _SLIT("SELECT last_insert_rowid()")).arg0;') + g.writeln('Array_sqlite__Row rows = sqlite__DB_exec($db_name, _SLIT("SELECT last_insert_rowid()")).arg0;') id_name := g.new_tmp_var() g.writeln('int $id_name = string_int((*(string*)array_get((*(sqlite__Row*)array_get(rows, 0)).vals, 0)));') g.writeln('sqlite3_bind_int($g.sql_stmt_name, ${i + 0} , $id_name); // id') diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 3bfe4e5382..84eb1f5b72 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -417,7 +417,7 @@ pub fn (t &Table) array_cname(elem_type Type) string { if elem_type.is_ptr() { res = '_ptr'.repeat(elem_type.nr_muls()) } - return 'array_$elem_type_sym.cname' + res + return 'Array_$elem_type_sym.cname' + res } // array_fixed_source_name generates the original name for the v source. @@ -436,7 +436,7 @@ pub fn (t &Table) array_fixed_cname(elem_type Type, size int) string { if elem_type.is_ptr() { res = '_ptr' } - return 'array_fixed_${elem_type_sym.cname}_$size' + res + return 'Array_fixed_${elem_type_sym.cname}_$size' + res } [inline] @@ -492,7 +492,7 @@ pub fn (t &Table) map_cname(key_type Type, value_type Type) string { key_type_sym := t.get_type_symbol(key_type) value_type_sym := t.get_type_symbol(value_type) suffix := if value_type.is_ptr() { '_ptr' } else { '' } - return 'map_${key_type_sym.cname}_$value_type_sym.cname' + suffix + return 'Map_${key_type_sym.cname}_$value_type_sym.cname' + suffix // return 'map_${value_type_sym.name}' + suffix } diff --git a/vlib/v/tests/clash_var_name_of_array_and_map_test.v b/vlib/v/tests/clash_var_name_of_array_and_map_test.v new file mode 100644 index 0000000000..a70105b87a --- /dev/null +++ b/vlib/v/tests/clash_var_name_of_array_and_map_test.v @@ -0,0 +1,78 @@ +fn test_clash_var_name_of_array() { + array_f32 := 1 + array_f64 := 2 + array_bool := 3 + array_i8 := 4 + array_byte := 5 + array_i16 := 6 + array_u16 := 7 + array_int := 8 + array_u32 := 9 + array_string := 10 + array_rune := 11 + + a_f32 := []f32{} + a_f64 := []f64{} + a_bool := []bool{} + a_i8 := []i8{} + a_byte := []byte{} + a_i16 := []i16{} + a_u16 := []u16{} + a_int := []int{} + a_u32 := []u32{} + a_string := []string{} + a_rune := []rune{} + + println(a_f32) + assert '$a_f32' == '[]' + println(a_f64) + assert '$a_f64' == '[]' + println(a_bool) + assert '$a_bool' == '[]' + println(a_i8) + assert '$a_i8' == '[]' + println(a_byte) + assert '$a_byte' == '[]' + println(a_i16) + assert '$a_i16' == '[]' + println(a_u16) + assert '$a_u16' == '[]' + println(a_int) + assert '$a_int' == '[]' + println(a_u32) + assert '$a_u32' == '[]' + println(a_string) + assert '$a_string' == '[]' + println(a_rune) + assert '$a_rune' == '[]' + + println(array_f32) + assert array_f32 == 1 + println(array_f64) + assert array_f64 == 2 + println(array_bool) + assert array_bool == 3 + println(array_i8) + assert array_i8 == 4 + println(array_byte) + assert array_byte == 5 + println(array_i16) + assert array_i16 == 6 + println(array_u16) + assert array_u16 == 7 + println(array_int) + assert array_int == 8 + println(array_u32) + assert array_u32 == 9 + println(array_string) + assert array_string == 10 + println(array_rune) + assert array_rune == 11 +} + +fn test_clash_var_name_of_map() { + map_string_int := 1 + a := map[string]int{} + assert '$a' == '{}' + assert map_string_int == 1 +}