[nullsafe][refactor] Simplify and document code processing particular part of prune instruction

Summary:
This refactoring is made possible by previous stack, which ensured we
don't do two completely different things in one code anymore (processing
results of functions returning booleans and objects in generic fashion).

Follow up diffs will clean up the code for Prune(a != zero) case.

Reviewed By: dulmarod

Differential Revision: D19745050

fbshipit-source-id: 61d3d02ad
master
Mitya Lyubarskiy 5 years ago committed by Facebook Github Bot
parent a55179ba80
commit 2001d39e9a

@ -50,7 +50,6 @@ type from_call =
| From_condition (** Direct condition *) | From_condition (** Direct condition *)
| From_instanceof (** x instanceof C *) | From_instanceof (** x instanceof C *)
| From_is_false_on_null (** returns false on null *) | From_is_false_on_null (** returns false on null *)
| From_is_true_on_null (** returns true on null *)
| From_containsKey (** x.containsKey *) | From_containsKey (** x.containsKey *)
[@@deriving compare] [@@deriving compare]

@ -735,29 +735,30 @@ let rec check_condition_for_sil_prune tenv idenv calls_this find_canonical_dupli
typestate2 typestate2
in in
match[@warning "-57"] c with match[@warning "-57"] c with
| Exp.BinOp (Binop.Eq, Exp.Const (Const.Cint i), e) | Exp.BinOp (Binop.Eq, Exp.Const (Const.Cint i), expr)
| Exp.BinOp (Binop.Eq, e, Exp.Const (Const.Cint i)) | Exp.BinOp (Binop.Eq, expr, Exp.Const (Const.Cint i))
when IntLit.iszero i -> ( when IntLit.iszero i -> (
let typestate1, e1, from_call = (* Zero literal has two different meanings important for Nullsafe:
match from_is_true_on_null e with `null` and `false`.
| Some e1 -> We don't currently have a logic for `a == null` case, but `a == false` is important.
(typestate, e1, EradicateChecks.From_is_true_on_null) *)
| None -> match from_is_true_on_null expr with
(typestate, e, EradicateChecks.From_condition) | Some argument ->
in (* [expr] is a call to function known to return true on `null`.
let e', typestate2 = According to PRUNE semantics, we just ensured that the result is `false`.
It means that [argument] can not be `null`, hence we can infer its nullability as a non-null.
*)
(* Trace the origin of [argument] back to pvar that originated it, so its nullability can be updated in typestate. *)
let pvar_expr, updated_typestate =
convert_complex_exp_to_pvar tenv idenv curr_pname curr_annotated_signature ~node convert_complex_exp_to_pvar tenv idenv curr_pname curr_annotated_signature ~node
~original_node ~is_assignment:false e1 typestate1 loc ~original_node ~is_assignment:false argument typestate loc
in in
match from_call with set_nonnull pvar_expr updated_typestate
| EradicateChecks.From_is_true_on_null -> | None ->
(* if f returns true on null, then false branch implies != null *) typestate )
set_nonnull e' typestate2
| _ ->
typestate2 )
| Exp.BinOp (Binop.Ne, Exp.Const (Const.Cint i), e) | Exp.BinOp (Binop.Ne, Exp.Const (Const.Cint i), e)
| Exp.BinOp (Binop.Ne, e, Exp.Const (Const.Cint i)) | Exp.BinOp (Binop.Ne, e, Exp.Const (Const.Cint i))
when IntLit.iszero i -> ( when IntLit.iszero i ->
let typestate1, e1, from_call = let typestate1, e1, from_call =
match from_instanceof e with match from_instanceof e with
| Some e1 -> | Some e1 ->
@ -785,14 +786,7 @@ let rec check_condition_for_sil_prune tenv idenv calls_this find_canonical_dupli
EradicateChecks.check_condition_for_redundancy ~is_always_true:true_branch tenv EradicateChecks.check_condition_for_redundancy ~is_always_true:true_branch tenv
find_canonical_duplicate curr_pdesc original_node e' typ inferred_nullability idenv find_canonical_duplicate curr_pdesc original_node e' typ inferred_nullability idenv
linereader loc instr_ref ; linereader loc instr_ref ;
match from_call with set_nonnull e' typestate2
| EradicateChecks.From_is_true_on_null ->
typestate2
| EradicateChecks.From_condition
| EradicateChecks.From_containsKey
| EradicateChecks.From_instanceof
| EradicateChecks.From_is_false_on_null ->
set_nonnull e' typestate2 )
| Exp.UnOp (Unop.LNot, Exp.BinOp (Binop.Eq, e1, e2), _) -> | Exp.UnOp (Unop.LNot, Exp.BinOp (Binop.Eq, e1, e2), _) ->
check_condition_for_sil_prune tenv idenv calls_this find_canonical_duplicate loc curr_pname check_condition_for_sil_prune tenv idenv calls_this find_canonical_duplicate loc curr_pname
curr_pdesc curr_annotated_signature linereader typestate checks true_branch instr_ref curr_pdesc curr_annotated_signature linereader typestate checks true_branch instr_ref

Loading…
Cancel
Save