diff --git a/infer/src/absint/AbstractDomain.ml b/infer/src/absint/AbstractDomain.ml
index b11f3541a..8527dcdb4 100644
--- a/infer/src/absint/AbstractDomain.ml
+++ b/infer/src/absint/AbstractDomain.ml
@@ -734,6 +734,10 @@ struct
let mem k m = M.mem k m
+ let fold f (m : t) acc =
+ M.fold (fun key values acc -> S.fold (fun v acc -> f key v acc) values acc) m acc
+
+
let remove k v m =
M.update k
(function
diff --git a/infer/src/absint/AbstractDomain.mli b/infer/src/absint/AbstractDomain.mli
index f6a379885..261ff5bba 100644
--- a/infer/src/absint/AbstractDomain.mli
+++ b/infer/src/absint/AbstractDomain.mli
@@ -250,6 +250,8 @@ include sig
val mem : Key.t -> t -> bool [@@warning "-32"]
val remove : Key.t -> Value.t -> t -> t [@@warning "-32"]
+
+ val fold : (Key.t -> Value.t -> 'a -> 'a) -> t -> 'a -> 'a
end
end
diff --git a/infer/src/checkers/impurity.ml b/infer/src/checkers/impurity.ml
index 0eba1972f..15126b836 100644
--- a/infer/src/checkers/impurity.ml
+++ b/infer/src/checkers/impurity.ml
@@ -42,8 +42,7 @@ let ignore_array_index (access : BaseMemory.Access.t) : unit HilExp.Access.t =
TakeAddress
-let add_invalid_and_modified ~pvar ~access ~check_empty attrs acc : ImpurityDomain.ModifiedVarSet.t
- =
+let add_invalid_and_modified ~pvar ~access ~check_empty attrs access_list acc =
let modified =
Attributes.get_written_to attrs
|> Option.value_map ~default:[] ~f:(fun modified -> [ImpurityDomain.WrittenTo modified])
@@ -58,51 +57,65 @@ let add_invalid_and_modified ~pvar ~access ~check_empty attrs acc : ImpurityDoma
if check_empty && List.is_empty invalid_and_modified then
L.(die InternalError) "Address is modified without being written to or invalidated."
else
- List.fold_left ~init:acc
- ~f:(fun acc trace ->
- ImpurityDomain.ModifiedVarSet.add {pvar; access= ignore_array_index access; trace} acc )
- invalid_and_modified
+ let access_list = ignore_array_index access :: access_list in
+ ( access_list
+ , List.fold_left ~init:acc
+ ~f:(fun acc trace ->
+ ImpurityDomain.ModifiedVarMap.add pvar
+ {ordered_access_list= List.rev access_list; trace}
+ acc )
+ invalid_and_modified )
let add_to_modified ~pvar ~access ~addr pre_heap post modified_vars =
- let rec aux modified_vars ~addr_to_explore ~visited : ImpurityDomain.ModifiedVarSet.t =
+ let rec aux (access_list, modified_vars) ~addr_to_explore ~visited =
match addr_to_explore with
| [] ->
modified_vars
| (access, addr) :: addr_to_explore -> (
- if AbstractValue.Set.mem addr visited then aux modified_vars ~addr_to_explore ~visited
+ if AbstractValue.Set.mem addr visited then
+ aux (access_list, modified_vars) ~addr_to_explore ~visited
else
let edges_pre_opt = BaseMemory.find_opt addr pre_heap in
let cell_post_opt = BaseDomain.find_cell_opt addr post in
let visited = AbstractValue.Set.add addr visited in
match (edges_pre_opt, cell_post_opt) with
| None, None ->
- aux modified_vars ~addr_to_explore ~visited
+ aux (access_list, modified_vars) ~addr_to_explore ~visited
| Some _, None ->
L.(die InternalError)
"It is unexpected to have an address which has a binding in pre but not in post!"
| None, Some (_, attrs_post) ->
aux
- (add_invalid_and_modified ~pvar ~access ~check_empty:false attrs_post modified_vars)
+ (add_invalid_and_modified ~pvar ~access ~check_empty:false attrs_post access_list
+ modified_vars)
~addr_to_explore ~visited
| Some edges_pre, Some (edges_post, attrs_post) -> (
match get_matching_dest_addr_opt ~edges_pre ~edges_post with
| Some addr_list ->
- aux
- (add_invalid_and_modified ~pvar ~access attrs_post ~check_empty:false
- modified_vars)
- ~addr_to_explore:(addr_list @ addr_to_explore) ~visited
+ (* we have multiple accesses to check here up to
+ currently accumulated point. We need to check them
+ one by one rather than all at once to ensure that
+ accesses are not collapsed together but kept
+ separately. *)
+ List.fold ~init:modified_vars
+ ~f:(fun acc addr ->
+ aux
+ (add_invalid_and_modified ~pvar ~access attrs_post ~check_empty:false
+ access_list acc)
+ ~addr_to_explore:(addr :: addr_to_explore) ~visited )
+ addr_list
| None ->
aux
- (add_invalid_and_modified ~pvar ~access ~check_empty:true attrs_post
+ (add_invalid_and_modified ~pvar ~access ~check_empty:true attrs_post access_list
modified_vars)
~addr_to_explore ~visited ) )
in
- aux modified_vars ~addr_to_explore:[(access, addr)] ~visited:AbstractValue.Set.empty
+ aux ([], modified_vars) ~addr_to_explore:[(access, addr)] ~visited:AbstractValue.Set.empty
let get_modified_params pname post_stack pre_heap post formals =
- List.fold_left formals ~init:ImpurityDomain.ModifiedVarSet.empty ~f:(fun acc (name, typ) ->
+ List.fold_left formals ~init:ImpurityDomain.ModifiedVarMap.bottom ~f:(fun acc (name, typ) ->
let pvar = Pvar.mk name pname in
match BaseStack.find_opt (Var.of_pvar pvar) post_stack with
| Some (addr, _) when Typ.is_pointer typ -> (
@@ -128,7 +141,7 @@ let get_modified_globals pre_heap post post_stack =
~pvar:(Option.value_exn (Var.get_pvar var))
~access:HilExp.Access.Dereference ~addr pre_heap post modified_globals
else modified_globals )
- post_stack ImpurityDomain.ModifiedVarSet.empty
+ post_stack ImpurityDomain.ModifiedVarMap.bottom
let is_modeled_pure tenv pname =
@@ -196,7 +209,7 @@ let checker {IntraproceduralAnalysis.proc_desc; tenv; err_log}
in
if PurityChecker.should_report proc_name && not (ImpurityDomain.is_pure impurity_astate) then
let modified_ltr param_source set acc =
- ImpurityDomain.ModifiedVarSet.fold
+ ImpurityDomain.ModifiedVarMap.fold
(ImpurityDomain.add_to_errlog ~nesting:1 param_source)
set acc
in
diff --git a/infer/src/checkers/impurityDomain.ml b/infer/src/checkers/impurityDomain.ml
index 35ccd81ca..f83f9df04 100644
--- a/infer/src/checkers/impurityDomain.ml
+++ b/infer/src/checkers/impurityDomain.ml
@@ -12,34 +12,40 @@ module SkippedCalls = PulseSkippedCalls
type trace = WrittenTo of PulseTrace.t | Invalid of (PulseInvalidation.t * PulseTrace.t)
[@@deriving compare]
-let pp_pvar fmt pv = F.pp_print_string fmt (Pvar.get_simplified_name pv)
+module PVar = struct
+ type t = Pvar.t [@@deriving compare]
-module ModifiedVar = struct
- type t = {pvar: Pvar.t; access: unit HilExp.Access.t; trace: trace [@compare.ignore]}
+ let pp fmt pv = F.pp_print_string fmt (Pvar.get_simplified_name pv)
+end
+
+module ModifiedAccess = struct
+ type t = {ordered_access_list: unit HilExp.Access.t list; trace: trace [@compare.ignore]}
[@@deriving compare]
- let pp fmt {pvar} = F.fprintf fmt "@\n %a @\n" pp_pvar pvar
+ let pp fmt {ordered_access_list} =
+ let pp_sep fmt () = F.fprintf fmt "" in
+ (F.pp_print_list ~pp_sep (HilExp.Access.pp (fun _ _ -> ()))) fmt ordered_access_list
end
-module ModifiedVarSet = AbstractDomain.FiniteSet (ModifiedVar)
+module ModifiedVarMap = AbstractDomain.FiniteMultiMap (PVar) (ModifiedAccess)
module Exited = AbstractDomain.BooleanOr
type t =
- { modified_params: ModifiedVarSet.t
- ; modified_globals: ModifiedVarSet.t
+ { modified_params: ModifiedVarMap.t
+ ; modified_globals: ModifiedVarMap.t
; skipped_calls: SkippedCalls.t
; exited: Exited.t }
let is_pure {modified_globals; modified_params; skipped_calls; exited} =
- ModifiedVarSet.is_empty modified_globals
- && ModifiedVarSet.is_empty modified_params
+ ModifiedVarMap.is_bottom modified_globals
+ && ModifiedVarMap.is_bottom modified_params
&& SkippedCalls.is_empty skipped_calls
&& Exited.is_bottom exited
let pure =
- { modified_params= ModifiedVarSet.empty
- ; modified_globals= ModifiedVarSet.empty
+ { modified_params= ModifiedVarMap.bottom
+ ; modified_globals= ModifiedVarMap.bottom
; skipped_calls= SkippedCalls.empty
; exited= Exited.bottom }
@@ -51,8 +57,8 @@ let join astate1 astate2 =
let {modified_globals= mg2; modified_params= mp2; skipped_calls= uk2; exited= e2} = astate2 in
PhysEqual.optim2
~res:
- { modified_globals= ModifiedVarSet.join mg1 mg2
- ; modified_params= ModifiedVarSet.join mp1 mp2
+ { modified_globals= ModifiedVarMap.join mg1 mg2
+ ; modified_params= ModifiedVarMap.join mp1 mp2
; skipped_calls= SkippedCalls.union (fun _pname t1 _ -> Some t1) uk1 uk2
; exited= Exited.join e1 e2 }
astate1 astate2
@@ -67,16 +73,17 @@ let pp_param_source fmt = function
F.pp_print_string fmt "global variable"
-let add_to_errlog ~nesting param_source ModifiedVar.{pvar; trace} errlog =
+let add_to_errlog ~nesting param_source pvar (ModifiedAccess.{trace} as access) errlog =
match trace with
| WrittenTo access_trace ->
PulseTrace.add_to_errlog ~include_value_history:false ~nesting
~pp_immediate:(fun fmt ->
- F.fprintf fmt "%a `%a` modified here" pp_param_source param_source pp_pvar pvar )
+ F.fprintf fmt "%a `%a.%a` modified here" pp_param_source param_source PVar.pp pvar
+ ModifiedAccess.pp access )
access_trace errlog
| Invalid (invalidation, invalidation_trace) ->
PulseTrace.add_to_errlog ~include_value_history:false ~nesting
~pp_immediate:(fun fmt ->
- F.fprintf fmt "%a `%a` %a here" pp_param_source param_source pp_pvar pvar
- PulseInvalidation.describe invalidation )
+ F.fprintf fmt "%a `%a.%a` %a here" pp_param_source param_source PVar.pp pvar
+ ModifiedAccess.pp access PulseInvalidation.describe invalidation )
invalidation_trace errlog
diff --git a/infer/src/checkers/impurityDomain.mli b/infer/src/checkers/impurityDomain.mli
index 2fa2a01e0..56971f853 100644
--- a/infer/src/checkers/impurityDomain.mli
+++ b/infer/src/checkers/impurityDomain.mli
@@ -8,22 +8,28 @@ open! IStd
type trace = WrittenTo of PulseTrace.t | Invalid of (PulseInvalidation.t * PulseTrace.t)
-module ModifiedVar : sig
+module ModifiedAccess : sig
type t =
- { pvar: Pvar.t
- ; access: unit HilExp.Access.t (** accesses that are oblivious to modified array indices *)
+ { ordered_access_list: unit HilExp.Access.t list
+ (** list of ordered accesses that are oblivious to modified array indices *)
; trace: trace }
end
-module ModifiedVarSet : sig
- include AbstractDomain.FiniteSetS with type elt = ModifiedVar.t
+module ModifiedVarMap : sig
+ type t
+
+ val bottom : t
+
+ val add : Pvar.t -> ModifiedAccess.t -> t -> t
+
+ val fold : (Pvar.t -> ModifiedAccess.t -> 'a -> 'a) -> t -> 'a -> 'a
end
module Exited = AbstractDomain.BooleanOr
type t =
- { modified_params: ModifiedVarSet.t
- ; modified_globals: ModifiedVarSet.t
+ { modified_params: ModifiedVarMap.t
+ ; modified_globals: ModifiedVarMap.t
; skipped_calls: PulseSkippedCalls.t
; exited: Exited.t }
@@ -36,7 +42,8 @@ type param_source = Formal | Global
val add_to_errlog :
nesting:int
-> param_source
- -> ModifiedVar.t
+ -> Pvar.t
+ -> ModifiedAccess.t
-> Errlog.loc_trace_elem list
-> Errlog.loc_trace_elem list
diff --git a/infer/tests/codetoanalyze/cpp/impurity/issues.exp b/infer/tests/codetoanalyze/cpp/impurity/issues.exp
index 4db9e2751..301b2c8e6 100644
--- a/infer/tests/codetoanalyze/cpp/impurity/issues.exp
+++ b/infer/tests/codetoanalyze/cpp/impurity/issues.exp
@@ -1,36 +1,36 @@
-../../facebook-clang-plugins/clang/install/include/c++/v1/iterator, std::__wrap_iter::operator++, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function std::__wrap_iter::operator++,parameter `this` modified here]
-../../facebook-clang-plugins/clang/install/include/c++/v1/iterator, std::__wrap_iter::operator++, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function std::__wrap_iter::operator++,parameter `this` modified here]
-codetoanalyze/cpp/impurity/array_test.cpp, alias_mod_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function alias_mod_impure,parameter `array` modified here]
-codetoanalyze/cpp/impurity/array_test.cpp, array_mod_both_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function array_mod_both_impure,parameter `a` modified here]
-codetoanalyze/cpp/impurity/array_test.cpp, array_mod_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function array_mod_impure,parameter `b` modified here,parameter `a` modified here]
-codetoanalyze/cpp/impurity/array_test.cpp, call_array_mod_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function call_array_mod_impure,when calling `array_mod_impure` here,parameter `a` modified here]
+../../facebook-clang-plugins/clang/install/include/c++/v1/iterator, std::__wrap_iter::operator++, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function std::__wrap_iter::operator++,parameter `this.*__i` modified here]
+../../facebook-clang-plugins/clang/install/include/c++/v1/iterator, std::__wrap_iter::operator++, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function std::__wrap_iter::operator++,parameter `this.*__i` modified here]
+codetoanalyze/cpp/impurity/array_test.cpp, alias_mod_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function alias_mod_impure,parameter `array.*[]` modified here]
+codetoanalyze/cpp/impurity/array_test.cpp, array_mod_both_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function array_mod_both_impure,parameter `a.*[]` modified here]
+codetoanalyze/cpp/impurity/array_test.cpp, array_mod_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function array_mod_impure,parameter `b.*[]` modified here,parameter `a.*[]` modified here]
+codetoanalyze/cpp/impurity/array_test.cpp, call_array_mod_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function call_array_mod_impure,when calling `array_mod_impure` here,parameter `a.*[]` modified here]
codetoanalyze/cpp/impurity/array_test.cpp, call_array_mod_with_fresh_pure_FP, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function call_array_mod_with_fresh_pure_FP with empty pulse summary]
-codetoanalyze/cpp/impurity/array_test.cpp, modify_direct_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function modify_direct_impure,parameter `array` modified here]
-codetoanalyze/cpp/impurity/array_test.cpp, modify_ptr_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function modify_ptr_impure,parameter `array` modified here]
+codetoanalyze/cpp/impurity/array_test.cpp, modify_direct_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function modify_direct_impure,parameter `array.*[]x` modified here]
+codetoanalyze/cpp/impurity/array_test.cpp, modify_ptr_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function modify_ptr_impure,parameter `array.*x` modified here]
codetoanalyze/cpp/impurity/exit_test.cpp, exit_positive_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function exit_positive_impure]
codetoanalyze/cpp/impurity/exit_test.cpp, unreachable_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function unreachable_impure]
-codetoanalyze/cpp/impurity/global_test.cpp, call_modify_global, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function call_modify_global,when calling `modify_global_array_impure` here,global variable `a` modified here,when calling `modify_global_primitive_impure` here,global variable `x` modified here]
-codetoanalyze/cpp/impurity/global_test.cpp, local_static_var_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function local_static_var_impure,global variable `local_static_var_impure.arr` modified here]
-codetoanalyze/cpp/impurity/global_test.cpp, modify_global_array_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function modify_global_array_impure,global variable `a` modified here]
-codetoanalyze/cpp/impurity/global_test.cpp, modify_global_inside_lamda_impure::lambda_global_test.cpp:33:14::operator(), 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function modify_global_inside_lamda_impure::lambda_global_test.cpp:33:14::operator(),global variable `x` modified here]
-codetoanalyze/cpp/impurity/global_test.cpp, modify_global_primitive_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function modify_global_primitive_impure,global variable `x` modified here]
-codetoanalyze/cpp/impurity/invalid_test.cpp, Simple::operator=, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function Simple::operator=,parameter `this` modified here]
-codetoanalyze/cpp/impurity/invalid_test.cpp, delete_param_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function delete_param_impure,parameter `s` was invalidated by `delete` here]
-codetoanalyze/cpp/impurity/invalid_test.cpp, double_free_global_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function double_free_global_impure,when calling `free_global_pointer_impure` here,global variable `global_pointer` was invalidated by call to `free()` here]
+codetoanalyze/cpp/impurity/global_test.cpp, call_modify_global, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function call_modify_global,when calling `modify_global_array_impure` here,global variable `a.*[]` modified here,when calling `modify_global_primitive_impure` here,global variable `x.*` modified here]
+codetoanalyze/cpp/impurity/global_test.cpp, local_static_var_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function local_static_var_impure,global variable `local_static_var_impure.arr.*[]` modified here]
+codetoanalyze/cpp/impurity/global_test.cpp, modify_global_array_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function modify_global_array_impure,global variable `a.*[]` modified here]
+codetoanalyze/cpp/impurity/global_test.cpp, modify_global_inside_lamda_impure::lambda_global_test.cpp:33:14::operator(), 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function modify_global_inside_lamda_impure::lambda_global_test.cpp:33:14::operator(),global variable `x.*` modified here]
+codetoanalyze/cpp/impurity/global_test.cpp, modify_global_primitive_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function modify_global_primitive_impure,global variable `x.*` modified here]
+codetoanalyze/cpp/impurity/invalid_test.cpp, Simple::operator=, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function Simple::operator=,parameter `this.*f` modified here]
+codetoanalyze/cpp/impurity/invalid_test.cpp, delete_param_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function delete_param_impure,parameter `s.*` was invalidated by `delete` here]
+codetoanalyze/cpp/impurity/invalid_test.cpp, double_free_global_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function double_free_global_impure,when calling `free_global_pointer_impure` here,global variable `global_pointer.**` was invalidated by call to `free()` here]
codetoanalyze/cpp/impurity/invalid_test.cpp, double_free_global_impure, 2, USE_AFTER_FREE, no_bucket, ERROR, [invalidation part of the trace starts here,global variable `global_pointer` accessed here,when calling `free_global_pointer_impure` here,global variable `global_pointer` accessed here,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,global variable `global_pointer` accessed here,when calling `free_global_pointer_impure` here,global variable `global_pointer` accessed here,invalid access occurs here]
-codetoanalyze/cpp/impurity/invalid_test.cpp, free_global_pointer_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function free_global_pointer_impure,global variable `global_pointer` was invalidated by call to `free()` here]
-codetoanalyze/cpp/impurity/invalid_test.cpp, free_param_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function free_param_impure,parameter `x` was invalidated by call to `free()` here]
-codetoanalyze/cpp/impurity/invalid_test.cpp, reassign_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function reassign_impure,when calling `Simple::operator=` here,parameter `s` modified here]
-codetoanalyze/cpp/impurity/invalid_test.cpp, swap_address_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function swap_address_impure,when calling `Simple::operator=` here,parameter `rhs` modified here,when calling `Simple::operator=` here,parameter `lhs` modified here]
-codetoanalyze/cpp/impurity/invalid_test.cpp, swap_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function swap_impure,when calling `Simple::operator=` here,parameter `s2` modified here,when calling `Simple::operator=` here,parameter `s1` modified here]
-codetoanalyze/cpp/impurity/param_test.cpp, create_cycle_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function create_cycle_impure,parameter `x` modified here]
-codetoanalyze/cpp/impurity/param_test.cpp, invalidate_local_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function invalidate_local_impure,parameter `pp` modified here]
-codetoanalyze/cpp/impurity/param_test.cpp, modify_mut_ref_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function modify_mut_ref_impure,parameter `x` modified here]
-codetoanalyze/cpp/impurity/unmodeled.cpp, output_stream_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function output_stream_impure,global variable `std::cout` modified here,call to skipped function std::basic_ostream>::operator<< occurs here,call to skipped function std::operator<<_> occurs here]
+codetoanalyze/cpp/impurity/invalid_test.cpp, free_global_pointer_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function free_global_pointer_impure,global variable `global_pointer.**` was invalidated by call to `free()` here]
+codetoanalyze/cpp/impurity/invalid_test.cpp, free_param_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function free_param_impure,parameter `x.*` was invalidated by call to `free()` here]
+codetoanalyze/cpp/impurity/invalid_test.cpp, reassign_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function reassign_impure,when calling `Simple::operator=` here,parameter `s.*f` modified here]
+codetoanalyze/cpp/impurity/invalid_test.cpp, swap_address_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function swap_address_impure,when calling `Simple::operator=` here,parameter `rhs.*f` modified here,when calling `Simple::operator=` here,parameter `lhs.*f` modified here]
+codetoanalyze/cpp/impurity/invalid_test.cpp, swap_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function swap_impure,when calling `Simple::operator=` here,parameter `s2.*f` modified here,when calling `Simple::operator=` here,parameter `s1.*f` modified here]
+codetoanalyze/cpp/impurity/param_test.cpp, create_cycle_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function create_cycle_impure,parameter `x.*next` modified here]
+codetoanalyze/cpp/impurity/param_test.cpp, invalidate_local_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function invalidate_local_impure,parameter `pp.*` modified here]
+codetoanalyze/cpp/impurity/param_test.cpp, modify_mut_ref_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function modify_mut_ref_impure,parameter `x.*` modified here]
+codetoanalyze/cpp/impurity/unmodeled.cpp, output_stream_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function output_stream_impure,global variable `std::cout.*` modified here,call to skipped function std::basic_ostream>::operator<< occurs here,call to skipped function std::operator<<_> occurs here]
codetoanalyze/cpp/impurity/unmodeled.cpp, random_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function random_impure,call to skipped function rand occurs here]
-codetoanalyze/cpp/impurity/vector.cpp, assign_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function assign_impure,parameter `vec` modified here]
-codetoanalyze/cpp/impurity/vector.cpp, clear_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function clear_impure,parameter `vec` modified here]
-codetoanalyze/cpp/impurity/vector.cpp, insert_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function insert_impure,parameter `vec` modified here]
-codetoanalyze/cpp/impurity/vector.cpp, push_back_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function push_back_impure,parameter `vec` modified here]
-codetoanalyze/cpp/impurity/vector.cpp, push_back_in_loop_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function push_back_in_loop_impure,parameter `vec` modified here]
-codetoanalyze/cpp/impurity/vector.cpp, set_zero_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function set_zero_impure,parameter `numbers` modified here]
+codetoanalyze/cpp/impurity/vector.cpp, assign_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function assign_impure,parameter `vec.*` modified here]
+codetoanalyze/cpp/impurity/vector.cpp, clear_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function clear_impure,parameter `vec.*` modified here]
+codetoanalyze/cpp/impurity/vector.cpp, insert_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function insert_impure,parameter `vec.*` modified here]
+codetoanalyze/cpp/impurity/vector.cpp, push_back_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function push_back_impure,parameter `vec.*` modified here]
+codetoanalyze/cpp/impurity/vector.cpp, push_back_in_loop_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function push_back_in_loop_impure,parameter `vec.*` modified here]
+codetoanalyze/cpp/impurity/vector.cpp, set_zero_impure, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function set_zero_impure,parameter `numbers.*backing_array[]i` modified here]
diff --git a/infer/tests/codetoanalyze/java/impurity/Test.java b/infer/tests/codetoanalyze/java/impurity/Test.java
index 575173b24..5feb28e94 100644
--- a/infer/tests/codetoanalyze/java/impurity/Test.java
+++ b/infer/tests/codetoanalyze/java/impurity/Test.java
@@ -102,4 +102,9 @@ class Test {
void while_true_impure() {
while (true) {}
}
+
+ void modify_both_impure() {
+ set_impure(0, 1);
+ global_array_set_impure(3, 1);
+ }
}
diff --git a/infer/tests/codetoanalyze/java/impurity/issues.exp b/infer/tests/codetoanalyze/java/impurity/issues.exp
index a2a55458d..2f565d800 100644
--- a/infer/tests/codetoanalyze/java/impurity/issues.exp
+++ b/infer/tests/codetoanalyze/java/impurity/issues.exp
@@ -1,54 +1,55 @@
-codetoanalyze/java/impurity/GlobalTest.java, GlobalTest$Foo.set_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void GlobalTest$Foo.set_impure(),global variable `GlobalTest` modified here]
-codetoanalyze/java/impurity/GlobalTest.java, GlobalTest.call_set_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void GlobalTest.call_set_impure(),when calling `void GlobalTest$Foo.set_impure()` here,global variable `GlobalTest` modified here]
-codetoanalyze/java/impurity/GlobalTest.java, GlobalTest.global_mod_via_argument_passing_impure(int,GlobalTest$Foo):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void GlobalTest.global_mod_via_argument_passing_impure(int,GlobalTest$Foo),when calling `void GlobalTest.incr(GlobalTest$Foo,int)` here,global variable `GlobalTest` modified here]
-codetoanalyze/java/impurity/GlobalTest.java, GlobalTest.global_mod_via_argument_passing_impure_aliased(int,GlobalTest$Foo):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void GlobalTest.global_mod_via_argument_passing_impure_aliased(int,GlobalTest$Foo),when calling `void GlobalTest.incr(GlobalTest$Foo,int)` here,global variable `GlobalTest` modified here]
-codetoanalyze/java/impurity/GlobalTest.java, GlobalTest.incr(GlobalTest$Foo,int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void GlobalTest.incr(GlobalTest$Foo,int),parameter `foo` modified here]
-codetoanalyze/java/impurity/Localities.java, Localities$Counter.inc_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Localities$Counter.inc_impure(),parameter `this` modified here]
-codetoanalyze/java/impurity/Localities.java, Localities$Foo.inc_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Localities$Foo.inc_impure(),parameter `this` modified here]
-codetoanalyze/java/impurity/Localities.java, Localities.copy_ref_impure(int[],int):boolean, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function boolean Localities.copy_ref_impure(int[],int),parameter `a` modified here]
-codetoanalyze/java/impurity/Localities.java, Localities.get_array_impure(Localities$Foo[],int,Localities$Foo):Localities$Foo[], 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function Localities$Foo[] Localities.get_array_impure(Localities$Foo[],int,Localities$Foo),parameter `array` modified here]
-codetoanalyze/java/impurity/Localities.java, Localities.get_f_impure(Localities$Foo[],int,Localities$Foo):Localities$Foo, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function Localities$Foo Localities.get_f_impure(Localities$Foo[],int,Localities$Foo),parameter `array` modified here]
-codetoanalyze/java/impurity/Localities.java, Localities.get_foo_via_tmp_impure(Localities$Foo[],int,Localities$Foo,Localities$Foo):Localities$Bar, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function Localities$Bar Localities.get_foo_via_tmp_impure(Localities$Foo[],int,Localities$Foo,Localities$Foo),parameter `array` modified here]
-codetoanalyze/java/impurity/Localities.java, Localities.get_impure(int):int[], 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function int[] Localities.get_impure(int),global variable `Localities` modified here]
-codetoanalyze/java/impurity/Localities.java, Localities.incrementAll_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Localities.incrementAll_impure(ArrayList),when calling `void Localities$Foo.inc_impure()` here,parameter `list` modified here]
-codetoanalyze/java/impurity/Localities.java, Localities.makeAllZero_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Localities.makeAllZero_impure(ArrayList),parameter `list` modified here]
-codetoanalyze/java/impurity/Localities.java, Localities.modify_first_el_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Localities.modify_first_el_impure(ArrayList),parameter `list` modified here]
-codetoanalyze/java/impurity/Localities.java, Localities.modify_via_call_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Localities.modify_via_call_impure(ArrayList),when calling `void Localities$Foo.inc_impure()` here,parameter `list` modified here]
+codetoanalyze/java/impurity/GlobalTest.java, GlobalTest$Foo.set_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void GlobalTest$Foo.set_impure(),global variable `GlobalTest.*s` modified here]
+codetoanalyze/java/impurity/GlobalTest.java, GlobalTest.call_set_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void GlobalTest.call_set_impure(),when calling `void GlobalTest$Foo.set_impure()` here,global variable `GlobalTest.*s` modified here]
+codetoanalyze/java/impurity/GlobalTest.java, GlobalTest.global_mod_via_argument_passing_impure(int,GlobalTest$Foo):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void GlobalTest.global_mod_via_argument_passing_impure(int,GlobalTest$Foo),when calling `void GlobalTest.incr(GlobalTest$Foo,int)` here,global variable `GlobalTest.*foo*x` modified here]
+codetoanalyze/java/impurity/GlobalTest.java, GlobalTest.global_mod_via_argument_passing_impure_aliased(int,GlobalTest$Foo):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void GlobalTest.global_mod_via_argument_passing_impure_aliased(int,GlobalTest$Foo),when calling `void GlobalTest.incr(GlobalTest$Foo,int)` here,global variable `GlobalTest.*foo*x` modified here]
+codetoanalyze/java/impurity/GlobalTest.java, GlobalTest.incr(GlobalTest$Foo,int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void GlobalTest.incr(GlobalTest$Foo,int),parameter `foo.*x` modified here]
+codetoanalyze/java/impurity/Localities.java, Localities$Counter.inc_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Localities$Counter.inc_impure(),parameter `this.*i` modified here]
+codetoanalyze/java/impurity/Localities.java, Localities$Foo.inc_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Localities$Foo.inc_impure(),parameter `this.*x` modified here]
+codetoanalyze/java/impurity/Localities.java, Localities.copy_ref_impure(int[],int):boolean, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function boolean Localities.copy_ref_impure(int[],int),parameter `a.*[]` modified here]
+codetoanalyze/java/impurity/Localities.java, Localities.get_array_impure(Localities$Foo[],int,Localities$Foo):Localities$Foo[], 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function Localities$Foo[] Localities.get_array_impure(Localities$Foo[],int,Localities$Foo),parameter `array.*[]*x` modified here]
+codetoanalyze/java/impurity/Localities.java, Localities.get_f_impure(Localities$Foo[],int,Localities$Foo):Localities$Foo, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function Localities$Foo Localities.get_f_impure(Localities$Foo[],int,Localities$Foo),parameter `array.*[]*x` modified here]
+codetoanalyze/java/impurity/Localities.java, Localities.get_foo_via_tmp_impure(Localities$Foo[],int,Localities$Foo,Localities$Foo):Localities$Bar, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function Localities$Bar Localities.get_foo_via_tmp_impure(Localities$Foo[],int,Localities$Foo,Localities$Foo),parameter `array.*[]*bar` modified here]
+codetoanalyze/java/impurity/Localities.java, Localities.get_impure(int):int[], 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function int[] Localities.get_impure(int),global variable `Localities.*pool*[]*[]` modified here]
+codetoanalyze/java/impurity/Localities.java, Localities.incrementAll_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Localities.incrementAll_impure(ArrayList),when calling `void Localities$Foo.inc_impure()` here,parameter `list.*backing_array[]x` modified here]
+codetoanalyze/java/impurity/Localities.java, Localities.makeAllZero_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Localities.makeAllZero_impure(ArrayList),parameter `list.*backing_array[]x` modified here]
+codetoanalyze/java/impurity/Localities.java, Localities.modify_first_el_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Localities.modify_first_el_impure(ArrayList),parameter `list.*backing_array[]x` modified here]
+codetoanalyze/java/impurity/Localities.java, Localities.modify_via_call_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Localities.modify_via_call_impure(ArrayList),when calling `void Localities$Foo.inc_impure()` here,parameter `list.*backing_array[]x` modified here]
codetoanalyze/java/impurity/Localities.java, Localities.newHashCode_impure():int, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function int Localities.newHashCode_impure(),call to skipped function int Object.hashCode() occurs here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.add_impure(java.util.ArrayList):java.lang.String, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function String PurityModeled.add_impure(ArrayList),parameter `list` modified here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.append_impure(java.lang.StringBuilder):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.append_impure(StringBuilder),parameter `strBuilder` modified here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.call_set_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.call_set_impure(ArrayList),when calling `void PurityModeled.list_set_impure(ArrayList)` here,parameter `list` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.add_impure(java.util.ArrayList):java.lang.String, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function String PurityModeled.add_impure(ArrayList),parameter `list.*backing_array` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.append_impure(java.lang.StringBuilder):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.append_impure(StringBuilder),parameter `strBuilder.*` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.call_set_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.call_set_impure(ArrayList),when calling `void PurityModeled.list_set_impure(ArrayList)` here,parameter `list.*backing_array` modified here]
codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.call_timing_symb_impure(int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.call_timing_symb_impure(int),when calling `void PurityModeled.timing_call_in_loop_symb_impure(int)` here,call to skipped function long System.nanoTime() occurs here]
codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.call_timing_symb_unrelated_impure(int,int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.call_timing_symb_unrelated_impure(int,int),when calling `void PurityModeled.timing_call_in_loop_symb_impure(int)` here,call to skipped function long System.nanoTime() occurs here]
codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.call_write_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.call_write_impure(),when calling `void PurityModeled.write_impure()` here,call to skipped function void PrintStream.write(byte[],int,int) occurs here]
codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.constant_loop_pure_FP():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.constant_loop_pure_FP() with empty pulse summary]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.list_add_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.list_add_impure(ArrayList),parameter `list` modified here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.list_addall_impure(java.util.ArrayList,java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.list_addall_impure(ArrayList,ArrayList),parameter `list1` modified here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.list_set_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.list_set_impure(ArrayList),parameter `list` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.list_add_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.list_add_impure(ArrayList),parameter `list.*backing_array` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.list_addall_impure(java.util.ArrayList,java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.list_addall_impure(ArrayList,ArrayList),parameter `list1.*` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.list_set_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.list_set_impure(ArrayList),parameter `list.*backing_array` modified here]
codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.math_random_impure():double, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function double PurityModeled.math_random_impure(),call to skipped function double Math.random() occurs here]
codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.math_random_in_loop_impure(int):int, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function int PurityModeled.math_random_in_loop_impure(int),when calling `void PurityModeled.call_write_impure()` here,when calling `void PurityModeled.write_impure()` here,call to skipped function void PrintStream.write(byte[],int,int) occurs here,call to skipped function double Math.random() occurs here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.nested_remove_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.nested_remove_impure(ArrayList),parameter `list` modified here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.next_impure(java.util.Iterator):java.lang.Integer, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function Integer PurityModeled.next_impure(Iterator),parameter `it` modified here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.process_queue_impure(java.util.ArrayList,java.util.Queue):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.process_queue_impure(ArrayList,Queue),parameter `queue` modified here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.remove_all_directly_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.remove_all_directly_impure(ArrayList),parameter `list` modified here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.remove_all_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.remove_all_impure(ArrayList),parameter `list` modified here,call to skipped function void PrintStream.println(String) occurs here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.remove_fresh_impure(java.util.ArrayList):java.lang.String, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function String PurityModeled.remove_fresh_impure(ArrayList),parameter `list` modified here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.remove_impure(java.util.Iterator):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.remove_impure(Iterator),parameter `i` modified here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.remove_impure_mult(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.remove_impure_mult(ArrayList),when calling `String PurityModeled.remove_fresh_impure(ArrayList)` here,parameter `list` modified here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.remove_iterator_impure(java.util.Iterator):java.lang.String, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function String PurityModeled.remove_iterator_impure(Iterator),parameter `listIterator` modified here]
-codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.replace_impure(java.lang.String):java.lang.String, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function String PurityModeled.replace_impure(String),parameter `s` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.nested_remove_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.nested_remove_impure(ArrayList),parameter `list.*backing_array[]backing_array` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.next_impure(java.util.Iterator):java.lang.Integer, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function Integer PurityModeled.next_impure(Iterator),parameter `it.*` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.process_queue_impure(java.util.ArrayList,java.util.Queue):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.process_queue_impure(ArrayList,Queue),parameter `queue.*backing_array` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.remove_all_directly_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.remove_all_directly_impure(ArrayList),parameter `list.*backing_array` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.remove_all_impure(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.remove_all_impure(ArrayList),parameter `list.*backing_array` modified here,call to skipped function void PrintStream.println(String) occurs here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.remove_fresh_impure(java.util.ArrayList):java.lang.String, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function String PurityModeled.remove_fresh_impure(ArrayList),parameter `list.*backing_array` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.remove_impure(java.util.Iterator):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.remove_impure(Iterator),parameter `i.*` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.remove_impure_mult(java.util.ArrayList):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.remove_impure_mult(ArrayList),when calling `String PurityModeled.remove_fresh_impure(ArrayList)` here,parameter `list.*backing_array` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.remove_iterator_impure(java.util.Iterator):java.lang.String, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function String PurityModeled.remove_iterator_impure(Iterator),parameter `listIterator.*` modified here]
+codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.replace_impure(java.lang.String):java.lang.String, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function String PurityModeled.replace_impure(String),parameter `s.*` modified here]
codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.timing_call_in_loop_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.timing_call_in_loop_impure() with empty pulse summary]
codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.timing_call_in_loop_symb_impure(int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.timing_call_in_loop_symb_impure(int),call to skipped function long System.nanoTime() occurs here]
codetoanalyze/java/impurity/PurityModeled.java, PurityModeled.write_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void PurityModeled.write_impure(),call to skipped function void PrintStream.write(byte[],int,int) occurs here]
-codetoanalyze/java/impurity/Test.java, Test.Test(int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.Test(int),global variable `Test` modified here]
-codetoanalyze/java/impurity/Test.java, Test.alias_impure(int[],int,int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.alias_impure(int[],int,int),parameter `array` modified here]
-codetoanalyze/java/impurity/Test.java, Test.call_impure_impure(int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.call_impure_impure(int),when calling `void Test.set_impure(int,int)` here,parameter `this` modified here]
+codetoanalyze/java/impurity/Test.java, Test.Test(int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.Test(int),global variable `Test.*global_arr` modified here]
+codetoanalyze/java/impurity/Test.java, Test.alias_impure(int[],int,int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.alias_impure(int[],int,int),parameter `array.*[]` modified here]
+codetoanalyze/java/impurity/Test.java, Test.call_impure_impure(int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.call_impure_impure(int),when calling `void Test.set_impure(int,int)` here,parameter `this.*a` modified here]
codetoanalyze/java/impurity/Test.java, Test.exit_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.exit_impure()]
-codetoanalyze/java/impurity/Test.java, Test.global_array_set_impure(int,int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.global_array_set_impure(int,int),global variable `Test` modified here]
-codetoanalyze/java/impurity/Test.java, Test.local_field_write_impure(Test):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.local_field_write_impure(Test),parameter `x` modified here]
-codetoanalyze/java/impurity/Test.java, Test.modify_exit_impure(int[]):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.modify_exit_impure(int[]),parameter `a` modified here]
-codetoanalyze/java/impurity/Test.java, Test.parameter_field_write_impure(Test,boolean):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.parameter_field_write_impure(Test,boolean),parameter `test` modified here]
-codetoanalyze/java/impurity/Test.java, Test.set_impure(int,int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.set_impure(int,int),parameter `this` modified here]
-codetoanalyze/java/impurity/Test.java, Test.swap_impure(int[],int,int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.swap_impure(int[],int,int),parameter `array` modified here]
+codetoanalyze/java/impurity/Test.java, Test.global_array_set_impure(int,int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.global_array_set_impure(int,int),global variable `Test.*global_arr*[]` modified here]
+codetoanalyze/java/impurity/Test.java, Test.local_field_write_impure(Test):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.local_field_write_impure(Test),parameter `x.*a` modified here]
+codetoanalyze/java/impurity/Test.java, Test.modify_both_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.modify_both_impure(),when calling `void Test.set_impure(int,int)` here,parameter `this.*a` modified here,when calling `void Test.global_array_set_impure(int,int)` here,global variable `Test.*global_arr*[]` modified here]
+codetoanalyze/java/impurity/Test.java, Test.modify_exit_impure(int[]):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.modify_exit_impure(int[]),parameter `a.*[]` modified here]
+codetoanalyze/java/impurity/Test.java, Test.parameter_field_write_impure(Test,boolean):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.parameter_field_write_impure(Test,boolean),parameter `test.*a` modified here]
+codetoanalyze/java/impurity/Test.java, Test.set_impure(int,int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.set_impure(int,int),parameter `this.*a` modified here]
+codetoanalyze/java/impurity/Test.java, Test.swap_impure(int[],int,int):void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.swap_impure(int[],int,int),parameter `array.*[]` modified here]
codetoanalyze/java/impurity/Test.java, Test.systemNanoTime_impure():long, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function long Test.systemNanoTime_impure(),call to skipped function long System.nanoTime() occurs here]
codetoanalyze/java/impurity/Test.java, Test.while_true_impure():void, 0, IMPURE_FUNCTION, no_bucket, ERROR, [Impure function void Test.while_true_impure() with no pulse summary]