From b455baae5dd57094fae86ba10e98db2e12c54c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezgi=20=C3=87i=C3=A7ek?= Date: Thu, 23 May 2019 01:31:34 -0700 Subject: [PATCH] [loop-invariance] Invalidate args to T function calls Reviewed By: ngorogiannis Differential Revision: D15451671 fbshipit-source-id: 20653f34e --- infer/src/checkers/loopInvariant.ml | 9 +++++++-- infer/tests/codetoanalyze/java/hoisting/HoistGlobal.java | 7 +++---- infer/tests/codetoanalyze/java/hoisting/issues.exp | 2 -- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/infer/src/checkers/loopInvariant.ml b/infer/src/checkers/loopInvariant.ml index b966cc2a3..0e9d652d1 100644 --- a/infer/src/checkers/loopInvariant.ml +++ b/infer/src/checkers/loopInvariant.ml @@ -196,8 +196,13 @@ let get_invalidated_vars_in_loop tenv loop_head ~is_inv_by_default ~get_callee_p | AbstractDomain.Types.Top -> (* modified global *) (* if one of the callees modifies a global static - variable, invalidate all unmodeled function calls *) - InvalidatedVars.union acc (force all_unmodeled_modified) + variable, invalidate all unmodeled function calls + args *) + let all_params = PurityDomain.all_params_modified args in + let invalidated_args = + get_vars_to_invalidate node loop_head args all_params + (InvalidatedVars.add (Var.of_id id) acc) + in + InvalidatedVars.union invalidated_args (force all_unmodeled_modified) | AbstractDomain.Types.NonTop modified_params -> if ModifiedParamIndices.is_empty modified_params then (*pure*) acc diff --git a/infer/tests/codetoanalyze/java/hoisting/HoistGlobal.java b/infer/tests/codetoanalyze/java/hoisting/HoistGlobal.java index 284589d64..d42e0aa92 100644 --- a/infer/tests/codetoanalyze/java/hoisting/HoistGlobal.java +++ b/infer/tests/codetoanalyze/java/hoisting/HoistGlobal.java @@ -91,17 +91,16 @@ class HoistGlobal { } } - void remove_first_dont_hoist_FP(LinkedList list) { + void remove_first_dont_hoist(LinkedList list) { while (list.size() >= 10) { list.removeFirst(); } } - String get_first_hoist(LinkedList list, String s) { - + String get_first_hoist_FN(LinkedList list, String s) { for (int i = 0; i <= 10; i++) { - String first = list.getFirst(); + String first = list.getFirst(); // list is invalidated if (list.contains(s)) { // hoist return first; } diff --git a/infer/tests/codetoanalyze/java/hoisting/issues.exp b/infer/tests/codetoanalyze/java/hoisting/issues.exp index 3e122a77e..4b8dd0968 100644 --- a/infer/tests/codetoanalyze/java/hoisting/issues.exp +++ b/infer/tests/codetoanalyze/java/hoisting/issues.exp @@ -29,13 +29,11 @@ codetoanalyze/java/hoisting/Hoist.java, Hoist.void_hoist(int):void, 2, INVARIANT codetoanalyze/java/hoisting/Hoist.java, Hoist.x_not_invariant_dont_hoist(int,int,int):void, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function void Hoist.x_not_invariant_dont_hoist(int,int,int)] codetoanalyze/java/hoisting/HoistGlobal.java, HoistGlobal$Foo.read_global():int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistGlobal$Foo.read_global()] codetoanalyze/java/hoisting/HoistGlobal.java, HoistGlobal$Foo.return_zero():int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistGlobal$Foo.return_zero()] -codetoanalyze/java/hoisting/HoistGlobal.java, HoistGlobal.get_first_hoist(java.util.LinkedList,java.lang.String):java.lang.String, 4, INVARIANT_CALL, no_bucket, ERROR, [The call to boolean LinkedList.contains(Object) at line 105 is loop-invariant] codetoanalyze/java/hoisting/HoistGlobal.java, HoistGlobal.global_modification_hoist_FN(java.util.ArrayList):int, 3, INVARIANT_CALL, no_bucket, ERROR, [The call to int ArrayList.size() at line 51 is loop-invariant] codetoanalyze/java/hoisting/HoistGlobal.java, HoistGlobal.processModulesDirectory_dont_hoist_FP(java.util.Set,java.lang.String[]):void, 5, INVARIANT_CALL, no_bucket, ERROR, [The call to boolean Set.contains(Object) at line 70 is loop-invariant] codetoanalyze/java/hoisting/HoistGlobal.java, HoistGlobal.processModulesDirectory_hoist(java.util.Set,java.lang.String[]):void, 4, INVARIANT_CALL, no_bucket, ERROR, [The call to boolean Set.contains(Object) at line 90 is loop-invariant] codetoanalyze/java/hoisting/HoistGlobal.java, HoistGlobal.processModulesDirectory_param_dont_hoist_FP(java.util.Set,java.lang.String[],AppModuleFileInfo,AppModuleFileInfo):void, 8, INVARIANT_CALL, no_bucket, ERROR, [The call to boolean Set.contains(Object) at line 82 is loop-invariant] codetoanalyze/java/hoisting/HoistGlobal.java, HoistGlobal.read_global():int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistGlobal.read_global()] -codetoanalyze/java/hoisting/HoistGlobal.java, HoistGlobal.remove_first_dont_hoist_FP(java.util.LinkedList):void, 2, INVARIANT_CALL, no_bucket, ERROR, [The call to int LinkedList.size() at line 96 is loop-invariant] codetoanalyze/java/hoisting/HoistGlobal.java, HoistGlobal.return_one():int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistGlobal.return_one()] codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect$Test.deep_modification_dont_hoist(int):int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistIndirect$Test.deep_modification_dont_hoist(int)] codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect$Test.foo(int):int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistIndirect$Test.foo(int)]