diff --git a/infer/src/cost/cost.ml b/infer/src/cost/cost.ml index 7f011dd56..924453b24 100644 --- a/infer/src/cost/cost.ml +++ b/infer/src/cost/cost.ml @@ -188,6 +188,9 @@ module WorstCaseCost = struct | Some (ThresholdReports.Threshold threshold), Some cost when should_report_cost cost ~threshold -> Some (ThresholdReports.ReportOn {location= InstrCFG.Node.loc instr_node; cost}) + | Some (ThresholdReports.ReportOn {cost= prev}), Some cost + when (not (BasicCost.is_top cost)) && BasicCost.compare_by_degree prev cost < 0 -> + Some (ThresholdReports.ReportOn {location= InstrCFG.Node.loc instr_node; cost}) | _ -> threshold_or_report_opt ) reports costs diff --git a/infer/tests/codetoanalyze/java/performance/Cost_test.java b/infer/tests/codetoanalyze/java/performance/Cost_test.java index 6f6bec6bb..e9dd6d815 100644 --- a/infer/tests/codetoanalyze/java/performance/Cost_test.java +++ b/infer/tests/codetoanalyze/java/performance/Cost_test.java @@ -210,6 +210,11 @@ public class Cost_test { void mult_symbols_quadratic(int x, int y) { for (int i = 0; i < x * y; i++) {} } + + void call_mult_symbold_quadratic(int n) { + for (int i = 0; i < n; i++) {} + mult_symbols_quadratic(n, n); + } } class CloneTest { diff --git a/infer/tests/codetoanalyze/java/performance/issues.exp b/infer/tests/codetoanalyze/java/performance/issues.exp index 5458e0165..2d9c3ca60 100644 --- a/infer/tests/codetoanalyze/java/performance/issues.exp +++ b/infer/tests/codetoanalyze/java/performance/issues.exp @@ -93,6 +93,8 @@ codetoanalyze/java/performance/Continue.java, codetoanalyze.java.performance.Con codetoanalyze/java/performance/Cost_test.java, codetoanalyze.java.performance.Cost_test.FN_loop2(int):int, 0, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 2 + 13 ⋅ k, O(k), degree = 1,{k},Loop at line 92] codetoanalyze/java/performance/Cost_test.java, codetoanalyze.java.performance.Cost_test.band_constant(int):void, 0, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 1277, O(1), degree = 0] codetoanalyze/java/performance/Cost_test.java, codetoanalyze.java.performance.Cost_test.call_inputstream_read_linear(java.io.InputStream):void, 3, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 27304, O(1), degree = 0] +codetoanalyze/java/performance/Cost_test.java, codetoanalyze.java.performance.Cost_test.call_mult_symbold_quadratic(int):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 14 + 5 ⋅ n + 6 ⋅ n², O(n²), degree = 2,{n},call to void Cost_test.mult_symbols_quadratic(int,int),Loop at line 211,{n},call to void Cost_test.mult_symbols_quadratic(int,int),Loop at line 211,{n},Loop at line 215] +codetoanalyze/java/performance/Cost_test.java, codetoanalyze.java.performance.Cost_test.call_mult_symbold_quadratic(int):void, 1, INTEGER_OVERFLOW_L5, no_bucket, ERROR, [Assignment,Call,,Assignment,Binary operation: ([0, +oo] + 1):signed32 by call to `void Cost_test.mult_symbols_quadratic(int,int)` ] codetoanalyze/java/performance/Cost_test.java, codetoanalyze.java.performance.Cost_test.ignore_boolean_symbols_linear(boolean,int):void, 0, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 2 + 6 ⋅ n + 2 ⋅ (1+max(0, n)), O(n), degree = 1,{1+max(0, n)},Loop at line 135,{n},Loop at line 135] codetoanalyze/java/performance/Cost_test.java, codetoanalyze.java.performance.Cost_test.loop0_bad():int, 0, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 1202, O(1), degree = 0] codetoanalyze/java/performance/Cost_test.java, codetoanalyze.java.performance.Cost_test.loop1_bad():int, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 1303, O(1), degree = 0]