From 0ef038332d5da2dcfd3fe9f020b85ea4cec2f18e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezgi=20=C3=87i=C3=A7ek?= Date: Wed, 5 Jun 2019 10:02:44 -0700 Subject: [PATCH] [purity] More models for Java Map Reviewed By: mbouaziz Differential Revision: D15659378 fbshipit-source-id: 2fa613281 --- infer/src/checkers/purityModels.ml | 5 +++++ .../hoistingExpensive/HoistExpensive.java | 21 +++++++++++++++++++ .../java/hoistingExpensive/issues.exp | 11 +++++----- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/infer/src/checkers/purityModels.ml b/infer/src/checkers/purityModels.ml index 7ee2fca4a..c86bfa721 100644 --- a/infer/src/checkers/purityModels.ml +++ b/infer/src/checkers/purityModels.ml @@ -132,7 +132,12 @@ module ProcName = struct ; +PatternMatch.implements_map &:: "isEmpty" <>--> PurityDomain.pure ; +PatternMatch.implements_map &:: "get" <>--> PurityDomain.pure ; +PatternMatch.implements_map &:: "put" <>--> modifies_first + ; +PatternMatch.implements_map &:: "putAll" <>--> modifies_first ; +PatternMatch.implements_map &:: "containsKey" <>--> PurityDomain.pure + ; +PatternMatch.implements_map &:: "keySet" <>--> PurityDomain.pure + ; +PatternMatch.implements_map &:: "values" <>--> PurityDomain.pure + ; +PatternMatch.implements_map &:: "entrySet" <>--> PurityDomain.pure + ; +PatternMatch.implements_map &:: "size" <>--> PurityDomain.pure ; +PatternMatch.implements_map_entry &:: "getKey" <>--> PurityDomain.pure ; +PatternMatch.implements_map_entry &:: "getValue" <>--> PurityDomain.pure ; +PatternMatch.implements_queue &:: "poll" <>--> modifies_first diff --git a/infer/tests/codetoanalyze/java/hoistingExpensive/HoistExpensive.java b/infer/tests/codetoanalyze/java/hoistingExpensive/HoistExpensive.java index d5f2e844d..38f76649e 100644 --- a/infer/tests/codetoanalyze/java/hoistingExpensive/HoistExpensive.java +++ b/infer/tests/codetoanalyze/java/hoistingExpensive/HoistExpensive.java @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ import java.util.ArrayList; +import java.util.Map; class HoistExpensive { @@ -48,4 +49,24 @@ class HoistExpensive { cheap_iterator_dont_hoist(list); } } + + private Map mLeakObjectResults; + + class Foo { + + String className; + } + + public String getLeakSummary() { + + StringBuilder leakedObjectSB = new StringBuilder(); + for (String key : mLeakObjectResults.keySet()) { + leakedObjectSB + .append(key) + .append(",") + .append(mLeakObjectResults.get(key).className) + .append("\n"); + } + return leakedObjectSB.toString(); + } } diff --git a/infer/tests/codetoanalyze/java/hoistingExpensive/issues.exp b/infer/tests/codetoanalyze/java/hoistingExpensive/issues.exp index c37d964ae..56782fa8a 100644 --- a/infer/tests/codetoanalyze/java/hoistingExpensive/issues.exp +++ b/infer/tests/codetoanalyze/java/hoistingExpensive/issues.exp @@ -1,14 +1,15 @@ codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.cheap_dont_hoist(int):void, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function void HoistExpensive.cheap_dont_hoist(int)] -codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.cheap_dont_hoist(int):void, 3, INVARIANT_CALL, no_bucket, ERROR, [The call to int HoistExpensive.incr(int) at line 19 is loop-invariant] +codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.cheap_dont_hoist(int):void, 3, INVARIANT_CALL, no_bucket, ERROR, [The call to int HoistExpensive.incr(int) at line 20 is loop-invariant] codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.cheap_iterator_dont_hoist(java.util.ArrayList):void, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function void HoistExpensive.cheap_iterator_dont_hoist(ArrayList)] -codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.cheap_iterator_dont_hoist(java.util.ArrayList):void, 3, INVARIANT_CALL, no_bucket, ERROR, [The call to int HoistExpensive.incr(int) at line 41 is loop-invariant] +codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.cheap_iterator_dont_hoist(java.util.ArrayList):void, 3, INVARIANT_CALL, no_bucket, ERROR, [The call to int HoistExpensive.incr(int) at line 42 is loop-invariant] +codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.getLeakSummary():java.lang.String, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function String HoistExpensive.getLeakSummary()] codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.incr(int):int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistExpensive.incr(int)] codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.instantiated_cheap_hoist(int):void, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function void HoistExpensive.instantiated_cheap_hoist(int)] -codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.instantiated_cheap_hoist(int):void, 2, INVARIANT_CALL, no_bucket, ERROR, [The call to void HoistExpensive.cheap_dont_hoist(int) at line 33 is loop-invariant] +codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.instantiated_cheap_hoist(int):void, 2, INVARIANT_CALL, no_bucket, ERROR, [The call to void HoistExpensive.cheap_dont_hoist(int) at line 34 is loop-invariant] codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.symbolic_expensive_hoist(int):void, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function void HoistExpensive.symbolic_expensive_hoist(int)] -codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.symbolic_expensive_hoist(int):void, 2, EXPENSIVE_LOOP_INVARIANT_CALL, no_bucket, ERROR, [The call to void HoistExpensive.cheap_dont_hoist(int) at line 26 is loop-invariant,with estimated cost 6 + 11 ⋅ size, degree = 1,{size},call to void HoistExpensive.cheap_dont_hoist(int),Loop at line 18] +codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.symbolic_expensive_hoist(int):void, 2, EXPENSIVE_LOOP_INVARIANT_CALL, no_bucket, ERROR, [The call to void HoistExpensive.cheap_dont_hoist(int) at line 27 is loop-invariant,with estimated cost 6 + 11 ⋅ size, degree = 1,{size},call to void HoistExpensive.cheap_dont_hoist(int),Loop at line 19] codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.symbolic_expensive_iterator_hoist(int,java.util.ArrayList):void, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function void HoistExpensive.symbolic_expensive_iterator_hoist(int,ArrayList)] -codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.symbolic_expensive_iterator_hoist(int,java.util.ArrayList):void, 2, EXPENSIVE_LOOP_INVARIANT_CALL, no_bucket, ERROR, [The call to void HoistExpensive.cheap_iterator_dont_hoist(ArrayList) at line 48 is loop-invariant,with estimated cost 7 + 14 ⋅ (list.length - 1) + 3 ⋅ list.length, degree = 1,{list.length},call to void HoistExpensive.cheap_iterator_dont_hoist(ArrayList),Loop at line 40,{list.length - 1},call to void HoistExpensive.cheap_iterator_dont_hoist(ArrayList),Loop at line 40] +codetoanalyze/java/hoistingExpensive/HoistExpensive.java, HoistExpensive.symbolic_expensive_iterator_hoist(int,java.util.ArrayList):void, 2, EXPENSIVE_LOOP_INVARIANT_CALL, no_bucket, ERROR, [The call to void HoistExpensive.cheap_iterator_dont_hoist(ArrayList) at line 49 is loop-invariant,with estimated cost 7 + 14 ⋅ (list.length - 1) + 3 ⋅ list.length, degree = 1,{list.length},call to void HoistExpensive.cheap_iterator_dont_hoist(ArrayList),Loop at line 41,{list.length - 1},call to void HoistExpensive.cheap_iterator_dont_hoist(ArrayList),Loop at line 41] codetoanalyze/java/hoistingExpensive/HoistModeled.java, HoistModeled.call_expensive_hoist(java.lang.String,java.util.ArrayList,java.lang.Integer):void, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function void HoistModeled.call_expensive_hoist(String,ArrayList,Integer)] codetoanalyze/java/hoistingExpensive/HoistModeled.java, HoistModeled.call_expensive_hoist(java.lang.String,java.util.ArrayList,java.lang.Integer):void, 2, EXPENSIVE_LOOP_INVARIANT_CALL, no_bucket, ERROR, [The call to void HoistModeled.expensive_get_hoist(int) at line 58 is loop-invariant,with estimated cost 85 + 10 ⋅ Provider.get().modeled.ub, degree = 1,{Provider.get().modeled.ub},call to void HoistModeled.expensive_get_hoist(int),Modeled call to Provider.get] codetoanalyze/java/hoistingExpensive/HoistModeled.java, HoistModeled.constant_contains_dont_hoist(java.lang.Integer):void, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function void HoistModeled.constant_contains_dont_hoist(Integer)]