[Inferbo] remove redundant alarm message

Summary:
This diff removes redundant alarm message of intra-procedural
alarms from Inferbo.

Reviewed By: mbouaziz

Differential Revision: D5154319

fbshipit-source-id: bc1c827
master
Kihong Heo 8 years ago committed by Facebook Github Bot
parent cc6b0f1e0b
commit 485814a75a

@ -31,6 +31,7 @@ let none file => {line: (-1), col: (-1), file};
let dummy = none (SourceFile.invalid __FILE__); let dummy = none (SourceFile.invalid __FILE__);
/** Pretty print a location */ /** Pretty print a location */
let pp f (loc: t) => F.fprintf f "[line %d]" loc.line; let pp f (loc: t) => F.fprintf f "[line %d]" loc.line;
@ -42,3 +43,11 @@ let to_string loc => {
s s
} }
}; };
/** Pretty print a file-position of a location */
let pp_file_pos f (loc: t) => {
let fname = SourceFile.to_string loc.file;
let pos = to_string loc;
F.fprintf f "%s:%s" fname pos
};

@ -38,3 +38,7 @@ let pp: Format.formatter => t => unit;
/** String representation of a location. */ /** String representation of a location. */
let to_string: t => string; let to_string: t => string;
/** Pretty print a file-position of a location */
let pp_file_pos: Format.formatter => t => unit;

