diff --git a/src/plugins/value/domains/abstract_domain.mli b/src/plugins/value/domains/abstract_domain.mli index 318a78d9638e6accdd2b77bcd46ab3863dba8699..7c5861aa9420ac2df98b4be9602488d1d5e27355 100644 --- a/src/plugins/value/domains/abstract_domain.mli +++ b/src/plugins/value/domains/abstract_domain.mli @@ -260,7 +260,16 @@ module type Transfer = sig It is None if the call is not recursive. - [state] is the abstract state at the call site, before the call; - [valuation] is a cache for all values and locations computed during - the evaluation of the function and its arguments. *) + the evaluation of the function and its arguments. + + On recursive calls, [recursion] contains some substitution of variables + to be applied on the domain state to prevent mixing up local variables + and formal parameters of different recursive calls. + See {!Eval.recursion} for more details. + This substitution has been applied on values and expressions in [call], + but not in the [valuation] given as argument. If the domain uses some + information from the [valuation] on a recursive call, it must apply the + substitution on it. *) val start_call: stmt -> (location, value) call -> recursion option -> (value, location, origin) valuation -> state -> state or_bottom diff --git a/src/plugins/value/domains/cvalue/cvalue_domain.ml b/src/plugins/value/domains/cvalue/cvalue_domain.ml index e31a140be372267d31bb1b442596d2b15a44064a..80f885d59365f5a7cc965285394b602cf60d6a7e 100644 --- a/src/plugins/value/domains/cvalue/cvalue_domain.ml +++ b/src/plugins/value/domains/cvalue/cvalue_domain.ml @@ -245,6 +245,9 @@ module State = struct Model.replace_base substitution state let start_call stmt call recursion valuation (state, clob) = + (* Uses the [valuation] to update the [state] before the substitution + for recursive calls. *) + Cvalue_transfer.update valuation state >>- fun state -> let state = match recursion with | None -> state diff --git a/src/plugins/value/domains/cvalue/cvalue_transfer.ml b/src/plugins/value/domains/cvalue/cvalue_transfer.ml index 1e7bedefe0b5a6de16ade918a054f434eefd50ad..26518aa8d7c76a6a249d3c082b9131c453b4bbda 100644 --- a/src/plugins/value/domains/cvalue/cvalue_transfer.ml +++ b/src/plugins/value/domains/cvalue/cvalue_transfer.ml @@ -204,8 +204,7 @@ let actualize_formals state arguments = in List.fold_left treat_one_formal state arguments -let start_call _stmt call _recursion valuation state = - let state = update valuation state in +let start_call _stmt call _recursion _valuation state = let with_formals = actualize_formals state call.arguments in let stack_with_call = Value_util.call_stack () in Db.Value.Call_Value_Callbacks.apply (with_formals, stack_with_call); diff --git a/src/plugins/value/domains/equality/equality_domain.ml b/src/plugins/value/domains/equality/equality_domain.ml index 4bc2213fcca50717d73ea1232bf22b3791f81830..74925890fdce72eaba7ab228afc9f19b2cfe097f 100644 --- a/src/plugins/value/domains/equality/equality_domain.ml +++ b/src/plugins/value/domains/equality/equality_domain.ml @@ -479,12 +479,19 @@ module Make let start_call _stmt call recursion valuation state = let state = - match call_init_state call.kf with - | ISCaller -> assign_formals valuation call state - | ISFormals -> assign_formals valuation call empty - | ISEmpty -> empty + match recursion with + | Some recursion -> + (* No relation inferred from the assignment of formal parameters + for recursive calls, because the valuation cannot be used safely + as the substitution of local and formals variables has not been + applied to it. *) + start_recursive_call recursion state + | None -> + match call_init_state call.kf with + | ISCaller -> assign_formals valuation call state + | ISFormals -> assign_formals valuation call empty + | ISEmpty -> empty in - let state = Extlib.opt_fold start_recursive_call recursion state in `Value state let finalize_call _stmt call _recursion ~pre ~post = diff --git a/src/plugins/value/domains/gauges/gauges_domain.ml b/src/plugins/value/domains/gauges/gauges_domain.ml index 8b45d1c11ff3d93957311bea2aebefb4a161b7ec..23cef9f01a25a84154166592159a41ad9281d01c 100644 --- a/src/plugins/value/domains/gauges/gauges_domain.ml +++ b/src/plugins/value/domains/gauges/gauges_domain.ml @@ -1225,8 +1225,8 @@ module D_Impl : Abstract_domain.S let state = match function_calls_handling with | FullInterprocedural -> - let state = Extlib.opt_fold start_recursive_call recursion state in - update valuation state + update valuation state >>-: fun state -> + Extlib.opt_fold start_recursive_call recursion state | IntraproceduralAll | IntraproceduralNonReferenced -> `Value G.empty in diff --git a/src/plugins/value/domains/octagons.ml b/src/plugins/value/domains/octagons.ml index b63cce8fc729d45187ac9f79c61de50ef6b5ca4f..e45b1c875de6bb8e1421c9064e1366382cf1982f 100644 --- a/src/plugins/value/domains/octagons.ml +++ b/src/plugins/value/domains/octagons.ml @@ -1224,12 +1224,19 @@ module Domain = struct if intraprocedural () then `Value (empty ()) else - let state = Extlib.opt_fold start_recursive_call recursion state in let state = { state with modified = Locations.Zone.bottom } in - let assign_formal state { formal; concrete; avalue } = - state >>- assign_variable formal concrete avalue valuation - in - List.fold_left assign_formal (`Value state) call.arguments + match recursion with + | Some recursion -> + (* No relation inferred from the assignment of formal parameters + for recursive calls, because the valuation cannot be used safely + as the substitution of local and formals variables has not been + applied to it. *) + `Value (start_recursive_call recursion state) + | None -> + let assign_formal state { formal; concrete; avalue } = + state >>- assign_variable formal concrete avalue valuation + in + List.fold_left assign_formal (`Value state) call.arguments let finalize_call _stmt _call _recursion ~pre ~post = if intraprocedural () diff --git a/src/plugins/value/domains/offsm_domain.ml b/src/plugins/value/domains/offsm_domain.ml index 07872c80f08088ae3a979608cbee6894342a5196..70f2f43cccafd606c62e5c4484da7feb9601dc4d 100644 --- a/src/plugins/value/domains/offsm_domain.ml +++ b/src/plugins/value/domains/offsm_domain.ml @@ -164,8 +164,8 @@ module Internal : Domain_builder.InputDomain Memory.remove_variables vars state let start_call _stmt _call recursion valuation state = - let state = Extlib.opt_fold start_recursive_call recursion state in - update valuation state + update valuation state >>-: fun state -> + Extlib.opt_fold start_recursive_call recursion state let show_expr _valuation _state _fmt _expr = () diff --git a/src/plugins/value/domains/symbolic_locs.ml b/src/plugins/value/domains/symbolic_locs.ml index 03f5bb739613e085951385362ff3b686f4964a2c..bd2fab8b55a914f5c6639aef3a8a5c494a2fc54d 100644 --- a/src/plugins/value/domains/symbolic_locs.ml +++ b/src/plugins/value/domains/symbolic_locs.ml @@ -568,8 +568,8 @@ module Internal : Domain_builder.InputDomain Memory.remove_variables vars state let start_call _stmt _call recursion valuation state = - let state = Extlib.opt_fold start_recursive_call recursion state in - update valuation state + update valuation state >>-: fun state -> + Extlib.opt_fold start_recursive_call recursion state let finalize_call _stmt _call _recursion ~pre:_ ~post = `Value post