diff --git a/src/plugins/eva/api/general_requests.ml b/src/plugins/eva/api/general_requests.ml
index c0a00d85c44e01f46c72940bc810081d2fe0db78..1247eda023de6562ec6a24325ede9fb52c206701 100644
--- a/src/plugins/eva/api/general_requests.ml
+++ b/src/plugins/eva/api/general_requests.ml
@@ -183,39 +183,78 @@ let () = Request.register ~package
 
 (* ----- Register Eva values information ------------------------------------ *)
 
+type evaluation_point =
+  | Initial
+  | Pre of kernel_function
+  | Stmt of stmt
+
+let post kf =
+  if Analysis.use_spec_instead_of_definition kf
+  then raise Not_found
+  else
+    try Stmt (Kernel_function.find_return kf)
+    with Kernel_function.No_Statement -> raise Not_found
+
+let request_at = function
+  | Initial -> Results.at_start
+  | Stmt stmt -> Results.before stmt
+  | Pre kf -> Results.at_start_of kf
+
+let property_evaluation_point = function
+  | Property.IPCodeAnnot { ica_stmt = stmt }
+  | IPPropertyInstance { ii_stmt = stmt } -> Stmt stmt
+  | IPPredicate {ip_kf; ip_kind = PKEnsures (_, Normal)} -> post ip_kf
+  | IPPredicate { ip_kf = kf;
+                  ip_kind = PKRequires _ | PKAssumes _ | PKTerminates }
+  | IPAssigns {ias_kf = kf} | IPFrom {if_kf = kf} ->
+    Pre kf
+  | IPPredicate _ | IPComplete _ | IPDisjoint _ | IPDecrease _
+  | IPAxiomatic _ | IPLemma _ | IPTypeInvariant _ | IPGlobalInvariant _
+  | IPOther _ | IPAllocation _ | IPReachable _ | IPExtended _ | IPBehavior _ ->
+    raise Not_found
+
+let marker_evaluation_point = function
+  | Printer_tag.PGlobal _ -> Initial
+  | PStmt (_, stmt) | PStmtStart (_, stmt) -> Stmt stmt
+  | PLval (kf, ki, _) | PExp (kf, ki, _) | PVDecl (kf, ki, _) ->
+    begin
+      match kf, ki with
+      | _, Kstmt stmt -> Stmt stmt
+      | Some kf, Kglobal -> Pre kf
+      | None, Kglobal -> Initial
+    end
+  | PTermLval (_, _, prop, _) | PIP prop -> property_evaluation_point prop
+  | PType _ -> raise Not_found
+
 let term_lval_to_lval tlval =
   try Logic_to_c.term_lval_to_lval tlval
   with Logic_to_c.No_conversion -> raise Not_found
 
 let print_value fmt loc =
   let is_scalar = Cil.isScalarType in
-  let kf, kinstr, eval =
+  let evaluation_point = marker_evaluation_point loc in
+  let request = request_at evaluation_point in
+  let eval =
     match loc with
-    | Printer_tag.PLval (kf, ki, lval) when is_scalar (Cil.typeOfLval lval) ->
-      kf, ki, Results.eval_lval lval
-    | Printer_tag.PExp (kf, ki, expr) when is_scalar (Cil.typeOf expr) ->
-      kf, ki, Results.eval_exp expr
-    | PVDecl (kf, ki, vi) when is_scalar vi.vtype ->
-      kf, ki, Results.eval_var vi
-    | PTermLval (kf, ki, _ip, tlval) ->
+    | Printer_tag.PLval (_, _, lval) when is_scalar (Cil.typeOfLval lval) ->
+      Results.eval_lval lval
+    | Printer_tag.PExp (_, _, expr) when is_scalar (Cil.typeOf expr) ->
+      Results.eval_exp expr
+    | PVDecl (_, _, vi) when is_scalar vi.vtype ->
+      Results.eval_var vi
+    | PTermLval (_, _, _ip, tlval) ->
       let lval = term_lval_to_lval tlval in
       if is_scalar (Cil.typeOfLval lval)
