From 9f7cb87bb0aa32623dbd283547cbbaffafe77508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1zaro=20Clapp=20Jim=C3=A9nez=20Labora?= Date: Tue, 19 Jul 2016 18:17:22 -0700 Subject: [PATCH] Add stacktrace extras to BoundedCallTree checker. Reviewed By: sblackshear Differential Revision: D3589871 fbshipit-source-id: 93c3df9 --- infer/src/checkers/BoundedCallTree.ml | 17 ++++++++++----- infer/src/checkers/registerCheckers.ml | 1 - infer/src/unit/BoundedCallTreeTests.ml | 29 ++++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/infer/src/checkers/BoundedCallTree.ml b/infer/src/checkers/BoundedCallTree.ml index bb0bfea71..72ff056a1 100644 --- a/infer/src/checkers/BoundedCallTree.ml +++ b/infer/src/checkers/BoundedCallTree.ml @@ -25,11 +25,18 @@ module Domain = AbstractDomain.FiniteSet(ProcnameSet) module TransferFunctions (CFG : ProcCfg.S) = struct module CFG = CFG module Domain = Domain - type extras = ProcData.no_extras + type extras = Stacktrace.t - let exec_instr astate _ _ = function + let exec_instr astate proc_data _ = function | Sil.Call (_, Const (Const.Cfun pn), _, _, _) -> - Domain.add pn astate + (** TODO: Match class. *) + let caller = Cfg.Procdesc.get_proc_name proc_data.ProcData.pdesc in + let matches_proc frame = + frame.Stacktrace.method_str = (Procname.get_method caller) in + let proc_in_trace = IList.exists + matches_proc + proc_data.ProcData.extras.Stacktrace.frames in + if proc_in_trace then Domain.add pn astate else astate | Sil.Call _ -> (** We currently ignore calls through function pointers in C and * other potential special kinds of procedure calls to be added later, @@ -46,5 +53,5 @@ module Analyzer = (Scheduler.ReversePostorder) (TransferFunctions) -let checker { Callbacks.proc_desc; tenv; } = - ignore(Analyzer.exec_pdesc (ProcData.make_default proc_desc tenv)) +let checker { Callbacks.proc_desc; tenv; } trace = + ignore(Analyzer.exec_pdesc (ProcData.make proc_desc tenv trace)) diff --git a/infer/src/checkers/registerCheckers.ml b/infer/src/checkers/registerCheckers.ml index 66618e28b..269e9a5be 100644 --- a/infer/src/checkers/registerCheckers.ml +++ b/infer/src/checkers/registerCheckers.ml @@ -39,7 +39,6 @@ let active_procedure_checkers () = PrintfArgs.callback_printf_args, checkers_enabled; AnnotationReachability.Interprocedural.check_and_report, checkers_enabled; Checkers.callback_print_access_to_globals, false; - BoundedCallTree.checker, false; ] in IList.map (fun (x, y) -> (x, y, Some Config.Java)) l in let c_cpp_checkers = diff --git a/infer/src/unit/BoundedCallTreeTests.ml b/infer/src/unit/BoundedCallTreeTests.ml index 291a11a30..9f9aece7f 100644 --- a/infer/src/unit/BoundedCallTreeTests.ml +++ b/infer/src/unit/BoundedCallTreeTests.ml @@ -23,7 +23,15 @@ let tests = let g_proc_name = Procname.from_string_c_fun "g" in let g_args = [((Sil.Const (Const.Cint (IntLit.one))), (Typ.Tint IInt))] in let g_ret_ids = [(ident_of_str "r")] in - let test_list = [ + let class_name = "com.example.SomeClass" in + let file_name = "SomeClass.java" in + let trace = Stacktrace.make "java.lang.NullPointerException" + [Stacktrace.make_frame class_name "foo" file_name 16; + Stacktrace.make_frame class_name "bar" file_name 20] in + let caller_foo_name = Procname.from_string_c_fun "foo" in + let caller_bar_name = Procname.from_string_c_fun "bar" in + let caller_baz_name = Procname.from_string_c_fun "baz" in + let test_list_from_foo = [ "on_call_add_proc_name", [ make_call ~procname:f_proc_name [] []; (* means f() *) @@ -48,5 +56,22 @@ let tests = make_call ~procname:f_proc_name [] []; invariant "{ f }" ]; - ] |> TestInterpreter.create_tests ProcData.empty_extras in + ] |> TestInterpreter.create_tests ~test_pname:caller_foo_name trace in + let test_list_from_bar = [ + "on_call_anywhere_on_stack_add_proc_name", + [ + make_call ~procname:f_proc_name [] []; (* means f() *) + invariant "{ f }" + ]; + ] |> TestInterpreter.create_tests ~test_pname:caller_bar_name trace in + let test_list_from_baz = [ + "ignore_procs_unrelated_to_trace", + [ + make_call ~procname:f_proc_name [] []; (* means f() *) + invariant "{ }" + ]; + ] |> TestInterpreter.create_tests ~test_pname:caller_baz_name trace in + let test_list = test_list_from_foo @ + test_list_from_bar @ + test_list_from_baz in "bounded_calltree_test_suite">:::test_list