Skip to content

Commit a55e930

Browse files
committed
checker: fix pointer checks in translated code
1 parent cc227d8 commit a55e930

File tree

2 files changed

+30
-21
lines changed

2 files changed

+30
-21
lines changed

vlib/v/checker/checker.v

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -804,8 +804,12 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
804804
left_name := c.table.type_to_str(left_type)
805805
right_name := c.table.type_to_str(right_type)
806806
if left_name == right_name {
807-
c.error('undefined operation `$left_name` $node.op.str() `$right_name`',
808-
left_right_pos)
807+
if !(node.op == .lt && c.pref.translated) {
808+
// Allow `&Foo < &Foo` in translated code.
809+
// TODO maybe in unsafe as well?
810+
c.error('undefined operation `$left_name` $node.op.str() `$right_name`',
811+
left_right_pos)
812+
}
809813
} else {
810814
c.error('mismatched types `$left_name` and `$right_name`', left_right_pos)
811815
}

vlib/v/checker/fn.v

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -801,18 +801,18 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
801801
continue
802802
}
803803

804-
typ := c.check_expr_opt_call(call_arg.expr, c.expr(call_arg.expr))
805-
node.args[i].typ = typ
804+
arg_typ := c.check_expr_opt_call(call_arg.expr, c.expr(call_arg.expr))
805+
node.args[i].typ = arg_typ
806806
if c.inside_comptime_for_field {
807807
if mut call_arg.expr is ast.Ident {
808808
if mut call_arg.expr.obj is ast.Var {
809809
node.args[i].typ = call_arg.expr.obj.typ
810810
}
811811
}
812812
}
813-
typ_sym := c.table.sym(typ)
813+
arg_typ_sym := c.table.sym(arg_typ)
814814
param_typ_sym := c.table.sym(param.typ)
815-
if func.is_variadic && typ.has_flag(.variadic) && node.args.len - 1 > i {
815+
if func.is_variadic && arg_typ.has_flag(.variadic) && node.args.len - 1 > i {
816816
c.error('when forwarding a variadic variable, it must be the final argument',
817817
call_arg.pos)
818818
}
@@ -846,7 +846,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
846846
c.error('function `$node.name` parameter `$param.name` is `$tok`, so use `$tok $call_arg.expr` instead',
847847
call_arg.expr.pos())
848848
} else {
849-
c.fail_if_unreadable(call_arg.expr, typ, 'argument')
849+
c.fail_if_unreadable(call_arg.expr, arg_typ, 'argument')
850850
}
851851
}
852852
mut final_param_sym := param_typ_sym
@@ -871,22 +871,23 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
871871
}
872872
// Handle expected interface
873873
if final_param_sym.kind == .interface_ {
874-
if c.type_implements(typ, final_param_typ, call_arg.expr.pos()) {
875-
if !typ.is_ptr() && !typ.is_pointer() && !c.inside_unsafe
876-
&& typ_sym.kind != .interface_ {
874+
if c.type_implements(arg_typ, final_param_typ, call_arg.expr.pos()) {
875+
if !arg_typ.is_ptr() && !arg_typ.is_pointer() && !c.inside_unsafe
876+
&& arg_typ_sym.kind != .interface_ {
877877
c.mark_as_referenced(mut &call_arg.expr, true)
878878
}
879879
}
880880
continue
881881
}
882-
c.check_expected_call_arg(typ, c.unwrap_generic(param.typ), node.language, call_arg) or {
882+
c.check_expected_call_arg(arg_typ, c.unwrap_generic(param.typ), node.language,
883+
call_arg) or {
883884
// str method, allow type with str method if fn arg is string
884885
// Passing an int or a string array produces a c error here
885886
// Deleting this condition results in propper V error messages
886887
// if arg_typ_sym.kind == .string && typ_sym.has_method('str') {
887888
// continue
888889
// }
889-
if typ_sym.kind == .void && param_typ_sym.kind == .string {
890+
if arg_typ_sym.kind == .void && param_typ_sym.kind == .string {
890891
continue
891892
}
892893
if param.typ.has_flag(.generic) {
@@ -895,10 +896,10 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
895896
if c.pref.translated || c.file.is_translated {
896897
// TODO duplicated logic in check_types() (check_types.v)
897898
// Allow enums to be used as ints and vice versa in translated code
898-
if param.typ == ast.int_type && typ_sym.kind == .enum_ {
899+
if param.typ == ast.int_type && arg_typ_sym.kind == .enum_ {
899900
continue
900901
}
901-
if typ == ast.int_type && param_typ_sym.kind == .enum_ {
902+
if arg_typ == ast.int_type && param_typ_sym.kind == .enum_ {
902903
continue
903904
}
904905
// In C unsafe number casts are used all the time (e.g. `char*` where
@@ -907,35 +908,39 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
907908
if param.typ.is_ptr() {
908909
param_is_number = param.typ.deref().is_number()
909910
}
910-
mut typ_is_number := typ.is_number()
911-
if typ.is_ptr() {
912-
typ_is_number = typ.deref().is_number()
911+
mut typ_is_number := arg_typ.is_number()
912+
if arg_typ.is_ptr() {
913+
typ_is_number = arg_typ.deref().is_number()
913914
}
914915
if param_is_number && typ_is_number {
915916
continue
916917
}
917918
// Allow voidptrs for everything
918-
if param.typ == ast.voidptr_type_idx || typ == ast.voidptr_type_idx {
919+
if param.typ == ast.voidptr_type_idx || arg_typ == ast.voidptr_type_idx {
919920
continue
920921
}
921922
// Allow `[32]i8` as `&i8` etc
922-
if (typ_sym.kind == .array_fixed && param_is_number)
923+
if (arg_typ_sym.kind == .array_fixed && param_is_number)
923924
|| (param_typ_sym.kind == .array_fixed && typ_is_number) {
924925
continue
925926
}
926927
// Allow `int` as `&i8`
927928
if param.typ.is_any_kind_of_pointer() && typ_is_number {
928929
continue
929930
}
931+
// Allow `&i8` as `int`
932+
if arg_typ.is_any_kind_of_pointer() && param_is_number {
933+
continue
934+
}
930935
}
931936
c.error('$err.msg() in argument ${i + 1} to `$fn_name`', call_arg.pos)
932937
}
933938
// Warn about automatic (de)referencing, which will be removed soon.
934-
if func.language != .c && !c.inside_unsafe && typ.nr_muls() != param.typ.nr_muls()
939+
if func.language != .c && !c.inside_unsafe && arg_typ.nr_muls() != param.typ.nr_muls()
935940
&& !(call_arg.is_mut && param.is_mut) && !(!call_arg.is_mut && !param.is_mut)
936941
&& param.typ !in [ast.byteptr_type, ast.charptr_type, ast.voidptr_type] {
937942
// sym := c.table.sym(typ)
938-
c.warn('automatic referencing/dereferencing is deprecated and will be removed soon (got: $typ.nr_muls() references, expected: $param.typ.nr_muls() references)',
943+
c.warn('automatic referencing/dereferencing is deprecated and will be removed soon (got: $arg_typ.nr_muls() references, expected: $param.typ.nr_muls() references)',
939944
call_arg.pos)
940945
}
941946
}

0 commit comments

Comments
 (0)