diff --git a/infer/src/checkers/control.ml b/infer/src/checkers/control.ml index 07f93de57..2d2f5120f 100644 --- a/infer/src/checkers/control.ml +++ b/infer/src/checkers/control.ml @@ -76,18 +76,13 @@ module TransferFunctionsControlDeps (CFG : ProcCfg.S) = struct let get_vars_in_exp exp prune_node loop_head = - let global_control_vars = + let program_control_vars = Exp.program_vars exp - |> Sequence.fold ~init:ControlDepSet.empty ~f:(fun global_acc pvar -> - let cvar = Var.of_pvar pvar in - if Pvar.is_global pvar then ControlDepSet.add {cvar; loop_head} global_acc - else - Logging.die InternalError - "We should never have non-global program variables in prune nodes: %a@." Var.pp - cvar ) + |> Sequence.fold ~init:ControlDepSet.empty ~f:(fun acc pvar -> + ControlDepSet.add {cvar= Var.of_pvar pvar; loop_head} acc ) in Exp.free_vars exp - |> Sequence.fold ~init:global_control_vars ~f:(fun acc id -> + |> Sequence.fold ~init:program_control_vars ~f:(fun acc id -> match Procdesc.Node.find_in_node_or_preds prune_node ~f:(find_vars_in_decl id loop_head) with diff --git a/infer/src/checkers/loopInvariant.ml b/infer/src/checkers/loopInvariant.ml index f93c8bb7e..b966cc2a3 100644 --- a/infer/src/checkers/loopInvariant.ml +++ b/infer/src/checkers/loopInvariant.ml @@ -100,6 +100,9 @@ let get_vars_in_loop loop_nodes = Var.get_all_vars_in_exp arg_exp |> Sequence.fold ~init:acc ~f:(fun acc var -> VarsInLoop.add var acc) ) args + | Sil.Prune (exp, _, _, _) -> + Var.get_all_vars_in_exp exp + |> Sequence.fold ~init:acc ~f:(fun acc var -> VarsInLoop.add var acc) | _ -> acc ) ~init:acc ) diff --git a/infer/tests/codetoanalyze/c/performance/issues.exp b/infer/tests/codetoanalyze/c/performance/issues.exp index b7fc549b6..94672d915 100644 --- a/infer/tests/codetoanalyze/c/performance/issues.exp +++ b/infer/tests/codetoanalyze/c/performance/issues.exp @@ -63,6 +63,7 @@ codetoanalyze/c/performance/loops.c, if_in_loop, 5, INTEGER_OVERFLOW_L5, no_buck codetoanalyze/c/performance/loops.c, if_out_loop, 7, EXPENSIVE_EXECUTION_CALL, no_bucket, ERROR, [with estimated cost 615, degree = 0] codetoanalyze/c/performance/loops.c, larger_state_FN, 3, EXPENSIVE_EXECUTION_CALL, no_bucket, ERROR, [with estimated cost 1006, degree = 0] codetoanalyze/c/performance/loops.c, loop_use_global_vars, 1, EXPENSIVE_EXECUTION_CALL, no_bucket, ERROR, [with estimated cost 3 + 4 ⋅ x + 2 ⋅ (1+max(0, x)), degree = 1,{1+max(0, x)},Loop at line 69, column 3,{x},Loop at line 69, column 3] +codetoanalyze/c/performance/loops.c, ptr_cmp, 2, EXPENSIVE_EXECUTION_CALL, no_bucket, ERROR, [with estimated cost 5 + 5 ⋅ size + 2 ⋅ (2+max(-1, size)), degree = 1,{2+max(-1, size)},Loop at line 76, column 3,{size},Loop at line 76, column 3] codetoanalyze/c/performance/purity.c, loop, 2, EXPENSIVE_EXECUTION_CALL, no_bucket, ERROR, [with estimated cost 7006, degree = 0] codetoanalyze/c/performance/switch_continue.c, test_switch, 3, CONDITION_ALWAYS_TRUE, no_bucket, WARNING, [Here] codetoanalyze/c/performance/switch_continue.c, test_switch, 3, EXPENSIVE_EXECUTION_CALL, no_bucket, ERROR, [with estimated cost 602, degree = 0] diff --git a/infer/tests/codetoanalyze/c/performance/loops.c b/infer/tests/codetoanalyze/c/performance/loops.c index a71118b74..4adee58e8 100644 --- a/infer/tests/codetoanalyze/c/performance/loops.c +++ b/infer/tests/codetoanalyze/c/performance/loops.c @@ -70,3 +70,12 @@ void loop_use_global_vars(int x) { // do something } } + +void ptr_cmp(char* end, int size) { + char buf[2] = "hi"; + for (int i = 0; i < size; i += 2) { + if (buf < end) { // pvar &buf occurs directly in prune node + return; + } + } +}