Revert "[clang] Removing the case of flagging npes in initialisers. This causes many FPs."

Summary:
This reverts commit 306f5b71c24042c89f71848898402cbc9269c543.
Turns out that developers think that this bugs should be fixed. So leaving it in for now until I gather more information.
master
Dulma Rodriguez 10 years ago
parent 18173a7b7f
commit 63b1d1ac1c

@ -821,8 +821,9 @@ let check_inconsistency_base prop =
Sil.pvar_is_seed pv Sil.pvar_is_seed pv
| _ -> false in | _ -> false in
list_exists do_hpred sigma in list_exists do_hpred sigma in
let inconsistent_self () = (* "self" cannot be null in ObjC *) let inconsistent_self () = (* "self" cannot be null in ObjC, outside of initializers *)
let procdesc = Cfg.Node.get_proc_desc (State.get_node ()) in let procdesc = Cfg.Node.get_proc_desc (State.get_node ()) in
let procname = Cfg.Procdesc.get_proc_name procdesc in
let procedure_attr = Cfg.Procdesc.get_attributes procdesc in let procedure_attr = Cfg.Procdesc.get_attributes procdesc in
let do_hpred = function let do_hpred = function
| Sil.Hpointsto (Sil.Lvar pv, Sil.Eexp (e, _), _) -> | Sil.Hpointsto (Sil.Lvar pv, Sil.Eexp (e, _), _) ->
@ -830,7 +831,8 @@ let check_inconsistency_base prop =
Sil.exp_equal e Sil.exp_zero && Sil.exp_equal e Sil.exp_zero &&
Sil.pvar_is_seed pv && Sil.pvar_is_seed pv &&
Sil.pvar_get_name pv = Mangled.from_string "self" && Sil.pvar_get_name pv = Mangled.from_string "self" &&
procedure_attr.Sil.is_objc_instance_method procedure_attr.Sil.is_objc_instance_method &&
not (Procname.is_constructor procname)
| _ -> false in | _ -> false in
list_exists do_hpred sigma in list_exists do_hpred sigma in
let inconsistent_atom = function let inconsistent_atom = function

