let compute_using_prototype kf  ~state_with_formals =
  match kf.fundec with
  | Definition (_,_) -> assert false
  | Declaration (_spec,varinfo,_,_) ->
      if Cil.hasAttribute "noreturn" varinfo.vattr then
        NoneRelations_type.Model.bottom, Location_Bits.Top_Param.bottom
      else begin
        let return_type,_formals_type,_inline,_attr =
          splitFunctionType (Kernel_function.get_type kf)
        in
        let behaviors = valid_behaviors kf state_with_formals in
        let assigns = Ast_info.merge_assigns behaviors in
        let returned_value, state_with_formals =
          return_value return_type kf state_with_formals
        in
        let returned_value = ref returned_value in
        let clobbered_set = ref Location_Bits.Top_Param.bottom in
        let state =
          match assigns with
          | [] -> state_with_formals
          | assigns -> (*VP: same behavior as before, but it is weird:
                         \from \nothing has the
                         same meaning as unspecified \from...
                       *)

              let treat_assign acc (out, ins) =
                let input =
                  (try
                     List.fold_left
                       (fun acc loc ->
                          List.fold_left
                            (fun acc lv ->
                              let _,_,r =
                                eval_lval ~with_alarms:CilE.warn_none_mode None
                                  state_with_formals
                                  lv
                              in
                               Cvalue_type.V.join acc r)
                            acc
                            (match loc with
                             | Location loc ->
                                 !Db.Properties.Interp.loc_to_lval
                                   loc.it_content
                             | Nothing -> []))
                       Cvalue_type.V.top_int ins
                   with Invalid_argument "not a lvalue" ->
                     Value_parameters.result
                       ~once:true ~current:true
                       "cannot interpret assigns in function %a"
                       Kernel_function.pretty_name kf;
                     Cvalue_type.V.top)
                in
                try
                  List.fold_left
                    (fun acc lval ->
                       let loc =
                         lval_to_loc  ~with_alarms:CilE.warn_none_mode
                           state_with_formals lval
                       in
                       remember_bases_with_locals clobbered_set loc input;
                       let bound =
                         Relations_type.Model.add_binding
                           ~with_alarms:CilE.warn_none_mode
                           ~exact:false acc loc input
                       in
                       Relations_type.Model.join bound acc)
                    acc
                    (match out with
                     | Location out ->
                         !Db.Properties.Interp.loc_to_lval out.it_content
                     | Nothing -> [])
                with
                  Invalid_argument "not a lvalue" ->
                    (match out with
                       Location out when
                         Logic_utils.is_result out.it_content ->
                           returned_value :=
                             Cvalue_type.V.join
                               (Cvalue_type.V.topify_arith_origin input)
                               ! returned_value;
                           acc
                     | Location _ ->
                         Value_parameters.warning ~once:true ~current:true
                           "Can not interpret assigns in function %a; effects will be ignored"
                           Kernel_function.pretty_name kf; acc
                     | Nothing -> assert false (* should not raise a failure
                                                  when converting to cloc *)
)
              in
              (List.fold_left treat_assign state_with_formals assigns)
        in
        (if isVoidType return_type then None else
           let offsetmap =
             V_Offsetmap.update_ival
               ~with_alarms:CilE.warn_none_mode
               ~validity:Base.All
               ~offsets:Ival.zero
               ~exact:true
               ~size:(Int.of_int (bitsSizeOf return_type))
               V_Offsetmap.empty
               (Cvalue_type.V_Or_Uninitialized.initialized !returned_value)
           in
           Some offsetmap),
        (Relations_type.Model.filter_base 
            (* TODO: Just remove the formals without iterating
               over the state *)

           (fun base -> not (Base.is_formal_of_prototype base varinfo))
           state),
        !clobbered_set
      end