@ -21,6 +21,10 @@ let always_strong_update = true (* unsound but ok for bug catching *)
module Condition = module Condition =
struct struct
type trace = Intra of Typ.Procname.t
| Inter of Typ.Procname.t * Typ.Procname.t * Location.t
[@@deriving compare]
type t = { type t = {
proc_name : Typ.Procname.t; proc_name : Typ.Procname.t;
loc : Location.t; loc : Location.t;
@ -30,134 +34,124 @@ struct
size : Itv.astate; size : Itv.astate;
} }
[@@deriving compare] [@@deriving compare]
and trace = Intra of Typ.Procname.t
| Inter of Typ.Procname.t * Typ.Procname.t * Location.t type astate = t
[@@deriving compare]
let set_size_pos : t -> t
and astate = t = fun c ->
if Itv.Bound.lt (Itv.lb c.size) Itv.Bound.zero
let set_size_pos : t -> t then { c with size = Itv.make Itv.Bound.zero (Itv.ub c.size) }
= fun c -> else c
if Itv.Bound.lt (Itv.lb c.size) Itv.Bound.zero
then { c with size = Itv.make Itv.Bound.zero (Itv.ub c.size) } let pp_location : F.formatter -> t -> unit
else c = fun fmt c ->
Location.pp_file_pos fmt c.loc
let string_of_location : Location.t -> string
= fun loc -> let pp : F.formatter -> t -> unit
let fname = SourceFile.to_string loc.Location.file in = fun fmt c ->
let pos = Location.to_string loc in let c = set_size_pos c in
F.fprintf F.str_formatter "%s:%s" fname pos; if Config.bo_debug <= 1 then
F.flush_str_formatter () F.fprintf fmt "%a < %a at %a" Itv.pp c.idx Itv.pp c.size pp_location c
else
let pp_location : F.formatter -> t -> unit match c.trace with
= fun fmt c -> Inter (_, pname, loc) ->
F.fprintf fmt "%s" (string_of_location c.loc) let pname = Typ.Procname.to_string pname in
F.fprintf fmt "%a < %a at %a by call %s() at %a"
let pp : F.formatter -> t -> unit Itv.pp c.idx Itv.pp c.size pp_location c pname Location.pp_file_pos loc
= fun fmt c -> | Intra _ -> F.fprintf fmt "%a < %a at %a" Itv.pp c.idx Itv.pp c.size pp_location c
let c = set_size_pos c in
if Config.bo_debug <= 1 then let get_location : t -> Location.t
F.fprintf fmt "%a < %a at %a" Itv.pp c.idx Itv.pp c.size pp_location c = fun c -> c.loc
else
match c.trace with let get_trace : t -> trace
Inter (_, pname, loc) -> = fun c -> c.trace
let pname = Typ.Procname.to_string pname in
F.fprintf fmt "%a < %a at %a by call %s() at %s" let get_proc_name : t -> Typ.Procname.t
Itv.pp c.idx Itv.pp c.size pp_location c pname (string_of_location loc) = fun c -> c.proc_name
| Intra _ -> F.fprintf fmt "%a < %a at %a" Itv.pp c.idx Itv.pp c.size pp_location c
let make : Typ.Procname.t -> Location.t -> string -> idx:Itv.t -> size:Itv.t -> t
let get_location : t -> Location.t = fun proc_name loc id ~idx ~size ->
= fun c -> c.loc { proc_name; idx; size; loc; id ; trace = Intra proc_name }
let get_trace : t -> trace let filter1 : t -> bool
= fun c -> c.trace = fun c ->
Itv.eq c.idx Itv.top || Itv.eq c.size Itv.top
let get_proc_name : t -> Typ.Procname.t || Itv.Bound.eq (Itv.lb c.idx) Itv.Bound.MInf
= fun c -> c.proc_name || Itv.Bound.eq (Itv.lb c.size) Itv.Bound.MInf
|| (Itv.eq c.idx Itv.nat && Itv.eq c.size Itv.nat)
let make : Typ.Procname.t -> Location.t -> string -> idx:Itv.t -> size:Itv.t -> t
= fun proc_name loc id ~idx ~size -> let filter2 : t -> bool
{ proc_name; idx; size; loc; id ; trace = Intra proc_name } = fun c ->
(* basically, alarms involving infinity are filtered *)
let filter1 : t -> bool (not (Itv.is_finite c.idx) || not (Itv.is_finite c.size))
= fun c -> && (* except the following cases *)
Itv.eq c.idx Itv.top || Itv.eq c.size Itv.top not ((Itv.Bound.is_not_infty (Itv.lb c.idx) && (* idx non-infty lb < 0 *)
|| Itv.Bound.eq (Itv.lb c.idx) Itv.Bound.MInf Itv.Bound.lt (Itv.lb c.idx) Itv.Bound.zero)
|| Itv.Bound.eq (Itv.lb c.size) Itv.Bound.MInf ||
|| (Itv.eq c.idx Itv.nat && Itv.eq c.size Itv.nat) (Itv.Bound.is_not_infty (Itv.lb c.idx) && (* idx non-infty lb > size lb *)
(Itv.Bound.gt (Itv.lb c.idx) (Itv.lb c.size)))
let filter2 : t -> bool ||
= fun c -> (Itv.Bound.is_not_infty (Itv.lb c.idx) && (* idx non-infty lb > size ub *)
(* basically, alarms involving infinity are filtered *) (Itv.Bound.gt (Itv.lb c.idx) (Itv.ub c.size)))
(not (Itv.is_finite c.idx) || not (Itv.is_finite c.size)) ||
&& (* except the following cases *) (Itv.Bound.is_not_infty (Itv.ub c.idx) && (* idx non-infty ub > size lb *)
not ((Itv.Bound.is_not_infty (Itv.lb c.idx) && (* idx non-infty lb < 0 *) (Itv.Bound.gt (Itv.ub c.idx) (Itv.lb c.size)))
Itv.Bound.lt (Itv.lb c.idx) Itv.Bound.zero) ||
|| (Itv.Bound.is_not_infty (Itv.ub c.idx) && (* idx non-infty ub > size ub *)
(Itv.Bound.is_not_infty (Itv.lb c.idx) && (* idx non-infty lb > size lb *) (Itv.Bound.gt (Itv.ub c.idx) (Itv.ub c.size))))
(Itv.Bound.gt (Itv.lb c.idx) (Itv.lb c.size)))
|| (* check buffer overrun and return its confidence *)
(Itv.Bound.is_not_infty (Itv.lb c.idx) && (* idx non-infty lb > size ub *) let check : t -> string option
(Itv.Bound.gt (Itv.lb c.idx) (Itv.ub c.size))) = fun c ->
|| (* idx = [il, iu], size = [sl, su], we want to check that 0 <= idx < size *)
(Itv.Bound.is_not_infty (Itv.ub c.idx) && (* idx non-infty ub > size lb *) let c' = set_size_pos c in (* if sl < 0, use sl' = 0 *)
(Itv.Bound.gt (Itv.ub c.idx) (Itv.lb c.size))) let not_overrun = Itv.lt_sem c'.idx c'.size in
|| let not_underrun = Itv.le_sem Itv.zero c'.idx in
(Itv.Bound.is_not_infty (Itv.ub c.idx) && (* idx non-infty ub > size ub *) (* il >= 0 and iu < sl, definitely not an error *)
(Itv.Bound.gt (Itv.ub c.idx) (Itv.ub c.size)))) if Itv.eq not_overrun Itv.one && Itv.eq not_underrun Itv.one then
None
(* check buffer overrun and return its confidence *) (* iu < 0 or il >= su, definitely an error *)
let check : t -> string option else if Itv.eq not_overrun Itv.zero || Itv.eq not_underrun Itv.zero then
= fun c -> Some Localise.BucketLevel.b1
(* idx = [il, iu], size = [sl, su], we want to check that 0 <= idx < size *) (* su <= iu < +oo, most probably an error *)
let c' = set_size_pos c in (* if sl < 0, use sl' = 0 *) else if Itv.Bound.is_not_infty (Itv.ub c.idx)
let not_overrun = Itv.lt_sem c'.idx c'.size in && Itv.Bound.le (Itv.ub c.size) (Itv.ub c.idx) then
let not_underrun = Itv.le_sem Itv.zero c'.idx in Some Localise.BucketLevel.b2
(* il >= 0 and iu < sl, definitely not an error *) (* symbolic il >= sl, probably an error *)
if Itv.eq not_overrun Itv.one && Itv.eq not_underrun Itv.one then else if Itv.Bound.is_symbolic (Itv.lb c.idx)
None && Itv.Bound.le (Itv.lb c'.size) (Itv.lb c.idx) then
(* iu < 0 or il >= su, definitely an error *) Some Localise.BucketLevel.b3
else if Itv.eq not_overrun Itv.zero || Itv.eq not_underrun Itv.zero then (* other symbolic bounds are probably too noisy *)
Some Localise.BucketLevel.b1 else if Config.bo_debug <= 3 && (Itv.is_symbolic c.idx || Itv.is_symbolic c.size) then
(* su <= iu < +oo, most probably an error *) None
else if Itv.Bound.is_not_infty (Itv.ub c.idx) else if filter1 c then
&& Itv.Bound.le (Itv.ub c.size) (Itv.ub c.idx) then Some Localise.BucketLevel.b5
Some Localise.BucketLevel.b2 else if filter2 c then
(* symbolic il >= sl, probably an error *) Some Localise.BucketLevel.b3
else if Itv.Bound.is_symbolic (Itv.lb c.idx) else
&& Itv.Bound.le (Itv.lb c'.size) (Itv.lb c.idx) then Some Localise.BucketLevel.b2
Some Localise.BucketLevel.b3
(* other symbolic bounds are probably too noisy *) let invalid : t -> bool
else if Config.bo_debug <= 3 && (Itv.is_symbolic c.idx || Itv.is_symbolic c.size) then = fun x -> Itv.invalid x.idx || Itv.invalid x.size
None
else if filter1 c then let to_string : t -> string
Some Localise.BucketLevel.b5 = fun c ->
else if filter2 c then let c = set_size_pos c in
Some Localise.BucketLevel.b3 "Offset: " ^ Itv.to_string c.idx ^ " Size: " ^ Itv.to_string c.size
else ^ (match c.trace with
Some Localise.BucketLevel.b2 | Inter (_, pname, _) ->
let loc = pp_location F.str_formatter c; F.flush_str_formatter () in
let invalid : t -> bool " @ " ^ loc ^ " by call "
= fun x -> Itv.invalid x.idx || Itv.invalid x.size ^ MF.monospaced_to_string (Typ.Procname.to_string pname ^ "()") ^ " "
| Intra _ -> "")
let to_string : t -> string
= fun c -> let subst : t -> Itv.Bound.t Itv.SubstMap.t -> Typ.Procname.t -> Typ.Procname.t -> Location.t -> t
let c = set_size_pos c in = fun c subst_map caller_pname callee_pname loc ->
"Offset: " ^ Itv.to_string c.idx ^ " Size: " ^ Itv.to_string c.size if Itv.is_symbolic c.idx || Itv.is_symbolic c.size then
^ " @ " ^ string_of_location c.loc { c with idx = Itv.subst c.idx subst_map;
^ (match c.trace with size = Itv.subst c.size subst_map;
Inter (_, pname, _) -> trace = Inter (caller_pname, callee_pname, loc) }
" by call " else c
^ MF.monospaced_to_string (Typ.Procname.to_string pname ^ "()") ^ " "
| Intra _ -> "")
let subst : t -> Itv.Bound.t Itv.SubstMap.t -> Typ.Procname.t -> Typ.Procname.t -> Location.t -> t
= fun c subst_map caller_pname callee_pname loc ->
if Itv.is_symbolic c.idx || Itv.is_symbolic c.size then
{ c with idx = Itv.subst c.idx subst_map;
size = Itv.subst c.size subst_map;
trace = Inter (caller_pname, callee_pname, loc) }
else c
end end
module ConditionSet = module ConditionSet =

@ -1,20 +1,20 @@
codetoanalyze/c/bufferoverrun/array_dynlength.c, init_variable_array, 3, BUFFER_OVERRUN, [Offset: [3xs$0 + 1, 3xs$1 + 1] Size: [3xs$0 + 1, 3xs$1 + 1] @ codetoanalyze/c/bufferoverrun/array_dynlength.c:13:3] codetoanalyze/c/bufferoverrun/array_dynlength.c, init_variable_array, 3, BUFFER_OVERRUN, [Offset: [3xs$0 + 1, 3xs$1 + 1] Size: [3xs$0 + 1, 3xs$1 + 1]]
codetoanalyze/c/bufferoverrun/break_continue_return.c, break_continue_return, 16, BUFFER_OVERRUN, [Offset: [0, 10] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/break_continue_return.c:29:5] codetoanalyze/c/bufferoverrun/break_continue_return.c, break_continue_return, 16, BUFFER_OVERRUN, [Offset: [0, 10] Size: [10, 10]]
codetoanalyze/c/bufferoverrun/do_while.c, do_while, 2, BUFFER_OVERRUN, [Offset: [0, +oo] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/do_while.c:18:5 by call `do_while_sub()` ] codetoanalyze/c/bufferoverrun/do_while.c, do_while, 2, BUFFER_OVERRUN, [Offset: [0, +oo] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/do_while.c:18:5 by call `do_while_sub()` ]
codetoanalyze/c/bufferoverrun/do_while.c, do_while, 3, BUFFER_OVERRUN, [Offset: [0, +oo] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/do_while.c:18:5 by call `do_while_sub()` ] codetoanalyze/c/bufferoverrun/do_while.c, do_while, 3, BUFFER_OVERRUN, [Offset: [0, +oo] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/do_while.c:18:5 by call `do_while_sub()` ]
codetoanalyze/c/bufferoverrun/for_loop.c, for_loop, 10, BUFFER_OVERRUN, [Offset: [0, 9] Size: [5, 10] @ codetoanalyze/c/bufferoverrun/for_loop.c:38:5] codetoanalyze/c/bufferoverrun/for_loop.c, for_loop, 10, BUFFER_OVERRUN, [Offset: [0, 9] Size: [5, 10]]
codetoanalyze/c/bufferoverrun/function_call.c, call_by_ptr_good_FP, 4, BUFFER_OVERRUN, [Offset: [99, 99] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/function_call.c:36:3] codetoanalyze/c/bufferoverrun/function_call.c, call_by_ptr_good_FP, 4, BUFFER_OVERRUN, [Offset: [99, 99] Size: [10, 10]]
codetoanalyze/c/bufferoverrun/function_call.c, function_call, 4, BUFFER_OVERRUN, [Offset: [20, 20] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/function_call.c:18:3 by call `arr_access()` ] codetoanalyze/c/bufferoverrun/function_call.c, function_call, 4, BUFFER_OVERRUN, [Offset: [20, 20] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/function_call.c:18:3 by call `arr_access()` ]
codetoanalyze/c/bufferoverrun/function_call.c, function_call, 4, BUFFER_OVERRUN, [Offset: [100, 100] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/function_call.c:17:3 by call `arr_access()` ] codetoanalyze/c/bufferoverrun/function_call.c, function_call, 4, BUFFER_OVERRUN, [Offset: [100, 100] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/function_call.c:17:3 by call `arr_access()` ]
codetoanalyze/c/bufferoverrun/global.c, compare_global_variable_bad, 3, BUFFER_OVERRUN, [Offset: [10, 10] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/global.c:14:5] codetoanalyze/c/bufferoverrun/global.c, compare_global_variable_bad, 3, BUFFER_OVERRUN, [Offset: [10, 10] Size: [10, 10]]
codetoanalyze/c/bufferoverrun/goto_loop.c, goto_loop, 11, BUFFER_OVERRUN, [Offset: [10, +oo] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/goto_loop.c:24:3] codetoanalyze/c/bufferoverrun/goto_loop.c, goto_loop, 11, BUFFER_OVERRUN, [Offset: [10, +oo] Size: [10, 10]]
codetoanalyze/c/bufferoverrun/models.c, fgetc_255_bad, 4, BUFFER_OVERRUN, [Offset: [0, 255] Size: [255, 255] @ codetoanalyze/c/bufferoverrun/models.c:29:5] codetoanalyze/c/bufferoverrun/models.c, fgetc_255_bad, 4, BUFFER_OVERRUN, [Offset: [0, 255] Size: [255, 255]]
codetoanalyze/c/bufferoverrun/models.c, fgetc_m1_bad, 3, BUFFER_OVERRUN, [Offset: [-1, 255] Size: [10000, 10000] @ codetoanalyze/c/bufferoverrun/models.c:22:3] codetoanalyze/c/bufferoverrun/models.c, fgetc_m1_bad, 3, BUFFER_OVERRUN, [Offset: [-1, 255] Size: [10000, 10000]]
codetoanalyze/c/bufferoverrun/nested_loop.c, nested_loop, 7, BUFFER_OVERRUN, [Offset: [0, 10] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/nested_loop.c:20:7] codetoanalyze/c/bufferoverrun/nested_loop.c, nested_loop, 7, BUFFER_OVERRUN, [Offset: [0, 10] Size: [10, 10]]
codetoanalyze/c/bufferoverrun/nested_loop_with_label.c, nested_loop_with_label, 6, BUFFER_OVERRUN, [Offset: [0, +oo] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/nested_loop_with_label.c:19:5] codetoanalyze/c/bufferoverrun/nested_loop_with_label.c, nested_loop_with_label, 6, BUFFER_OVERRUN, [Offset: [0, +oo] Size: [10, 10]]
codetoanalyze/c/bufferoverrun/pointer_arith.c, pointer_arith_bad, 4, BUFFER_OVERRUN, [Offset: [10, 10] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/pointer_arith.c:14:5] codetoanalyze/c/bufferoverrun/pointer_arith.c, pointer_arith_bad, 4, BUFFER_OVERRUN, [Offset: [10, 10] Size: [10, 10]]
codetoanalyze/c/bufferoverrun/prune_alias.c, FP_prune_alias_exp_Ok, 4, BUFFER_OVERRUN, [Offset: [1, 1] Size: [1, 1] @ codetoanalyze/c/bufferoverrun/prune_alias.c:107:5] codetoanalyze/c/bufferoverrun/prune_alias.c, FP_prune_alias_exp_Ok, 4, BUFFER_OVERRUN, [Offset: [1, 1] Size: [1, 1]]
codetoanalyze/c/bufferoverrun/sizeof.c, eval_sizeof_bad, 4, BUFFER_OVERRUN, [Offset: [1, 1] Size: [0, 0] @ codetoanalyze/c/bufferoverrun/sizeof.c:16:5] codetoanalyze/c/bufferoverrun/sizeof.c, eval_sizeof_bad, 4, BUFFER_OVERRUN, [Offset: [1, 1] Size: [0, 0]]
codetoanalyze/c/bufferoverrun/sizeof.c, static_stride_bad, 7, BUFFER_OVERRUN, [Offset: [1, 1] Size: [0, 0] @ codetoanalyze/c/bufferoverrun/sizeof.c:32:5] codetoanalyze/c/bufferoverrun/sizeof.c, static_stride_bad, 7, BUFFER_OVERRUN, [Offset: [1, 1] Size: [0, 0]]
codetoanalyze/c/bufferoverrun/trivial.c, trivial, 2, BUFFER_OVERRUN, [Offset: [10, 10] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/trivial.c:15:3] codetoanalyze/c/bufferoverrun/trivial.c, trivial, 2, BUFFER_OVERRUN, [Offset: [10, 10] Size: [10, 10]]
codetoanalyze/c/bufferoverrun/while_loop.c, while_loop, 3, BUFFER_OVERRUN, [Offset: [0, +oo] Size: [10, 10] @ codetoanalyze/c/bufferoverrun/while_loop.c:16:10] codetoanalyze/c/bufferoverrun/while_loop.c, while_loop, 3, BUFFER_OVERRUN, [Offset: [0, +oo] Size: [10, 10]]

@ -1,5 +1,5 @@
codetoanalyze/cpp/bufferoverrun/function_call.cpp, call_by_ref_good_FP, 4, BUFFER_OVERRUN, [Offset: [99, 99] Size: [10, 10] @ codetoanalyze/cpp/bufferoverrun/function_call.cpp:18:3] codetoanalyze/cpp/bufferoverrun/function_call.cpp, call_by_ref_good_FP, 4, BUFFER_OVERRUN, [Offset: [99, 99] Size: [10, 10]]
codetoanalyze/cpp/bufferoverrun/simple_vector.cpp, instantiate_my_vector_oob_Ok, 3, BUFFER_OVERRUN, [Offset: [-oo, +oo] Size: [0, +oo] @ codetoanalyze/cpp/bufferoverrun/simple_vector.cpp:21:23 by call `my_vector_oob_Bad()` ] codetoanalyze/cpp/bufferoverrun/simple_vector.cpp, instantiate_my_vector_oob_Ok, 3, BUFFER_OVERRUN, [Offset: [-oo, +oo] Size: [0, +oo] @ codetoanalyze/cpp/bufferoverrun/simple_vector.cpp:21:23 by call `my_vector_oob_Bad()` ]
codetoanalyze/cpp/bufferoverrun/simple_vector.cpp, my_vector_oob_Bad, 2, BUFFER_OVERRUN, [Offset: [s$6, s$7] Size: [s$6, s$7] @ codetoanalyze/cpp/bufferoverrun/simple_vector.cpp:21:23 by call `int_vector_access_at()` ] codetoanalyze/cpp/bufferoverrun/simple_vector.cpp, my_vector_oob_Bad, 2, BUFFER_OVERRUN, [Offset: [s$6, s$7] Size: [s$6, s$7] @ codetoanalyze/cpp/bufferoverrun/simple_vector.cpp:21:23 by call `int_vector_access_at()` ]
codetoanalyze/cpp/bufferoverrun/trivial.cpp, trivial, 2, BUFFER_OVERRUN, [Offset: [10, 10] Size: [10, 10] @ codetoanalyze/cpp/bufferoverrun/trivial.cpp:15:3] codetoanalyze/cpp/bufferoverrun/trivial.cpp, trivial, 2, BUFFER_OVERRUN, [Offset: [10, 10] Size: [10, 10]]
codetoanalyze/cpp/bufferoverrun/vector.cpp, out_of_bound_Bad, 2, BUFFER_OVERRUN, [Offset: [s$14, s$15] Size: [s$14, s$15] @ INFER_MODEL/cpp/include/infer_model/vector_bufferoverrun.h:91:24 by call `std::vector<int,std::allocator<int>>_operator[]()` ] codetoanalyze/cpp/bufferoverrun/vector.cpp, out_of_bound_Bad, 2, BUFFER_OVERRUN, [Offset: [s$14, s$15] Size: [s$14, s$15] @ INFER_MODEL/cpp/include/infer_model/vector_bufferoverrun.h:91:24 by call `std::vector<int,std::allocator<int>>_operator[]()` ]

Loading…
Cancel
Save