diff --git a/infer/src/bufferoverrun/bufferOverrunField.ml b/infer/src/bufferoverrun/bufferOverrunField.ml index 2dfc274dd..2046bbc2c 100644 --- a/infer/src/bufferoverrun/bufferOverrunField.ml +++ b/infer/src/bufferoverrun/bufferOverrunField.ml @@ -47,7 +47,9 @@ let mk, get_type = (mk, get_type) -let java_collection_internal_array = mk "java.collection.$elements." Typ.(mk_array void) +let java_collection_internal_array = mk "java.collection.elements" Typ.(mk_array void) + +let is_java_collection_internal_array fn = Typ.Fieldname.equal fn java_collection_internal_array let c_strlen () = if Language.curr_language_is Java then mk "length" Typ.uint else mk "c.strlen" Typ.uint diff --git a/infer/src/bufferoverrun/symb.ml b/infer/src/bufferoverrun/symb.ml index c67cfc5a5..852277a07 100644 --- a/infer/src/bufferoverrun/symb.ml +++ b/infer/src/bufferoverrun/symb.ml @@ -163,6 +163,12 @@ module SymbolPath = struct pp_partial fmt p | Offset {p; is_void} -> F.fprintf fmt "%a.offset%a" pp_partial p pp_is_void is_void + | Length {p= Field {fn; prefix= p}; is_void} + when BufferOverrunField.is_java_collection_internal_array fn -> + F.fprintf fmt "%a.length%a" pp_partial p pp_is_void is_void + | Length {p= StarField {last_field= fn; prefix= p}; is_void} + when BufferOverrunField.is_java_collection_internal_array fn -> + F.fprintf fmt "%a.length%a" (pp_star ~paren:false) p pp_is_void is_void | Length {p; is_void} -> F.fprintf fmt "%a.length%a" pp_partial p pp_is_void is_void diff --git a/infer/tests/codetoanalyze/java/performance/issues.exp b/infer/tests/codetoanalyze/java/performance/issues.exp index 82c53ee5c..ec85b79eb 100644 --- a/infer/tests/codetoanalyze/java/performance/issues.exp +++ b/infer/tests/codetoanalyze/java/performance/issues.exp @@ -62,7 +62,7 @@ codetoanalyze/java/performance/CantHandle.java, CantHandle.square_root_variant_F codetoanalyze/java/performance/CollectionTest.java, CollectionTest.ensure_call(CollectionTest$MyCollection):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 11 + 5 ⋅ list.length, O(list.length), degree = 1,{list.length},call to void CollectionTest.iterate_over_mycollection(CollectionTest$MyCollection),Loop at line 17] codetoanalyze/java/performance/CollectionTest.java, CollectionTest.iterate_over_call_quad(int,CollectionTest$MyCollection):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 18 ⋅ list.length + 5 ⋅ list.length × list.length + 3 ⋅ (list.length + 1), O(list.length × list.length), degree = 2,{list.length + 1},Loop at line 48,{list.length},call to void CollectionTest.iterate_over_mycollection(CollectionTest$MyCollection),Loop at line 17,{list.length},Loop at line 48] codetoanalyze/java/performance/CollectionTest.java, CollectionTest.iterate_over_mycollection(CollectionTest$MyCollection):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 5 + 5 ⋅ list.length, O(list.length), degree = 1,{list.length},Loop at line 17] -codetoanalyze/java/performance/CollectionTest.java, CollectionTest.iterate_over_mycollection_quad_FN(java.util.concurrent.ConcurrentLinkedQueue):void, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 18 ⋅ mSubscribers.length + 5 ⋅ mSubscribers.length × mSubscribers.*.length.ub + 3 ⋅ (mSubscribers.length + 1), O(mSubscribers.length × mSubscribers.*.length.ub), degree = 2,{mSubscribers.length + 1},Loop at line 29,{mSubscribers.*.length.ub},call to void CollectionTest.iterate_over_mycollection(CollectionTest$MyCollection),Loop at line 17,{mSubscribers.length},Loop at line 29] +codetoanalyze/java/performance/CollectionTest.java, CollectionTest.iterate_over_mycollection_quad_FN(java.util.concurrent.ConcurrentLinkedQueue):void, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 18 ⋅ mSubscribers.length + 5 ⋅ mSubscribers.length × mSubscribers.elements.*.length.ub + 3 ⋅ (mSubscribers.length + 1), O(mSubscribers.length × mSubscribers.elements.*.length.ub), degree = 2,{mSubscribers.length + 1},Loop at line 29,{mSubscribers.elements.*.length.ub},call to void CollectionTest.iterate_over_mycollection(CollectionTest$MyCollection),Loop at line 17,{mSubscribers.length},Loop at line 29] codetoanalyze/java/performance/CollectionTest.java, CollectionTest.iterate_over_some_java_collection(java.util.concurrent.ConcurrentLinkedQueue):void, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 8 ⋅ mSubscribers.length + 3 ⋅ (mSubscribers.length + 1), O(mSubscribers.length), degree = 1,{mSubscribers.length + 1},Loop at line 22,{mSubscribers.length},Loop at line 22] codetoanalyze/java/performance/CollectionTest.java, CollectionTest.loop_over_call(int,CollectionTest$MyCollection):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 2 + 15 ⋅ size + 5 ⋅ size × list.length, O(size × list.length), degree = 2,{list.length},call to void CollectionTest.iterate_over_mycollection(CollectionTest$MyCollection),Loop at line 17,{size},Loop at line 41] codetoanalyze/java/performance/CollectionTest.java, CollectionTest.nested_iterator_qubic(int,CollectionTest$MyCollection,CollectionTest$MyCollection):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 4 + 13 ⋅ list1.length + 5 ⋅ list1.length × list1.length × list2.length + 5 ⋅ list1.length × list1.length × list2.length + 28 ⋅ list1.length × list2.length + 3 ⋅ list1.length × (list2.length + 1) + 3 ⋅ (list1.length + 1), O(list1.length × list1.length × list2.length), degree = 3,{list1.length + 1},Loop at line 55,{list2.length + 1},Loop at line 56,{list2.length},Loop at line 56,{list2.length},Loop at line 56,{list1.length},call to void CollectionTest.iterate_over_mycollection(CollectionTest$MyCollection),Loop at line 17,{list2.length},Loop at line 56,{list1.length},call to void CollectionTest.iterate_over_mycollection(CollectionTest$MyCollection),Loop at line 17,{list1.length},Loop at line 55]