From 15534be574f02713bff2e0d80713cdd3a75fd511 Mon Sep 17 00:00:00 2001 From: Sam Blackshear Date: Wed, 13 Jul 2016 06:31:39 -0700 Subject: [PATCH] eliminate tmp vars in resource leak error message Reviewed By: dulmarod Differential Revision: D3551198 fbshipit-source-id: 2758f56 --- infer/src/IR/Sil.re | 17 +++++++++++++++++ infer/src/IR/Sil.rei | 4 ++++ infer/src/backend/errdesc.ml | 14 +++++++------- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/infer/src/IR/Sil.re b/infer/src/IR/Sil.re index 4e9c37ca4..5f1f2cdad 100644 --- a/infer/src/IR/Sil.re +++ b/infer/src/IR/Sil.re @@ -987,6 +987,23 @@ let const_kind_equal c1 c2 => { const_kind_number c1 == const_kind_number c2 }; +let rec dexp_has_tmp_var = + fun + | Dpvar pvar + | Dpvaraddr pvar => Pvar.is_frontend_tmp pvar + | Dderef dexp + | Ddot dexp _ + | Darrow dexp _ + | Dunop _ dexp + | Dsizeof _ (Some dexp) _ => dexp_has_tmp_var dexp + | Darray dexp1 dexp2 + | Dbinop _ dexp1 dexp2 => dexp_has_tmp_var dexp1 || dexp_has_tmp_var dexp2 + | Dretcall dexp dexp_list _ _ + | Dfcall dexp dexp_list _ _ => dexp_has_tmp_var dexp || IList.exists dexp_has_tmp_var dexp_list + | Dconst _ + | Dunknown + | Dsizeof _ None _ => false; + let rec attribute_compare (att1: attribute) (att2: attribute) :int => switch (att1, att2) { | (Aresource ra1, Aresource ra2) => diff --git a/infer/src/IR/Sil.rei b/infer/src/IR/Sil.rei index 142644b4f..8e4491594 100644 --- a/infer/src/IR/Sil.rei +++ b/infer/src/IR/Sil.rei @@ -511,6 +511,10 @@ let binop_invert: binop => exp => exp => exp; The return value false means "don't know". */ let binop_is_zero_runit: binop => bool; + +/** return true if [dexp] contains a temporary pvar */ +let dexp_has_tmp_var: dexp => bool; + let mem_kind_compare: mem_kind => mem_kind => int; let attribute_compare: attribute => attribute => int; diff --git a/infer/src/backend/errdesc.ml b/infer/src/backend/errdesc.ml index 5ea4be778..df9c0260d 100644 --- a/infer/src/backend/errdesc.ml +++ b/infer/src/backend/errdesc.ml @@ -507,16 +507,16 @@ let explain_leak tenv hpred prop alloc_att_opt bucket = Some desc_string end else match vpath with - | Some de -> + | Some de when not (Sil.dexp_has_tmp_var de) -> Some (Sil.dexp_to_string de) - | None -> None in + | _ -> None in let res_action_opt, resource_opt, vpath = match alloc_att_opt with | Some (Sil.Aresource ({ Sil.ra_kind = Sil.Racquire } as ra)) -> Some ra, Some ra.Sil.ra_res, ra.Sil.ra_vpath | _ -> (None, None, None) in let is_file = match resource_opt with | Some Sil.Rfile -> true - | _ -> false in + | _ -> false in let check_pvar pvar = (* check that pvar is local or global and has the same type as the leaked hpred *) (Pvar.is_local pvar || Pvar.is_global pvar) && @@ -541,8 +541,8 @@ let explain_leak tenv hpred prop alloc_att_opt bucket = (L.d_str "explain_leak: current instruction is Nullify for pvar "; Pvar.d pvar; L.d_ln ()); (match exp_lv_dexp (State.get_node ()) (Sil.Lvar pvar) with - | None -> None - | Some de -> Some (Sil.dexp_to_string de)) + | Some de when not (Sil.dexp_has_tmp_var de)-> Some (Sil.dexp_to_string de) + | _ -> None) | Some (Sil.Abstract _) -> if verbose then (L.d_str "explain_leak: current instruction is Abstract"; L.d_ln ()); let get_nullify = function @@ -563,8 +563,8 @@ let explain_leak tenv hpred prop alloc_att_opt bucket = (L.d_str "explain_leak: current instruction Set for "; Sil.d_exp lexp; L.d_ln ()); (match exp_lv_dexp node lexp with - | Some dexp -> Some (Sil.dexp_to_string dexp) - | None -> None) + | Some dexp when not (Sil.dexp_has_tmp_var dexp) -> Some (Sil.dexp_to_string dexp) + | _ -> None) | Some instr -> if verbose then