diff --git a/infer/src/checkers/copyPropagation.ml b/infer/src/checkers/copyPropagation.ml index a57cb3d4a..6b326a2e2 100644 --- a/infer/src/checkers/copyPropagation.ml +++ b/infer/src/checkers/copyPropagation.ml @@ -87,9 +87,6 @@ module TransferFunctions = struct let postprocess = TransferFunctions.no_postprocessing let exec_instr astate _ = function - | Sil.Letderef (lhs_id, Sil.Var rhs_id, _, _) -> - (* note: logical vars are SSA, don't need to worry about overwriting existing bindings *) - Domain.gen (LogicalVar lhs_id) (LogicalVar rhs_id) astate | Sil.Letderef (lhs_id, Sil.Lvar rhs_pvar, _, _) when not (Pvar.is_global rhs_pvar) -> Domain.gen (LogicalVar lhs_id) (ProgramVar rhs_pvar) astate | Sil.Set (Sil.Lvar lhs_pvar, _, Sil.Var rhs_id, _) when not (Pvar.is_global lhs_pvar) -> @@ -97,12 +94,15 @@ module TransferFunctions = struct | Sil.Set (Sil.Lvar lhs_pvar, _, Sil.Lvar rhs_pvar, _) when not (Pvar.is_global lhs_pvar || Pvar.is_global rhs_pvar) -> Domain.kill_then_gen (ProgramVar lhs_pvar) (ProgramVar rhs_pvar) astate - | Sil.Letderef (lhs_id, _, _, _) -> - (* non-copy assignment (or assignment to global); can only kill *) - Domain.kill_copies_with_var (LogicalVar lhs_id) astate | Sil.Set (Sil.Lvar lhs_pvar, _, _, _) -> (* non-copy assignment (or assignment to global); can only kill *) Domain.kill_copies_with_var (ProgramVar lhs_pvar) astate + | Sil.Letderef _ + (* lhs = *rhs where rhs isn't a pvar (or is a global). in any case, not a copy *) + (* note: since logical vars can't be reassigned, don't need to kill bindings for lhs id *) + | Sil.Set (Var _, _, _, _) -> + (* *lhs = rhs. not a copy, and not a write to lhs *) + astate | Sil.Call (ret_ids, _, actuals, _, _) -> let kill_ret_ids astate_acc id = Domain.kill_copies_with_var (LogicalVar id) astate_acc in @@ -113,9 +113,6 @@ module TransferFunctions = struct if !Config.curr_language = Config.Java then astate' (* Java doesn't have pass-by-reference *) else IList.fold_left kill_actuals_by_ref astate' actuals - | Sil.Set (Sil.Var _, _, _, _) -> - (* this should never happen *) - assert false | Sil.Set _ | Sil.Prune _ | Sil.Nullify _ | Sil.Abstract _ | Sil.Remove_temps _ | Sil.Declare_locals _ | Sil.Stackop _ -> (* none of these can assign to program vars or logical vars *) diff --git a/infer/src/unit/analyzerTester.ml b/infer/src/unit/analyzerTester.ml index 0e4d2c094..678f69e91 100644 --- a/infer/src/unit/analyzerTester.ml +++ b/infer/src/unit/analyzerTester.ml @@ -104,6 +104,11 @@ module StructuredSil = struct let rhs_exp = var_of_str rhs in make_letderef ~rhs_typ lhs_id rhs_exp + let id_set_id ?(rhs_typ=dummy_typ) lhs_id rhs_id = + let lhs_exp = Sil.Var (ident_of_str lhs_id) in + let rhs_exp = Sil.Var (ident_of_str rhs_id) in + make_set ~rhs_typ ~lhs_exp ~rhs_exp + let var_assign_exp ~rhs_typ lhs rhs_exp = let lhs_exp = var_of_str lhs in make_set ~rhs_typ ~lhs_exp ~rhs_exp diff --git a/infer/src/unit/copyPropagationTests.ml b/infer/src/unit/copyPropagationTests.ml index 97aaf10cc..b9e992d55 100644 --- a/infer/src/unit/copyPropagationTests.ml +++ b/infer/src/unit/copyPropagationTests.ml @@ -32,10 +32,23 @@ let tests = id_assign_id "a" "a"; assert_empty ]; - "id_assign_id_gen", + "id_letderef_id_no_gen", [ - id_assign_id "b" "a"; - invariant "{ b$0 -> a$0 }" + id_assign_id "b" "a"; (* means b = *a *) + assert_empty + ]; + "id_set_id_no_gen", + [ + id_set_id "b" "a"; (* means *b = a *) + assert_empty + ]; + + "id_set_id_no_kill", + [ + id_assign_var "b" "a"; + invariant "{ b$0 -> &a }"; + id_set_id "b" "x"; + invariant "{ b$0 -> &a }" ]; "id_assign_var_gen", [ diff --git a/infer/src/unit/livenessTests.ml b/infer/src/unit/livenessTests.ml index 000b44b27..fefaa7e07 100644 --- a/infer/src/unit/livenessTests.ml +++ b/infer/src/unit/livenessTests.ml @@ -30,11 +30,6 @@ let tests = let unknown_cond = (* don't want to use AnalyzerTest.unknown_exp because we'll treat it as a live var! *) Sil.exp_zero in - let id_set_id lhs_id rhs_id = - let lhs_exp = Sil.Var (ident_of_str lhs_id) in - let rhs_exp = Sil.Var (ident_of_str rhs_id) in - let rhs_typ = dummy_typ in - make_set ~rhs_typ ~lhs_exp ~rhs_exp in let test_list = [ "basic_live", [