let compute_using_prototype kf  ~state_with_formals =
  match kf.fundec with
  | Definition (_,_) -> assert false
  | Declaration (_,vi,_,_) when Cil.hasAttribute "noreturn" vi.vattr ->
      NoneRelations_type.Model.bottom, Location_Bits.Top_Param.bottom
  | Declaration (_spec,varinfo,_,_) ->
      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
        | WritesAny -> Value_parameters.warning "Cannot handle empty assigns clause. Assuming assigns \\nothing: be aware this is probably incorrect.";
            state_with_formals
        | Writes [] -> state_with_formals
        | Writes l ->
            let treat_assign acc (out, ins) =
              let input_contents =
                try
                  match ins with
                      FromAny -> 
                       (* [VP] \from \nothing has the
                          same meaning as unspecified \from... *)

                        Cvalue_type.V.top_int
                    | From l ->
                      List.fold_left
                        (fun acc term ->
                          let input_loc =
                            !Db.Properties.Interp.identified_term_zone_to_loc
                              ~result:None
                              state_with_formals
                              term
                          in
                          let r =
                            Relations_type.Model.find
                              ~conflate_bottom:true
                              ~with_alarms:CilE.warn_none_mode
                              state_with_formals
                              input_loc
                          in
                         (*                 Format.printf "loc %a r %a@."
                                         Locations.pretty input_loc
                                         Cvalue_type.V.pretty r; *)

                          Cvalue_type.V.join acc r)
                        Cvalue_type.V.top_int
                        l
                with Invalid_argument "not an lvalue" ->
                  Value_parameters.result
                    ~once:true ~current:true
                    "cannot interpret assigns in function %a"
                    Kernel_function.pretty_name kf;
                  Cvalue_type.V.top
              in
              let treat_output_loc loc acc =
                remember_bases_with_locals
                  clobbered_set
                  loc
                  input_contents;
                let bound =
                  Relations_type.Model.add_binding
                    ~with_alarms:CilE.warn_none_mode
                    ~exact:false acc loc input_contents
                in
                bound
              in
              try
                let lvals_out =
                  try
                    !Db.Properties.Interp.loc_to_lval
                      ~result:None
                      out.it_content
                  with
                    Invalid_argument "not an lvalue" as e ->
                      begin
                        match out with
                            {it_content=
                                {term_node=
                                    TLval 
                                      (TMem 
                                         {term_node=TBinOp((IndexPI|PlusPI) ,
                                                           t1,_o1)}, _o2)}}
                            ->
                              let deref_lvals =
                                !Db.Properties.Interp.loc_to_lval 
                                  ~result:None t1
                              in
                          (*  Format.printf "input: %a@."
                              Cvalue_type.V.pretty input_contents ; *)

                              raise (Deref_lvals deref_lvals)
                          | _ -> raise e
                      end
                in
                let result =
                  List.fold_left
                    (fun acc lval ->
                      let loc =
                        lval_to_loc  ~with_alarms:CilE.warn_none_mode
                          state_with_formals lval
                      in
                      (* Format.printf "lval:%a loc:%a@."
                            !d_lval lval
                            Locations.pretty loc; *)

                      treat_output_loc loc acc
                    )
                    acc
                    lvals_out
                in
                result
              with
                Invalid_argument "not an lvalue" ->
                  if Logic_utils.is_result out.it_content then begin
                    returned_value :=
                      Cvalue_type.V.join
                      (Cvalue_type.V.topify_arith_origin
                         input_contents)
                      !returned_value;
                    acc
                  end else begin
                    Value_parameters.warning ~once:true ~current:true
                      "Can not interpret assigns in function %a; effects will be ignored"
                      Kernel_function.pretty_name kf; acc
                  end
              | Deref_lvals deref_lvals ->
                  let deref_loc =
                    List.fold_left
                      (fun acc lv ->
                        Location_Bits.join
                          (lval_to_loc ~with_alarms:CilE.warn_none_mode
                              state_with_formals lv).loc
                          acc)
                      Location_Bits.bottom
                      deref_lvals
                  in
                  let deref_loc = Location_Bits.topify_arith_origin deref_loc
                  in
                  let loc_bytes =
                    Relations_type.Model.find
                      ~conflate_bottom:true
                      ~with_alarms:CilE.warn_none_mode
                      state_with_formals
                      (make_loc deref_loc Int_Base.top)
                  in
                  let loc =
                    make_loc (loc_bytes_to_loc_bits loc_bytes) Int_Base.top
                  in
                  treat_output_loc loc acc
            in
            (List.fold_left treat_assign state_with_formals l)
      in
      let retres_vi, state =
        if isVoidType return_type
        then None, state
        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
          Library_functions.add_retres_to_state
            varinfo
            offsetmap
            state
      in
      retres_vi, state, !clobbered_set