From 606a3c95d9d9ca4b9ae7015b9c991c04e4d20ed3 Mon Sep 17 00:00:00 2001 From: Joscha Benz Date: Thu, 19 Nov 2020 02:29:53 -0800 Subject: [PATCH] Add a config option to whitelist common initializer values for liveness analysis (#1340) Summary: Implements https://github.com/facebook/infer/issues/1083 Pull Request resolved: https://github.com/facebook/infer/pull/1340 Reviewed By: mityal Differential Revision: D24956747 Pulled By: jvillard fbshipit-source-id: 820eb538a --- infer/man/man1/infer-analyze.txt | 3 +++ infer/man/man1/infer-full.txt | 7 ++++++ infer/man/man1/infer.txt | 4 +++ infer/src/base/Config.ml | 8 ++++++ infer/src/base/Config.mli | 2 ++ infer/src/checkers/liveness.ml | 25 ++++++++++++++++--- .../codetoanalyze/cpp/liveness/.inferconfig | 1 + .../cpp/liveness/dead_stores.cpp | 6 +++++ 8 files changed, 53 insertions(+), 3 deletions(-) diff --git a/infer/man/man1/infer-analyze.txt b/infer/man/man1/infer-analyze.txt index ea677cabb..c6fe760df 100644 --- a/infer/man/man1/infer-analyze.txt +++ b/infer/man/man1/infer-analyze.txt @@ -200,6 +200,9 @@ OPTIONS Deactivates: checker liveness: Detection of dead stores and unused variables. (Conversely: --liveness) + --liveness-ignored-constant +string + List of integer constants to be ignored by liveness analysis + --liveness-only Activates: Enable liveness and disable all other checkers (Conversely: --no-liveness-only) diff --git a/infer/man/man1/infer-full.txt b/infer/man/man1/infer-full.txt index b34f7f8ea..6ebc30f56 100644 --- a/infer/man/man1/infer-full.txt +++ b/infer/man/man1/infer-full.txt @@ -790,6 +790,10 @@ OPTIONS unique_ptr) will count as dead stores when the variables are not read explicitly by the program. See also infer-analyze(1). + --liveness-ignored-constant +string + List of integer constants to be ignored by liveness analysis + See also infer-analyze(1). + --liveness-only Activates: Enable liveness and disable all other checkers (Conversely: --no-liveness-only) See also infer-analyze(1). @@ -1597,6 +1601,9 @@ INTERNAL OPTIONS --linters-doc-url-reset Set --linters-doc-url to the empty list. + --liveness-ignored-constant-reset + Set --liveness-ignored-constant to the empty list. + --load-average-reset Cancel the effect of --load-average. diff --git a/infer/man/man1/infer.txt b/infer/man/man1/infer.txt index bc63dd730..c778b685e 100644 --- a/infer/man/man1/infer.txt +++ b/infer/man/man1/infer.txt @@ -790,6 +790,10 @@ OPTIONS unique_ptr) will count as dead stores when the variables are not read explicitly by the program. See also infer-analyze(1). + --liveness-ignored-constant +string + List of integer constants to be ignored by liveness analysis + See also infer-analyze(1). + --liveness-only Activates: Enable liveness and disable all other checkers (Conversely: --no-liveness-only) See also infer-analyze(1). diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 38e817398..2a846c5a4 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -1497,6 +1497,12 @@ and liveness_dangerous_classes = by the program." +and liveness_ignored_constant = + CLOpt.mk_string_list ~default:["0"] ~long:"liveness-ignored-constant" + ~in_help:InferCommand.[(Analyze, manual_generic)] + "List of integer constants to be ignored by liveness analysis" + + and _log_events = CLOpt.mk_bool ~long:"" ~deprecated:["-log-events"] ~deprecated_no:["-no-log-events"] "[DOES NOTHING] Turn on the feature that logs events in a machine-readable format" @@ -2962,6 +2968,8 @@ and list_issue_types = !list_issue_types and liveness_dangerous_classes = !liveness_dangerous_classes +and liveness_ignored_constant = !liveness_ignored_constant + and load_average = match !load_average with None when !buck -> Some (float_of_int ncpu) | _ -> !load_average diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index dbfb0ece8..e9c4103fe 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -376,6 +376,8 @@ val list_issue_types : bool val liveness_dangerous_classes : Yojson.Basic.t +val liveness_ignored_constant : string list + val max_nesting : int option val merge : bool diff --git a/infer/src/checkers/liveness.ml b/infer/src/checkers/liveness.ml index ed15a69f5..103528439 100644 --- a/infer/src/checkers/liveness.ml +++ b/infer/src/checkers/liveness.ml @@ -212,6 +212,21 @@ let get_captured_by_ref_invariant_map proc_desc = CapturedByRefAnalyzer.exec_cfg cfg () ~initial:VarSet.empty +module IntLitSet = Caml.Set.Make (IntLit) + +let ignored_constants = + let int_lit_constants = + List.map + ~f:(fun el -> + try IntLit.of_string el + with Invalid_argument _ -> + L.die UserError + "Ill-formed option '%s' for --liveness-ignored-constant: an integer was expected" el ) + Config.liveness_ignored_constant + in + IntLitSet.of_list int_lit_constants + + let checker {IntraproceduralAnalysis.proc_desc; err_log} = let captured_by_ref_invariant_map = get_captured_by_ref_invariant_map proc_desc in let cfg = CFG.from_pdesc proc_desc in @@ -223,9 +238,13 @@ let checker {IntraproceduralAnalysis.proc_desc; err_log} = | Exp.Cast (_, e) -> is_sentinel_exp e | Exp.Const (Cint i) -> - IntLit.iszero i || IntLit.isnull i - | Exp.Const (Cfloat 0.0) -> - true + IntLitSet.mem i ignored_constants + | Exp.Const (Cfloat f) -> ( + match Z.of_float f with + | z -> + IntLitSet.mem (IntLit.of_big_int z) ignored_constants + | exception Z.Overflow -> + false ) | _ -> false in diff --git a/infer/tests/codetoanalyze/cpp/liveness/.inferconfig b/infer/tests/codetoanalyze/cpp/liveness/.inferconfig index 6a8eb0b6a..ac6ffd6ba 100644 --- a/infer/tests/codetoanalyze/cpp/liveness/.inferconfig +++ b/infer/tests/codetoanalyze/cpp/liveness/.inferconfig @@ -1,4 +1,5 @@ { + "liveness-ignored-constant" : ["44"], "liveness-dangerous-classes": [ "dead_stores::BlacklistedStruct" ], diff --git a/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp b/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp index 3cd12f752..ca60a04ce 100644 --- a/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp +++ b/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp @@ -609,4 +609,10 @@ void switch_with_temporary_ok() { }; } +void ignored_constants_ok() { + int x = 0; + float f = 0.0; + int z = 44; +} + } // namespace dead_stores