-      then kf, ki, Results.eval_lval lval
+      then Results.eval_lval lval
       else raise Not_found
     | _ -> raise Not_found
   in
   let pretty = Cvalue.V_Or_Uninitialized.pretty in
   let eval_cvalue at = Results.(eval at |> as_cvalue_or_uninitialized) in
-  let request =
-    match kf, kinstr with
-    | _, Kstmt stmt -> Results.before stmt
-    | Some kf, Kglobal -> Results.at_start_of kf
-    | None, Kglobal -> Results.at_start
-  in
   let before = eval_cvalue request in
-  match kinstr with
-  | Kglobal -> pretty fmt before
-  | Kstmt stmt ->
+  match evaluation_point with
+  | Initial | Pre _ -> pretty fmt before
+  | Stmt stmt ->
     let after = eval_cvalue (Results.after stmt) in
     if Cvalue.V_Or_Uninitialized.equal before after
     then pretty fmt before
diff --git a/src/plugins/eva/api/general_requests.mli b/src/plugins/eva/api/general_requests.mli
index 6472763b7e5187d8703feffb06c7581d7b81282f..57502fa634b02596890e3ef4a16e847ba2b2644a 100644
--- a/src/plugins/eva/api/general_requests.mli
+++ b/src/plugins/eva/api/general_requests.mli
@@ -21,3 +21,14 @@
 (**************************************************************************)
 
 (** General Eva requests registered in the server. *)
+
+open Cil_types
+
+type evaluation_point =
+  | Initial
+  | Pre of kernel_function
+  | Stmt of stmt
+
+(* Returns the evaluation point of a marker.
+   @raises Not_found if the marker cannot be evaluated. *)
+val marker_evaluation_point: Printer_tag.localizable -> evaluation_point
diff --git a/src/plugins/eva/api/values_request.ml b/src/plugins/eva/api/values_request.ml
index 094ca793a92f84a12a86432bb8f74c5b6af3d909..93040df685bec0cb5ef89dbe23a4d246b2dc2113 100644
--- a/src/plugins/eva/api/values_request.ml
+++ b/src/plugins/eva/api/values_request.ml
@@ -42,14 +42,12 @@ let package =
     ~title:"Eva Values"
     ()
 
-(* Term to evaluate. *)
 type term = Pexpr of exp | Plval of lval | Ppred of predicate
+type evaluation_point = General_requests.evaluation_point =
+    Initial | Pre of kernel_function | Stmt of stmt
 
-(* A term and the program point where it should be evaluated:
-   - at a statement of a function: Some kf, Kstmt stmt.
-   - at the start of a function: Some kf, Kglobal.
-   - at the start of the analysis: None, Kglobal. *)
-type probe = term * kernel_function option * kinstr
+(* A term and the program point where it should be evaluated. *)
+type probe = term * evaluation_point
 
 type callstack = Value_types.callstack
 type truth = Abstract_interp.truth
@@ -87,8 +85,8 @@ let () = Analysis.register_computation_hook ~on:Computed
 (* -------------------------------------------------------------------------- *)
 
 let next_steps = function
