From 3fb1053b752e5136cb5708a7ec1d4211cfbe56e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezgi=20=C3=87i=C3=A7ek?= Date: Wed, 7 Nov 2018 10:39:11 -0800 Subject: [PATCH] [hoisting] Invalidate arguments of type structs Reviewed By: mbouaziz Differential Revision: D12924850 fbshipit-source-id: b442d37be --- infer/src/IR/Typ.ml | 2 ++ infer/src/IR/Typ.mli | 2 ++ infer/src/checkers/loopInvariant.ml | 10 ++++++---- .../codetoanalyze/java/hoisting/HoistIndirect.java | 11 +++++++++++ infer/tests/codetoanalyze/java/hoisting/issues.exp | 10 +++++----- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/infer/src/IR/Typ.ml b/infer/src/IR/Typ.ml index 68e221567..a30a244ab 100644 --- a/infer/src/IR/Typ.ml +++ b/infer/src/IR/Typ.ml @@ -539,6 +539,8 @@ let is_pointer typ = match typ.desc with Tptr _ -> true | _ -> false let is_reference typ = match typ.desc with Tptr (_, Pk_reference) -> true | _ -> false +let is_struct typ = match typ.desc with Tstruct _ -> true | _ -> false + let is_pointer_to_cpp_class typ = match typ.desc with Tptr (t, _) -> is_cpp_class t | _ -> false let is_pointer_to_void typ = match typ.desc with Tptr ({desc= Tvoid}, _) -> true | _ -> false diff --git a/infer/src/IR/Typ.mli b/infer/src/IR/Typ.mli index 529b66dd2..bd3149156 100644 --- a/infer/src/IR/Typ.mli +++ b/infer/src/IR/Typ.mli @@ -288,6 +288,8 @@ val is_pointer : t -> bool val is_reference : t -> bool +val is_struct : t -> bool + val has_block_prefix : string -> bool val unsome : string -> t option -> t diff --git a/infer/src/checkers/loopInvariant.ml b/infer/src/checkers/loopInvariant.ml index bc2c9cf16..0542cabd0 100644 --- a/infer/src/checkers/loopInvariant.ml +++ b/infer/src/checkers/loopInvariant.ml @@ -37,6 +37,8 @@ let is_fun_pure tenv ~is_inv_by_default callee_pname params = is_inv_by_default ) +let is_non_primitive typ = Typ.is_pointer typ || Typ.is_struct typ + (* check if the def of var is unique and invariant *) let is_def_unique_and_satisfy tenv var (loop_nodes : LoopNodes.t) ~is_inv_by_default is_exp_invariant = @@ -114,11 +116,11 @@ let get_ptr_vars_in_defn_path node var = Procdesc.Node.get_instrs node |> Instrs.fold ~init:InvalidatedVars.empty ~f:(fun acc instr -> match instr with - | Sil.Load (id, exp_rhs, typ, _) when Var.equal var (Var.of_id id) && Typ.is_pointer typ - -> + | Sil.Load (id, exp_rhs, typ, _) + when Var.equal var (Var.of_id id) && is_non_primitive typ -> invalidate_exp exp_rhs acc | Sil.Store (Exp.Lvar pvar, typ, exp_rhs, _) - when Var.equal var (Var.of_pvar pvar) && Typ.is_pointer typ -> + when Var.equal var (Var.of_pvar pvar) && is_non_primitive typ -> invalidate_exp exp_rhs acc | _ -> acc ) @@ -131,7 +133,7 @@ let get_vars_to_invalidate node params invalidated_vars : InvalidatedVars.t = ~f:(fun acc (arg_exp, typ) -> Var.get_all_vars_in_exp arg_exp |> Sequence.fold ~init:acc ~f:(fun acc var -> - if Typ.is_pointer typ then + if is_non_primitive typ then let dep_vars = get_ptr_vars_in_defn_path node var in InvalidatedVars.union dep_vars (InvalidatedVars.add var acc) else acc ) ) diff --git a/infer/tests/codetoanalyze/java/hoisting/HoistIndirect.java b/infer/tests/codetoanalyze/java/hoisting/HoistIndirect.java index a669acc68..299adfcea 100644 --- a/infer/tests/codetoanalyze/java/hoisting/HoistIndirect.java +++ b/infer/tests/codetoanalyze/java/hoisting/HoistIndirect.java @@ -14,6 +14,8 @@ class HoistIndirect { int a = 0; + int[] test_array; + int foo(int x) { return x + 10; } @@ -149,6 +151,15 @@ class HoistIndirect { return d; } + int modified_inner_array_dont_hoist(int size, Test t) { + int d = 0; + for (int i = 0; i < size; i++) { + set_ith(i, t.test_array); + d += t.foo(t.test_array[0]); // don't hoist since t.test_array changes + } + return d; + } + static int regionFirst(int[] region) { return region[0]; } diff --git a/infer/tests/codetoanalyze/java/hoisting/issues.exp b/infer/tests/codetoanalyze/java/hoisting/issues.exp index 5cb412391..5fddc2fa0 100644 --- a/infer/tests/codetoanalyze/java/hoisting/issues.exp +++ b/infer/tests/codetoanalyze/java/hoisting/issues.exp @@ -25,15 +25,15 @@ codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect$Test.foo(int):int, codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect$Test.get_sum_test(HoistIndirect$Test,int):int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistIndirect$Test.get_sum_test(HoistIndirect$Test,int)] codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect$Test.get_test(HoistIndirect$Test):int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistIndirect$Test.get_test(HoistIndirect$Test)] codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect$Test.return_only(HoistIndirect$Test):HoistIndirect$Test, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function HoistIndirect$Test HoistIndirect$Test.return_only(HoistIndirect$Test)] -codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.arg_modification_hoist(int,HoistIndirect$Test):int, 3, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to int HoistIndirect.get() at line 119] -codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.direct_this_modification_dont_hoist_FP(int):int, 4, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to int HoistIndirect.get() at line 101] +codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.arg_modification_hoist(int,HoistIndirect$Test):int, 3, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to int HoistIndirect.get() at line 121] +codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.direct_this_modification_dont_hoist_FP(int):int, 4, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to int HoistIndirect.get() at line 103] codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.double_me(int):int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistIndirect.double_me(int)] codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.get():int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistIndirect.get()] codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.get_ith(int,int[]):int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistIndirect.get_ith(int,int[])] -codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.independent_hoist(int,HoistIndirect$Test):int, 4, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to int HoistIndirect$Test.foo(int) at line 146] -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 187] +codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.independent_hoist(int,HoistIndirect$Test):int, 4, INVARIANT_CALL, no_bucket, ERROR, [Loop-invariant call to int HoistIndirect$Test.foo(int) at line 148] +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 198] codetoanalyze/java/hoisting/HoistIndirect.java, HoistIndirect.regionFirst(int[]):int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistIndirect.regionFirst(int[])] -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 111] +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 113] codetoanalyze/java/hoisting/HoistNoIndirectMod.java, HoistNoIndirectMod.calcNext():int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistNoIndirectMod.calcNext()] codetoanalyze/java/hoisting/HoistNoIndirectMod.java, HoistNoIndirectMod.calcSame():int, 0, PURE_FUNCTION, no_bucket, ERROR, [Side-effect free function int HoistNoIndirectMod.calcSame()] 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]