@ -784,6 +784,13 @@ let handle_special_cases_call tenv cfg pname actual_params =
else pname, actual_params else pname, actual_params
let handle_objc_method_call actual_pars actual_params pre tenv cfg ret_ids pdesc callee_pname loc path = let handle_objc_method_call actual_pars actual_params pre tenv cfg ret_ids pdesc callee_pname loc path =
let receiver_self receiver prop =
list_exists (fun hpred ->
match hpred with
| Sil.Hpointsto (Sil.Lvar pv, Sil.Eexp (e, _), _) ->
Sil.exp_equal e receiver && Sil.pvar_is_seed pv &&
Sil.pvar_get_name pv = Mangled.from_string "self"
| _ -> false) (Prop.get_sigma prop) in
let path_description = "Message "^(Procname.to_simplified_string callee_pname)^" with receiver nil returns nil." in let path_description = "Message "^(Procname.to_simplified_string callee_pname)^" with receiver nil returns nil." in
let receiver = (match actual_pars with let receiver = (match actual_pars with
| (e, _):: _ -> e | (e, _):: _ -> e
@ -793,6 +800,10 @@ let handle_objc_method_call actual_pars actual_params pre tenv cfg ret_ids pdesc
match actual_pars with match actual_pars with
| (e, _):: _ when Sil.exp_equal e Sil.exp_zero || Option.is_some (Prop.get_objc_null_attribute pre e) -> true | (e, _):: _ when Sil.exp_equal e Sil.exp_zero || Option.is_some (Prop.get_objc_null_attribute pre e) -> true
| _ -> false in | _ -> false in
let prop_null =
match ret_ids with
| [ret_id] -> Prop.conjoin_eq (Sil.Var ret_id) Sil.exp_zero pre
| _ -> pre in
let add_objc_null_attribute_or_nullify_result prop = let add_objc_null_attribute_or_nullify_result prop =
match ret_ids with match ret_ids with
| [ret_id] -> | [ret_id] ->
@ -815,16 +826,22 @@ let handle_objc_method_call actual_pars actual_params pre tenv cfg ret_ids pdesc
| _ -> false in | _ -> false in
if !Config.footprint && not is_undef then if !Config.footprint && not is_undef then
let res_null = (* returns: (objc_null(res) /\ receiver=0) or an empty list of results *) let res_null = (* returns: (objc_null(res) /\ receiver=0) or an empty list of results *)
let pre_with_attr_or_null = add_objc_null_attribute_or_nullify_result pre in let is_receiver_self = receiver_self receiver pre in
let pre_with_attr_or_null =
if is_receiver_self then prop_null
else add_objc_null_attribute_or_nullify_result pre in
let propset = prune_ne tenv false receiver Sil.exp_zero pre_with_attr_or_null in let propset = prune_ne tenv false receiver Sil.exp_zero pre_with_attr_or_null in
if Propset.is_empty propset then [] if Propset.is_empty propset then []
else else
let prop = list_hd (Propset.to_proplist propset) in let prop = list_hd (Propset.to_proplist propset) in
let path = Paths.Path.add_description path path_description in let path =
if is_receiver_self then path
else Paths.Path.add_description path path_description in
[(prop, path)] in [(prop, path)] in
res_null @ res res_null @ res
else res (* Not known if receiver = 0 and not footprint. Standard tabulation *) else res (* Not known if receiver = 0 and not footprint. Standard tabulation *)
let normalize_params pdesc prop actual_params = let normalize_params pdesc prop actual_params =
let norm_arg (p, args) (e, t) = let norm_arg (p, args) (e, t) =
let e', p' = exp_norm_check_arith pdesc p e in let e', p' = exp_norm_check_arith pdesc p e in
@ -832,6 +849,7 @@ let normalize_params pdesc prop actual_params =
let prop, args = list_fold_left norm_arg (prop, []) actual_params in let prop, args = list_fold_left norm_arg (prop, []) actual_params in
(prop, list_rev args) (prop, list_rev args)
(** Execute [instr] with a symbolic heap [prop].*) (** Execute [instr] with a symbolic heap [prop].*)
let rec sym_exec cfg tenv pdesc _instr (_prop: Prop.normal Prop.t) path let rec sym_exec cfg tenv pdesc _instr (_prop: Prop.normal Prop.t) path
: (Prop.normal Prop.t * Paths.Path.t) list = : (Prop.normal Prop.t * Paths.Path.t) list =
@ -1146,7 +1164,7 @@ and call_unknown_or_scan is_scan cfg pdesc tenv pre path
let do_exp p (e, t) = let do_exp p (e, t) =
let do_attribute q = function let do_attribute q = function
| Sil.Aresource res_action as res | Sil.Aresource res_action as res
when res_action.Sil.ra_res = Sil.Rfile -> when res_action.Sil.ra_res = Sil.Rfile ->
Prop.remove_attribute res q Prop.remove_attribute res q
| _ -> q in | _ -> q in
list_fold_left do_attribute p (Prop.get_exp_attributes p e) in list_fold_left do_attribute p (Prop.get_exp_attributes p e) in

@ -60,8 +60,8 @@ public class NPESelfTest {
throws InterruptedException, IOException, InferException { throws InterruptedException, IOException, InferException {
InferResults inferResults = InferRunner.runInferObjC(inferCmdNPD); InferResults inferResults = InferRunner.runInferObjC(inferCmdNPD);
assertThat( assertThat(
"NPE should not be found", inferResults, "NPE should be found", inferResults,
doesNotContain( contains(
NULL_DEREFERENCE, NULL_DEREFERENCE,
NPE_FILE, NPE_FILE,
"init")); "init"));

Loading…
Cancel
Save