diff --git a/infer/src/bufferoverrun/absLoc.ml b/infer/src/bufferoverrun/absLoc.ml index 4247667a2..08330065c 100644 --- a/infer/src/bufferoverrun/absLoc.ml +++ b/infer/src/bufferoverrun/absLoc.ml @@ -124,9 +124,11 @@ module Loc = struct Allocsite.pp_paren ~paren fmt a | Field (Allocsite (Allocsite.Symbol (SP.Deref (SP.Deref_CPointer, p))), f) | Field (Allocsite (Allocsite.Known {path= Some (SP.Deref (SP.Deref_CPointer, p))}), f) -> - F.fprintf fmt "%a->%s" (SP.pp_partial_paren ~paren:true) p (Typ.Fieldname.to_flat_string f) + BufferOverrunField.pp ~pp_lhs:(SP.pp_partial_paren ~paren:true) + ~pp_lhs_alone:(SP.pp_pointer ~paren) ~sep:"->" fmt p f | Field (l, f) -> - F.fprintf fmt "%a.%s" (pp_paren ~paren:true) l (Typ.Fieldname.to_flat_string f) + BufferOverrunField.pp ~pp_lhs:(pp_paren ~paren:true) ~pp_lhs_alone:(pp_paren ~paren) + ~sep:"." fmt l f let pp = pp_paren ~paren:false diff --git a/infer/src/bufferoverrun/bufferOverrunField.ml b/infer/src/bufferoverrun/bufferOverrunField.ml new file mode 100644 index 000000000..eb981afcc --- /dev/null +++ b/infer/src/bufferoverrun/bufferOverrunField.ml @@ -0,0 +1,17 @@ +(* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) +open! IStd +module F = Format + +(** + If fn is empty, prints [pp_lhs_alone lhs] + Otherwise prints [pp_lhs lhs ^ sep ^ fn] +*) +let pp ~pp_lhs ~pp_lhs_alone ~sep f lhs fn = + let fieldname = Typ.Fieldname.to_flat_string fn in + if String.is_empty fieldname then pp_lhs_alone f lhs + else F.fprintf f "%a%s%s" pp_lhs lhs sep fieldname diff --git a/infer/src/bufferoverrun/symb.ml b/infer/src/bufferoverrun/symb.ml index a7f629009..f8179cfd8 100644 --- a/infer/src/bufferoverrun/symb.ml +++ b/infer/src/bufferoverrun/symb.ml @@ -60,17 +60,23 @@ module SymbolPath = struct | Deref (Deref_ArrayIndex, p) -> F.fprintf fmt "%a[*]" (pp_partial_paren ~paren:true) p | Deref (Deref_CPointer, p) -> - if paren then F.fprintf fmt "(" ; - F.fprintf fmt "*%a" (pp_partial_paren ~paren:false) p ; - if paren then F.fprintf fmt ")" + pp_pointer ~paren fmt p | Field (fn, Deref (Deref_CPointer, p)) -> - F.fprintf fmt "%a->%s" (pp_partial_paren ~paren:true) p (Typ.Fieldname.to_flat_string fn) + BufferOverrunField.pp ~pp_lhs:(pp_partial_paren ~paren:true) + ~pp_lhs_alone:(pp_pointer ~paren) ~sep:"->" fmt p fn | Field (fn, p) -> - F.fprintf fmt "%a.%s" (pp_partial_paren ~paren:true) p (Typ.Fieldname.to_flat_string fn) + BufferOverrunField.pp ~pp_lhs:(pp_partial_paren ~paren:true) + ~pp_lhs_alone:(pp_partial_paren ~paren) ~sep:"." fmt p fn | Callsite {cs} -> F.fprintf fmt "%s" (Typ.Procname.to_simplified_string ~withclass:true (CallSite.pname cs)) + and pp_pointer ~paren fmt p = + if paren then F.fprintf fmt "(" ; + F.fprintf fmt "*%a" (pp_partial_paren ~paren:false) p ; + if paren then F.fprintf fmt ")" + + let pp_partial = pp_partial_paren ~paren:false let pp fmt = function diff --git a/infer/src/bufferoverrun/symb.mli b/infer/src/bufferoverrun/symb.mli index 11a9789e9..e5a2deaf5 100644 --- a/infer/src/bufferoverrun/symb.mli +++ b/infer/src/bufferoverrun/symb.mli @@ -34,6 +34,8 @@ module SymbolPath : sig val pp_partial_paren : paren:bool -> F.formatter -> partial -> unit + val pp_pointer : paren:bool -> F.formatter -> partial -> unit + val of_pvar : Pvar.t -> partial val of_callsite : ret_typ:Typ.t -> CallSite.t -> partial