Skip to content

Commit

Permalink
cgen: fix variable name conflict, when using a C reserved name (#19942)
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyi98 committed Nov 20, 2023
1 parent 8c1da9b commit 0966fd3
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 14 deletions.
2 changes: 1 addition & 1 deletion vlib/v/gen/c/assign.v
Expand Up @@ -552,7 +552,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
''
}

fn_name := c_name(g.get_ternary_name(ident.name))
fn_name := c_fn_name(g.get_ternary_name(ident.name))
g.write('${ret_styp} (${msvc_call_conv}*${fn_name}) (')
def_pos := g.definitions.len
g.fn_decl_params(func.func.params, unsafe { nil }, false)
Expand Down
15 changes: 12 additions & 3 deletions vlib/v/gen/c/cgen.v
Expand Up @@ -6394,6 +6394,15 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty

@[inline]
fn c_name(name_ string) string {
name := util.no_dots(name_)
if c.c_reserved_chk.matches(name) {
return '__v_${name}'
}
return name
}

@[inline]
fn c_fn_name(name_ string) string {
name := util.no_dots(name_)
if c.c_reserved_chk.matches(name) {
return '_v_${name}'
Expand Down Expand Up @@ -6740,7 +6749,7 @@ fn (mut g Gen) interface_table() string {
for k, method in inter_info.methods {
methodidx[method.name] = k
ret_styp := g.typ(method.return_type)
methods_struct_def.write_string('\t${ret_styp} (*_method_${c_name(method.name)})(void* _')
methods_struct_def.write_string('\t${ret_styp} (*_method_${c_fn_name(method.name)})(void* _')
// the first param is the receiver, it's handled by `void*` above
for i in 1 .. method.params.len {
arg := method.params[i]
Expand Down Expand Up @@ -6865,7 +6874,7 @@ static inline __shared__${interface_name} ${shared_fn_name}(__shared__${cctype}*
if st == ast.voidptr_type || st == ast.nil_type {
for mname, _ in methodidx {
if g.pref.build_mode != .build_module {
methods_struct.writeln('\t\t._method_${c_name(mname)} = (void*) 0,')
methods_struct.writeln('\t\t._method_${c_fn_name(mname)} = (void*) 0,')
}
}
}
Expand Down Expand Up @@ -6975,7 +6984,7 @@ static inline __shared__${interface_name} ${shared_fn_name}(__shared__${cctype}*
}
if g.pref.build_mode != .build_module && st != ast.voidptr_type
&& st != ast.nil_type {
methods_struct.writeln('\t\t._method_${c_name(method.name)} = (void*) ${method_call},')
methods_struct.writeln('\t\t._method_${c_fn_name(method.name)} = (void*) ${method_call},')
}
}

Expand Down
14 changes: 7 additions & 7 deletions vlib/v/gen/c/fn.v
Expand Up @@ -457,7 +457,7 @@ fn (mut g Gen) c_fn_name(node &ast.FnDecl) string {
if node.language == .c {
name = util.no_dots(name)
} else {
name = c_name(name)
name = c_fn_name(name)
}

if node.generic_names.len > 0 {
Expand Down Expand Up @@ -1235,7 +1235,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
g.expr(node.left)
}
dot := g.dot_or_ptr(left_type)
mname := c_name(node.name)
mname := c_fn_name(node.name)
g.write('${dot}_typ]._method_${mname}(')
if node.left.is_auto_deref_var() && left_type.nr_muls() > 1 {
g.write('(')
Expand Down Expand Up @@ -1620,7 +1620,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
ast_type := node.args[0].expr as ast.TypeNode
// `json.decode(User, s)` => json.decode_User(s)
typ := c_name(g.typ(ast_type.typ))
fn_name := c_name(name) + '_' + typ
fn_name := c_fn_name(name) + '_' + typ
g.gen_json_for_type(ast_type.typ)
g.empty_line = true
g.writeln('// json.decode')
Expand All @@ -1647,7 +1647,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
// Skip "C."
name = util.no_dots(name[2..])
} else {
name = c_name(name)
name = c_fn_name(name)
}
if g.pref.translated || g.file.is_translated || node.is_file_translated {
// For `[c: 'P_TryMove'] fn p_trymove( ... `
Expand Down Expand Up @@ -1713,7 +1713,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
expr := node.args[0].expr
typ_sym := g.table.sym(typ)
if typ_sym.kind == .interface_ && (typ_sym.info as ast.Interface).defines_method('str') {
g.write('${c_name(print_method)}(')
g.write('${c_fn_name(print_method)}(')
rec_type_name := util.no_dots(g.cc_type(typ, false))
g.write('${c_name(rec_type_name)}_name_table[')
g.expr(expr)
Expand All @@ -1729,9 +1729,9 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
tmp := g.new_tmp_var()
g.write('string ${tmp} = ')
g.gen_expr_to_string(expr, typ)
g.writeln('; ${c_name(print_method)}(${tmp}); string_free(&${tmp});')
g.writeln('; ${c_fn_name(print_method)}(${tmp}); string_free(&${tmp});')
} else {
g.write('${c_name(print_method)}(')
g.write('${c_fn_name(print_method)}(')
if expr is ast.ComptimeSelector {
key_str := g.get_comptime_selector_key_type(expr)
if key_str != '' {
Expand Down
6 changes: 3 additions & 3 deletions vlib/v/gen/c/json.v
Expand Up @@ -400,7 +400,7 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
if variant_sym.kind == .enum_ {
enc.writeln('\t\tcJSON_AddItemToObject(o, "${unmangled_variant_name}", ${js_enc_name('u64')}(*${var_data}${field_op}_${variant_typ}));')
} else if variant_sym.name == 'time.Time' {
enc.writeln('\t\tcJSON_AddItemToObject(o, "${unmangled_variant_name}", ${js_enc_name('i64')}(${var_data}${field_op}_${variant_typ}->_v_unix));')
enc.writeln('\t\tcJSON_AddItemToObject(o, "${unmangled_variant_name}", ${js_enc_name('i64')}(${var_data}${field_op}_${variant_typ}->__v_unix));')
} else {
enc.writeln('\t\tcJSON_AddItemToObject(o, "${unmangled_variant_name}", ${js_enc_name(variant_typ)}(*${var_data}${field_op}_${variant_typ}));')
}
Expand All @@ -425,7 +425,7 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
}
} else if variant_sym.name == 'time.Time' {
enc.writeln('\t\tcJSON_AddItemToObject(o, "_type", cJSON_CreateString("${unmangled_variant_name}"));')
enc.writeln('\t\tcJSON_AddItemToObject(o, "value", ${js_enc_name('i64')}(val${field_op}_${variant_typ}->_v_unix));')
enc.writeln('\t\tcJSON_AddItemToObject(o, "value", ${js_enc_name('i64')}(val${field_op}_${variant_typ}->__v_unix));')
} else {
enc.writeln('\t\to = ${js_enc_name(variant_typ)}(*val${field_op}_${variant_typ});')
enc.writeln('\t\tcJSON_AddItemToObject(o, "_type", cJSON_CreateString("${unmangled_variant_name}"));')
Expand Down Expand Up @@ -832,7 +832,7 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
if field_sym.name == 'time.Time' {
// time struct requires special treatment
// it has to be encoded as a unix timestamp number
enc.writeln('${indent}cJSON_AddItemToObject(o, "${name}", json__encode_u64(${prefix_enc}${op}${c_name(field.name)}._v_unix));')
enc.writeln('${indent}cJSON_AddItemToObject(o, "${name}", json__encode_u64(${prefix_enc}${op}${c_name(field.name)}.__v_unix));')
} else {
if !field.typ.is_any_kind_of_pointer() {
if field_sym.kind == .alias && field.typ.has_flag(.option) {
Expand Down
10 changes: 10 additions & 0 deletions vlib/v/tests/var_name_using_reserved_test.v
@@ -0,0 +1,10 @@
fn test_var_name_using_reserved() {
error := {
0: 1
1: 2
2: 3
}
ret := error[4] or { 42 }
println(ret)
assert ret == 42
}

0 comments on commit 0966fd3

Please sign in to comment.