-  | Kglobal -> []
-  | Kstmt stmt ->
+  | Initial | Pre _ -> []
+  | Stmt stmt ->
     match stmt.skind with
     | If (cond, _, _, _) -> [ `Then cond ; `Else cond ]
     | Instr (Set _ | Call _ | Local_init _) -> [ `After ]
@@ -97,49 +95,45 @@ let next_steps = function
     | TryCatch _ | TryFinally _ | TryExcept _
     | Instr (Skip _) | Return _ | Break _ | Continue _ | Goto _ | Throw _ -> []
 
-let probe_stmt kf stmt =
-  let term =
-    match stmt.skind with
-    | Instr (Set (lv,_,_)) -> Some (Plval lv)
-    | Instr (Call (Some lr,_,_,_)) -> Some (Plval lr)
-    | Instr (Local_init (v,_,_)) -> Some (Plval (Var v,NoOffset))
-    | Return (Some e,_) | If (e,_,_,_) | Switch (e,_,_,_) -> Some (Pexpr e)
-    | _ -> None
-  in
-  Option.map (fun t -> (t, Some kf, Kstmt stmt)) term
+let probe_stmt stmt =
+  match stmt.skind with
+  | Instr (Set (lv, _, _))
+  | Instr (Call (Some lv, _, _, _)) -> Plval lv
+  | Instr (Local_init (v, _, _)) -> Plval (Var v, NoOffset)
+  | Return (Some e, _) | If (e, _, _, _) | Switch (e, _, _, _) -> Pexpr e
+  | _ -> raise Not_found
 
-let probe_code_annot kf stmt = function
-  | AAssert (_, p) | AInvariant (_, true, p) ->
-    Some (Ppred p.tp_statement, Some kf, Kstmt stmt)
-  | _ -> None
+let probe_code_annot = function
+  | AAssert (_, p) | AInvariant (_, true, p) -> Ppred p.tp_statement
+  | _ -> raise Not_found
 
 let probe_property = function
-  | Property.IPCodeAnnot ica ->
-    probe_code_annot ica.ica_kf ica.ica_stmt ica.ica_ca.annot_content
-  | IPPropertyInstance { ii_kf; ii_stmt; ii_pred=Some pred;} ->
-    let pred = Logic_const.pred_of_id_pred pred in
-    Some (Ppred pred, Some ii_kf, Kstmt ii_stmt)
-  | _ -> None
-
-let probe_term_lval kf kinstr tlval =
+  | Property.IPCodeAnnot ica -> probe_code_annot ica.ica_ca.annot_content
+  | IPPropertyInstance { ii_pred = Some pred } ->
+    Ppred (Logic_const.pred_of_id_pred pred)
+  | _ -> raise Not_found
+
+let probe_term_lval kf tlval =
   try
     let result = Option.bind kf Library_functions.get_retres_vi in
-    let lval = Logic_to_c.term_lval_to_lval ?result tlval in
-    Some (Plval lval, kf, kinstr)
-  with Logic_to_c.No_conversion -> None
+    Plval (Logic_to_c.term_lval_to_lval ?result tlval)
+  with Logic_to_c.No_conversion -> raise Not_found
+
+let probe_marker = function
+  | Printer_tag.PLval (_, _, (Var vi, NoOffset))
+  | PVDecl (_, _, vi) when Cil.isFunctionType vi.vtype -> raise Not_found
+  | PLval (_, _, l) -> Plval l
+  | PExp (_, _, e) -> Pexpr e
+  | PStmt (_, s) | PStmtStart (_, s) -> probe_stmt s
+  | PVDecl (_, _, v) -> Plval (Var v, NoOffset)
+  | PTermLval (kf, _, _, tlval) -> probe_term_lval kf tlval
+  | PIP property -> probe_property property
+  | _ -> raise Not_found
 
 let probe marker =
-  let open Printer_tag in
-  match marker with
-  | PLval (_, _, (Var vi, NoOffset))
-  | PVDecl (_, _, vi) when Cil.isFunctionType vi.vtype -> None
-  | PLval (kf, kinstr, l) -> Some (Plval l, kf, kinstr)
-  | PExp (kf, kinstr, e) -> Some (Pexpr e, kf, kinstr)
-  | PStmt (kf, s) | PStmtStart (kf, s) -> probe_stmt kf s
-  | PVDecl (kf, kinstr, v) -> Some (Plval (Var v, NoOffset), kf, kinstr)
-  | PTermLval (kf, kinstr, _, tlval) -> probe_term_lval kf kinstr tlval
-  | PIP property -> probe_property property
-  | _ -> None
+  try Some (probe_marker marker,
+            General_requests.marker_evaluation_point marker)
+  with Not_found -> None
 
 (* -------------------------------------------------------------------------- *)
 (* --- Stmt Ranking                                                       --- *)
@@ -403,11 +397,10 @@ module Proxy(A : Analysis.S) : EvaProxy = struct
   let get_initial_state =
     get_state A.get_initial_state A.get_initial_state_by_callstack
 
-  let get_state kf kinstr callstack =
-    match kf, kinstr with
-    | Some _, Kstmt stmt -> get_stmt_state ~after:false stmt callstack
-    | Some kf, Kglobal -> get_initial_state kf callstack
-    | None, _ -> A.get_global_state ()
+  let domain_state callstack = function
+    | Initial -> A.get_global_state ()
+    | Pre kf -> get_initial_state kf callstack
+    | Stmt stmt -> get_stmt_state ~after:false stmt callstack
 
   (* --- Converts an evaluation [result] into an exported [value]. ---------- *)
 
@@ -428,9 +421,17 @@ module Proxy(A : Analysis.S) : EvaProxy = struct
     | Offsetmap offsm -> get_pointed_bases offsm
     | Status _ -> Base.Hptset.empty
 
-  let get_pointed_markers kf kinstr result =
+  let get_pointed_markers eval_point result =
     let bases = get_pointed_bases result in
     let vars = filter_variables bases in
+    let kf, kinstr =
+      match eval_point with
+      | Initial -> None, Kglobal
+      | Pre kf -> Some kf, Kglobal
+      | Stmt stmt ->
+        let kf = Kernel_function.find_englobing_kf stmt in
+        Some kf, Kstmt stmt
+    in
     let to_marker vi =
       let text = Pretty_utils.to_string Printer.pp_varinfo vi in
       let marker = Printer_tag.PLval (kf, kinstr, Cil.var vi) in
@@ -439,13 +440,13 @@ module Proxy(A : Analysis.S) : EvaProxy = struct
     List.map to_marker vars
 
   (* Creates an exported [value] from an evaluation result. *)
-  let make_value typ kf kinstr (result, alarms) =
+  let make_value typ eval_point (result, alarms) =
     let descr = Format.asprintf "@[<hov 2>%a@]" Alarms.pretty in
     let f alarm status acc = (status, descr alarm) :: acc in
     let alarms = Alarmset.fold f [] alarms |> List.rev in
     let pretty_eval = Bottom.pretty (pp_result typ) in
     let value = Pretty_utils.to_string pretty_eval result in
-    let pointed_markers = get_pointed_markers kf kinstr in
+    let pointed_markers = get_pointed_markers eval_point in
     let pointed_vars = Bottom.fold ~bottom:[] pointed_markers result in
     { value; alarms; pointed_vars }
 
@@ -493,30 +494,30 @@ module Proxy(A : Analysis.S) : EvaProxy = struct
       After (eval after_state)
     | _ -> Nothing
 
-  let eval_steps typ eval kf kinstr callstack =
+  let eval_steps typ eval eval_point callstack =
     let default value = { value; alarms = []; pointed_vars = []; } in
     let eval = function
       | `Bottom -> default "Unreachable"
       | `Top -> default "No information"
-      | `Value state -> make_value typ kf kinstr (eval state)
+      | `Value state -> make_value typ eval_point (eval state)
     in
-    let before = get_state kf kinstr callstack in
+    let before = domain_state callstack eval_point in
     let here = eval before in
     let next =
-      match before, kinstr with
-      | (`Bottom | `Top), _ | _, Kglobal -> Nothing
-      | `Value state, Kstmt stmt -> do_next eval state stmt callstack
+      match before, eval_point with
+      | `Value state, Stmt stmt -> do_next eval state stmt callstack
+      | _ -> Nothing
     in
     { here; next; }
 
-  let evaluate (term, kf, kinstr) callstack =
+  let evaluate (term, eval_point) callstack =
     match term with
     | Plval lval ->
-      eval_steps (Cil.typeOfLval lval) (eval_lval lval) kf kinstr callstack
+      eval_steps (Cil.typeOfLval lval) (eval_lval lval) eval_point callstack
     | Pexpr expr ->
-      eval_steps (Cil.typeOf expr) (eval_expr expr) kf kinstr callstack
+      eval_steps (Cil.typeOf expr) (eval_expr expr) eval_point callstack
     | Ppred pred ->
-      eval_steps Cil.intType (eval_pred pred) kf kinstr callstack
+      eval_steps Cil.intType (eval_pred pred) eval_point callstack
 end
 
 let proxy =
@@ -541,9 +542,9 @@ let () =
       let gather_callstacks cset marker =
         let list =
           match probe marker with
-          | Some (_, _, Kstmt stmt) -> A.stmt_callstacks stmt
-          | Some (_, Some kf, Kglobal) -> A.kf_callstacks kf
-          | Some (_, _, Kglobal) | None -> []
+          | Some (_, Stmt stmt) -> A.stmt_callstacks stmt
+          | Some (_, Pre kf) -> A.kf_callstacks kf
+          | Some (_, Initial) | None -> []
         in
         List.fold_left (fun set elt -> CSet.add elt set) cset list
       in
@@ -588,11 +589,10 @@ let () =
 (* --- Request getProbeInfo                                               --- *)
 (* -------------------------------------------------------------------------- *)
 
-let is_reachable kf kinstr =
-  match kf, kinstr with
-  | _, Kstmt stmt -> Results.is_reachable stmt
-  | Some kf, Kglobal -> Results.is_called kf
-  | None, Kglobal -> Results.is_reachable_kinstr Kglobal
+let is_reachable = function
+  | Stmt stmt -> Results.is_reachable stmt
+  | Pre kf -> Results.is_called kf
+  | Initial -> Results.is_reachable_kinstr Kglobal
 
 let () =
   let getProbeInfo = Request.signature ~input:(module Jmarker) () in
@@ -612,18 +612,18 @@ let () =
       ~name:"condition" ~descr:(Md.plain "Conditional statement")
       ~default:false (module Jbool)
   in
-  let set_probe rq pp p kf kinstr =
+  let set_probe rq pp p eval_point =
     let computed = Analysis.is_computed () in
-    let reachable = is_reachable kf kinstr in
+    let reachable = is_reachable eval_point in
     set_evaluable rq (computed && reachable);
     set_code rq (Some (Pretty_utils.to_string pp p)) ;
-    set_stmt rq (match kinstr with Kglobal -> None | Kstmt s -> Some s) ;
+    set_stmt rq (match eval_point with Stmt s -> Some s | _ -> None) ;
     let on_steps = function
       | `Here -> ()
       | `Then _ | `Else _ -> set_condition rq true
       | `After -> set_effects rq true
     in
-    List.iter on_steps (next_steps kinstr)
+    List.iter on_steps (next_steps eval_point)
   in
   Request.register_sig ~package getProbeInfo
     ~kind:`GET ~name:"getProbeInfo"
@@ -631,11 +631,11 @@ let () =
     begin fun rq marker ->
       match probe marker with
       | None -> set_evaluable rq false
-      | Some (term, kf, kinstr) ->
+      | Some (term, eval_point) ->
         match term with
-        | Plval l -> set_probe rq Printer.pp_lval l kf kinstr
-        | Pexpr e -> set_probe rq Printer.pp_exp e kf kinstr
-        | Ppred p -> set_probe rq Printer.pp_predicate p kf kinstr
+        | Plval l -> set_probe rq Printer.pp_lval l eval_point
+        | Pexpr e -> set_probe rq Printer.pp_exp e eval_point
+        | Ppred p -> set_probe rq Printer.pp_predicate p eval_point
     end
 
 (* -------------------------------------------------------------------------- *)