diff --git a/infer/src/IR/ProcnameDispatcher.ml b/infer/src/IR/ProcnameDispatcher.ml index 98af77d53..15c8906a9 100644 --- a/infer/src/IR/ProcnameDispatcher.ml +++ b/infer/src/IR/ProcnameDispatcher.ml @@ -396,6 +396,11 @@ module type Common = sig -> ('context, 'f_in, 'f_out, 'captured_types, 'markers_in, 'markers_out) name_matcher (** Separates names (accepts ALL template arguments on the left one) *) + val ( &::+ ) : + ('context, 'f_in, 'f_out, 'captured_types, 'markers_in, 'markers_out) name_matcher + -> ('context -> string -> bool) + -> ('context, 'f_in, 'f_out, 'captured_types, 'markers_in, 'markers_out) name_matcher + val ( <>:: ) : ('context, 'f_in, 'f_out, 'captured_types, 'markers_in, 'markers_out) name_matcher -> string @@ -486,6 +491,8 @@ module Common = struct let ( &::! ) path_matcher name = name_cons path_matcher name + let ( &::+! ) path_matcher f_name = name_cons_f path_matcher f_name + let ( &::.*! ) path_matcher () = all_names_cons path_matcher let ( ~- ) name = empty &::! name @@ -506,6 +513,8 @@ module Common = struct let ( &:: ) name_matcher name = name_matcher <...>! () &::! name + let ( &::+ ) name_matcher f_name = name_matcher <...>! () &::+! f_name + let ( <>:: ) name_matcher name = name_matcher :: name end diff --git a/infer/src/IR/ProcnameDispatcher.mli b/infer/src/IR/ProcnameDispatcher.mli index d3d63cd2d..7b7dfe26b 100644 --- a/infer/src/IR/ProcnameDispatcher.mli +++ b/infer/src/IR/ProcnameDispatcher.mli @@ -165,6 +165,13 @@ module type Common = sig -> ('context, 'f_in, 'f_out, 'captured_types, 'markers_in, 'markers_out) name_matcher (** Separates names (accepts ALL template arguments on the left one) *) + val ( &::+ ) : + ('context, 'f_in, 'f_out, 'captured_types, 'markers_in, 'markers_out) name_matcher + -> ('context -> string -> bool) + -> ('context, 'f_in, 'f_out, 'captured_types, 'markers_in, 'markers_out) name_matcher + (** Separates names that satisfies the given function (accepts ALL + template arguments on the left one) *) + val ( <>:: ) : ('context, 'f_in, 'f_out, 'captured_types, 'markers_in, 'markers_out) name_matcher -> string diff --git a/infer/src/absint/PatternMatch.ml b/infer/src/absint/PatternMatch.ml index 61ebc5aa0..4e19794ec 100644 --- a/infer/src/absint/PatternMatch.ml +++ b/infer/src/absint/PatternMatch.ml @@ -58,6 +58,8 @@ let implements_iterator = implements "java.util.Iterator" let implements_collection = implements "java.util.Collection" +let implements_list = implements "java.util.List" + let implements_pseudo_collection t s = implements "android.util.SparseArray" t s || implements "android.util.SparseIntArray" t s @@ -72,10 +74,18 @@ let implements_io class_name = implements ("java.io." ^ class_name) let implements_map = implements "java.util.Map" +let implements_map_entry = implements "java.util.Map$Entry" + let implements_queue = implements "java.util.Queue" let implements_lang class_name = implements ("java.lang." ^ class_name) +let implements_google class_name = implements ("com.google." ^ class_name) + +let implements_android class_name = implements ("android." ^ class_name) + +let implements_jackson class_name = implements ("com.fasterxml.jackson." ^ class_name) + (** The type the method is invoked on *) let get_this_type proc_attributes = match proc_attributes.ProcAttributes.formals with (_, t) :: _ -> Some t | _ -> None diff --git a/infer/src/absint/PatternMatch.mli b/infer/src/absint/PatternMatch.mli index b17239818..eeb81f2b5 100644 --- a/infer/src/absint/PatternMatch.mli +++ b/infer/src/absint/PatternMatch.mli @@ -43,6 +43,9 @@ val implements_pseudo_collection : Tenv.t -> string -> bool val implements_enumeration : Tenv.t -> string -> bool (** Check whether class implements a Java's Enumeration *) +val implements_jackson : string -> Tenv.t -> string -> bool +(** Check whether class implements a class from Jackson *) + val implements_inject : string -> Tenv.t -> string -> bool (** Check whether class implements a Javax Inject *) @@ -52,12 +55,24 @@ val implements_io : string -> Tenv.t -> string -> bool val implements_map : Tenv.t -> string -> bool (** Check whether class implements a Java's Map *) +val implements_map_entry : Tenv.t -> string -> bool +(** Check whether class implements a Java's Map$Entry *) + val implements_queue : Tenv.t -> string -> bool (** Check whether class implements a Java's Queue *) val implements_lang : string -> Tenv.t -> string -> bool (** Check whether class implements a Java's lang *) +val implements_list : Tenv.t -> string -> bool +(** Check whether class implements a Java's list *) + +val implements_google : string -> Tenv.t -> string -> bool +(** Check whether class implements a class of Google *) + +val implements_android : string -> Tenv.t -> string -> bool +(** Check whether class implements a class of Android *) + val supertype_exists : Tenv.t -> (Typ.Name.t -> Typ.Struct.t -> bool) -> Typ.Name.t -> bool (** Holds iff the predicate holds on a supertype of the named type, including the type itself *) diff --git a/infer/src/checkers/invariantModels.ml b/infer/src/checkers/invariantModels.ml index 526cb2561..1c5076101 100644 --- a/infer/src/checkers/invariantModels.ml +++ b/infer/src/checkers/invariantModels.ml @@ -27,48 +27,107 @@ let invariants = let invariant_builtins _ s = BuiltinInvariantSet.mem s invariants +let endsWith suffix _ s = String.is_suffix ~suffix s + +let startsWith prefix _ s = String.is_prefix ~prefix s + +(* matches get*Value *) +let getStarValue tenv s = startsWith "get" tenv s && endsWith "Value" tenv s + module Call = struct let dispatch : (Tenv.t, model) ProcnameDispatcher.Call.dispatcher = let open ProcnameDispatcher.Call in make_dispatcher - [ +PatternMatch.implements_collection &:: "iterator" <>--> Variant - ; +PatternMatch.implements_iterator &:: "hasNext" <>--> Variant - ; +PatternMatch.implements_enumeration &:: "hasMoreElements" <>--> Variant - ; +PatternMatch.implements_enumeration &:: "nextElement" <>--> Variant + [ +invariant_builtins <>--> VariantForHoisting + ; +(fun _ name -> BuiltinDecl.is_declared (Typ.Procname.from_string_c_fun name)) + <>--> Variant + ; +PatternMatch.implements_android "text.TextUtils" &:: "isEmpty" <>--> VariantForHoisting + ; +PatternMatch.implements_android "view.ViewGroup" &:: "getChildAt" <>--> VariantForHoisting + ; +PatternMatch.implements_android "view.View" &::+ startsWith "get" <>--> VariantForHoisting + ; +PatternMatch.implements_android "view.View" + &::+ startsWith "findViewById" <>--> VariantForHoisting + ; +PatternMatch.implements_android "view.ViewGroup" + &:: "getChildCount" <>--> VariantForHoisting + ; +PatternMatch.implements_android "content.Context" + &::+ startsWith "get" <>--> VariantForHoisting + ; +PatternMatch.implements_android "content.res.Resources" + &::+ startsWith "get" <>--> VariantForHoisting + ; +PatternMatch.implements_lang "Iterable" &:: "iterator" <>--> VariantForHoisting + ; +PatternMatch.implements_collection &:: "iterator" <>--> VariantForHoisting + ; +PatternMatch.implements_iterator &:: "hasNext" <>--> VariantForHoisting ; +PatternMatch.implements_iterator &:: "next" <>--> Variant + ; +PatternMatch.implements_iterator &:: "remove" <>--> Variant ; +PatternMatch.implements_collection &:: "size" <>--> VariantForHoisting ; +PatternMatch.implements_collection &:: "add" <>--> Variant + ; +PatternMatch.implements_collection &:: "addAll" <>--> Variant ; +PatternMatch.implements_collection &:: "remove" <>--> Variant ; +PatternMatch.implements_collection &:: "isEmpty" <>--> VariantForHoisting ; +PatternMatch.implements_collection &:: "get" <>--> VariantForHoisting ; +PatternMatch.implements_collection &:: "set" <>--> Variant + (* Unlike Set.contains, List.contains is linear *) + ; +PatternMatch.implements_list &:: "contains" <>--> Invariant + ; +PatternMatch.implements_collection &:: "contains" <>--> VariantForHoisting + ; +PatternMatch.implements_enumeration &:: "hasMoreElements" <>--> VariantForHoisting + ; +PatternMatch.implements_enumeration &:: "nextElement" <>--> Variant + ; +PatternMatch.implements_google "common.base.Preconditions" + &::+ startsWith "check" <>--> VariantForHoisting + ; +PatternMatch.implements_inject "Provider" &:: "get" <>--> Invariant + ; +PatternMatch.implements_io "OutputStream" &:: "write" <>--> Variant + ; +PatternMatch.implements_io "InputStream" &:: "read" <>--> Variant + ; +PatternMatch.implements_io "PrintStream" &:: "print" <>--> Variant + ; +PatternMatch.implements_io "PrintStream" &:: "println" <>--> Variant + ; +PatternMatch.implements_io "Reader" &:: "read" <>--> Variant + ; +PatternMatch.implements_io "BufferedReader" &:: "readLine" <>--> Variant + (* deserialization is often expensive *) + ; +PatternMatch.implements_jackson "databind.JsonDeserializer" + &:: "deserialize" <>--> Invariant + ; +PatternMatch.implements_jackson "core.JsonParser" &:: "nextToken" <>--> Variant + ; +PatternMatch.implements_jackson "core.JsonParser" + &:: "getCurrentName" <>--> VariantForHoisting + ; +PatternMatch.implements_jackson "core.JsonParser" + &::+ getStarValue <>--> VariantForHoisting + ; +PatternMatch.implements_jackson "core.JsonParser" + &::+ startsWith "get" <>--> VariantForHoisting ; +PatternMatch.implements_pseudo_collection &:: "size" <>--> VariantForHoisting ; +PatternMatch.implements_pseudo_collection &:: "get" <>--> VariantForHoisting - ; +PatternMatch.implements_map &:: "isEmpty" <>--> VariantForHoisting - ; +PatternMatch.implements_map &:: "put" <>--> Variant - ; +PatternMatch.implements_queue &:: "poll" <>--> Variant - ; +PatternMatch.implements_queue &:: "add" <>--> Variant - ; +PatternMatch.implements_queue &:: "remove" <>--> Variant - ; +PatternMatch.implements_queue &:: "peek" <>--> VariantForHoisting + ; +PatternMatch.implements_lang "Math" &::.*--> VariantForHoisting + (* for (int|short|byte...)Value*) + ; +PatternMatch.implements_lang "Number" &::+ endsWith "Value" <>--> VariantForHoisting ; +PatternMatch.implements_lang "Boolean" &:: "valueOf" <>--> VariantForHoisting + ; +PatternMatch.implements_lang "Boolean" &:: "parseBoolean" <>--> VariantForHoisting + ; +PatternMatch.implements_lang "Boolean" &::+ endsWith "Value" <>--> VariantForHoisting ; +PatternMatch.implements_lang "Number" &:: "valueOf" <>--> VariantForHoisting - ; +PatternMatch.implements_lang "Boolean" &:: "toString" <>--> VariantForHoisting - ; +PatternMatch.implements_lang "Number" &:: "toString" <>--> VariantForHoisting ; +PatternMatch.implements_lang "String" &:: "length" <>--> VariantForHoisting + ; +PatternMatch.implements_lang "String" &:: "charAt" <>--> VariantForHoisting + (* substring in Java >= 1.7 has linear complexity *) + ; +PatternMatch.implements_lang "String" &:: "substring" <>--> Invariant + ; +PatternMatch.implements_lang "CharSequence" &:: "charAt" <>--> VariantForHoisting ; +PatternMatch.implements_lang "String" &:: "equals" <>--> VariantForHoisting ; +PatternMatch.implements_lang "String" &:: "startsWith" <>--> VariantForHoisting ; +PatternMatch.implements_lang "String" &:: "valueOf" <>--> VariantForHoisting ; +PatternMatch.implements_lang "String" &:: "replace" <>--> Variant + ; +PatternMatch.implements_lang "String" &:: "format" <>--> VariantForHoisting + (* String.hashCode is deterministic whereas Object's might not be *) + ; +PatternMatch.implements_lang "String" &:: "hashCode" <>--> VariantForHoisting + ; +PatternMatch.implements_lang "StringBuilder" &:: "" <>--> Variant ; +PatternMatch.implements_lang "StringBuilder" &:: "append" <>--> Variant ; +PatternMatch.implements_lang "StringBuilder" &:: "length" <>--> VariantForHoisting - ; +PatternMatch.implements_io "OutputStream" &:: "write" <>--> Variant - ; +PatternMatch.implements_io "InputStream" &:: "read" <>--> Variant - ; +PatternMatch.implements_io "PrintStream" &:: "print" <>--> Variant - ; +PatternMatch.implements_io "PrintStream" &:: "println" <>--> Variant - ; +PatternMatch.implements_io "Reader" &:: "read" <>--> Variant - ; +PatternMatch.implements_io "BufferedReader" &:: "readLine" <>--> Variant - ; +PatternMatch.implements_inject "Provider" &:: "get" <>--> Invariant - ; +invariant_builtins <>--> VariantForHoisting - ; +(fun _ name -> BuiltinDecl.is_declared (Typ.Procname.from_string_c_fun name)) - <>--> Variant ] + ; +PatternMatch.implements_lang "Object" &:: "equals" <>--> VariantForHoisting + ; +PatternMatch.implements_lang "Object" &:: "toString" <>--> VariantForHoisting + ; +PatternMatch.implements_lang "Object" &:: "getClass" <>--> VariantForHoisting + ; +PatternMatch.implements_lang "Class" &:: "getSimpleName" <>--> VariantForHoisting + ; +PatternMatch.implements_lang "Class" &::+ startsWith "get" <>--> VariantForHoisting + ; +PatternMatch.implements_lang "System" &:: "arraycopy" <>--> Variant + ; +PatternMatch.implements_lang "Enum" &:: "valueOf" <>--> VariantForHoisting + ; +PatternMatch.implements_lang "Enum" &:: "ordinal" <>--> VariantForHoisting + ; +PatternMatch.implements_map &:: "isEmpty" <>--> VariantForHoisting + ; +PatternMatch.implements_map &:: "get" <>--> VariantForHoisting + ; +PatternMatch.implements_map &:: "put" <>--> Variant + ; +PatternMatch.implements_map &:: "containsKey" <>--> VariantForHoisting + ; +PatternMatch.implements_map_entry &:: "getKey" <>--> VariantForHoisting + ; +PatternMatch.implements_map_entry &:: "getValue" <>--> VariantForHoisting + ; +PatternMatch.implements_queue &:: "poll" <>--> Variant + ; +PatternMatch.implements_queue &:: "add" <>--> Variant + ; +PatternMatch.implements_queue &:: "remove" <>--> Variant + ; +PatternMatch.implements_queue &:: "peek" <>--> VariantForHoisting ] end diff --git a/infer/src/checkers/loopInvariant.ml b/infer/src/checkers/loopInvariant.ml index 62f3b7d5d..63767ba38 100644 --- a/infer/src/checkers/loopInvariant.ml +++ b/infer/src/checkers/loopInvariant.ml @@ -30,12 +30,13 @@ let get_purity tenv ~is_inv_by_default callee_pname args = | Some inv -> PurityDomain.with_purity (InvariantModels.is_invariant inv) all_params_modified | None -> ( - (* If there is no model, invoke purity analysis to see if function is pure *) - match Ondemand.analyze_proc_name callee_pname with - | Some {Summary.payloads= {Payloads.purity= Some purity_summary}} -> - purity_summary - | _ -> - PurityDomain.with_purity is_inv_by_default all_params_modified ) + debug "No model for %a \n" Typ.Procname.pp callee_pname ; + (* If there is no model, invoke purity analysis to see if function is pure *) + match Ondemand.analyze_proc_name callee_pname with + | Some {Summary.payloads= {Payloads.purity= Some purity_summary}} -> + purity_summary + | _ -> + PurityDomain.with_purity is_inv_by_default all_params_modified ) let is_non_primitive typ = Typ.is_pointer typ || Typ.is_struct typ diff --git a/infer/tests/codetoanalyze/java/hoisting/HoistModeled.java b/infer/tests/codetoanalyze/java/hoisting/HoistModeled.java new file mode 100644 index 000000000..d1be796c9 --- /dev/null +++ b/infer/tests/codetoanalyze/java/hoisting/HoistModeled.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import java.io.IOException; +import java.util.List; + +class HoistModeled { + + int list_contains_hoist(List list, String s) { + int d = 0; + for (int i = 0; i < 10; i++) { + if (list.contains(s.substring(0, 1))) { + d++; + } + } + return d; + } + + void deserialize_hoist( + final JsonDeserializer specDeserializer, + final JsonParser p, + final DeserializationContext ctx) + throws IOException { + int d = 0; + Object o; + for (int i = 0; i < 10; i++) { + o = specDeserializer.deserialize(p, ctx); + } + } +} diff --git a/infer/tests/codetoanalyze/java/hoisting/issues.exp b/infer/tests/codetoanalyze/java/hoisting/issues.exp index 14e7db045..17286421f 100644 --- a/infer/tests/codetoanalyze/java/hoisting/issues.exp +++ b/infer/tests/codetoanalyze/java/hoisting/issues.exp @@ -18,5 +18,8 @@ codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.indirect_this_modi codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.irvar_independent_hoist(int[][],int,int[]):void, 2, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to int HoistIndirect.double_me(int) at line 212] codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.this_modification_outside_hoist(int):int, 4, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to int HoistIndirect.get() at line 127] codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.unmodified_arg_hoist(int[][],int,int[]):void, 4, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to int HoistIndirect.regionFirst(int[]) at line 222] +codetoanalyze/java/hoisting/HoistModeled.java, HoistModeled.deserialize_hoist(com.fasterxml.jackson.databind.JsonDeserializer,com.fasterxml.jackson.core.JsonParser,com.fasterxml.jackson.databind.DeserializationContext):void, 8, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to Object JsonDeserializer.deserialize(JsonParser,DeserializationContext) at line 33] +codetoanalyze/java/hoisting/HoistModeled.java, HoistModeled.list_contains_hoist(java.util.List,java.lang.String):int, 3, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to String String.substring(int,int) at line 18] +codetoanalyze/java/hoisting/HoistModeled.java, HoistModeled.list_contains_hoist(java.util.List,java.lang.String):int, 3, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to boolean List.contains(Object) at line 18] codetoanalyze/java/hoisting/HoistNoIndirectMod.java, HoistNoIndirectMod.increment_dont_hoist_FP(int):int, 2, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to int HoistNoIndirectMod.calcNext() at line 27] codetoanalyze/java/hoisting/HoistNoIndirectMod.java, HoistNoIndirectMod.modify_and_increment_dont_hoist_FP(int):int, 3, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to int HoistNoIndirectMod.calcNext() at line 35] diff --git a/infer/tests/codetoanalyze/java/performance/ArrayListTest.java b/infer/tests/codetoanalyze/java/performance/ArrayListTest.java index 4cc856b9b..7d5030172 100644 --- a/infer/tests/codetoanalyze/java/performance/ArrayListTest.java +++ b/infer/tests/codetoanalyze/java/performance/ArrayListTest.java @@ -173,7 +173,9 @@ public class ArrayListTest { public void iterate_while_has_next(ArrayList list) { Iterator itr = list.iterator(); - while (itr.hasNext()) {} + while (itr.hasNext()) { + System.out.println(itr.next()); + } } public void iterate_over_arraylist_with_inner(ArrayList list1) { diff --git a/infer/tests/codetoanalyze/java/performance/IteratorTest.java b/infer/tests/codetoanalyze/java/performance/IteratorTest.java index 3dc9654b1..a485940a6 100644 --- a/infer/tests/codetoanalyze/java/performance/IteratorTest.java +++ b/infer/tests/codetoanalyze/java/performance/IteratorTest.java @@ -9,6 +9,8 @@ import java.util.Iterator; public class IteratorTest { public void appendTo(Iterator parts) { - while (parts.hasNext()) {} + while (parts.hasNext()) { + System.out.println(parts.next()); + } } } diff --git a/infer/tests/codetoanalyze/java/performance/issues.exp b/infer/tests/codetoanalyze/java/performance/issues.exp index e8f8836f0..2067996b1 100644 --- a/infer/tests/codetoanalyze/java/performance/issues.exp +++ b/infer/tests/codetoanalyze/java/performance/issues.exp @@ -33,8 +33,9 @@ codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_ar codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_arraylist_with_inner(java.util.ArrayList):void, 3, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 9 + 13 ⋅ (list1.length.ub - 1) + 4 ⋅ list1.length.ub, degree = 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_local_arraylist(java.util.ArrayList):void, 2, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 9 + 5 ⋅ list.length.ub, degree = 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_over_local_arraylist(java.util.ArrayList):void, 2, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 8 + 5 ⋅ list.length.ub, degree = 1] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_while_has_next(java.util.ArrayList):void, 3, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 5 + 2 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1] -codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_while_has_next(java.util.ArrayList):void, 3, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 6 + 2 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_while_has_next(java.util.ArrayList):void, 3, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 5 + 12 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_while_has_next(java.util.ArrayList):void, 3, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 6 + 12 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1] +codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_while_has_next(java.util.ArrayList):void, 4, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 5 + 12 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_with_iterator(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 6 + 9 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1] codetoanalyze/java/performance/ArrayListTest.java, ArrayListTest.iterate_with_iterator(java.util.ArrayList):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 5 + 9 ⋅ (list.length.ub - 1) + 4 ⋅ list.length.ub, degree = 1] codetoanalyze/java/performance/Break.java, codetoanalyze.java.performance.Break.break_constant(int):int, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 10 + 7 ⋅ p.ub, degree = 1] @@ -115,8 +116,9 @@ codetoanalyze/java/performance/Invariant.java, Invariant.local_not_invariant_FP( codetoanalyze/java/performance/Invariant.java, Invariant.local_not_invariant_FP(int):void, 5, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 3 + 36 ⋅ (size.ub + 5) + 3 ⋅ (size.ub + 5) × (5+min(1, size.ub)) + 4 ⋅ (5+min(0, size.ub)), degree = 2] codetoanalyze/java/performance/Invariant.java, Invariant.x_is_invariant_ok(int):void, 7, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 9 + 6 ⋅ (size.ub + 20), degree = 1] codetoanalyze/java/performance/Invariant.java, Invariant.x_is_invariant_ok(int):void, 7, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 8 + 6 ⋅ (size.ub + 20), degree = 1] -codetoanalyze/java/performance/IteratorTest.java, IteratorTest.appendTo(java.util.Iterator):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 1 + 2 ⋅ (parts.length.ub - 1) + 4 ⋅ parts.length.ub, degree = 1] -codetoanalyze/java/performance/IteratorTest.java, IteratorTest.appendTo(java.util.Iterator):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 2 + 2 ⋅ (parts.length.ub - 1) + 4 ⋅ parts.length.ub, degree = 1] +codetoanalyze/java/performance/IteratorTest.java, IteratorTest.appendTo(java.util.Iterator):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 1 + 12 ⋅ (parts.length.ub - 1) + 4 ⋅ parts.length.ub, degree = 1] +codetoanalyze/java/performance/IteratorTest.java, IteratorTest.appendTo(java.util.Iterator):void, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 2 + 12 ⋅ (parts.length.ub - 1) + 4 ⋅ parts.length.ub, degree = 1] +codetoanalyze/java/performance/IteratorTest.java, IteratorTest.appendTo(java.util.Iterator):void, 2, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 1 + 12 ⋅ (parts.length.ub - 1) + 4 ⋅ parts.length.ub, degree = 1] codetoanalyze/java/performance/JsonArray.java, libraries.marauder.analytics.utils.json.JsonArray.addStringEntry(java.lang.String):void, 0, INFINITE_EXECUTION_TIME_CALL, no_bucket, ERROR, [] codetoanalyze/java/performance/JsonMap.java, libraries.marauder.analytics.utils.json.JsonMap.addEntry(java.lang.String,boolean):void, 0, INFINITE_EXECUTION_TIME_CALL, no_bucket, ERROR, [] codetoanalyze/java/performance/JsonMap.java, libraries.marauder.analytics.utils.json.JsonMap.addEntry(java.lang.String,double):void, 0, INFINITE_EXECUTION_TIME_CALL, no_bucket, ERROR, []