method vinst =
    function
      | Set(lv,e,loc) ->
          (* Type of [e] has not been changed by retyping formals and return. *)
          if isStructOrUnionType (typeOf e) then
            ChangeTo (expand_assign lv e (typeOf e) loc)
          else SkipChildren
      | Call(lvo,callee,args,loc) ->
          let args = List.map (fun arg ->
            (* Type of [arg] has not been changed. *)
            if isStructOrUnionType (typeOf arg) then
              match arg.enode with
              | Lval lv -> Cabs2cil.mkAddrOfAndMark lv
              | _ -> assert false (* Should not be possible *)
            else arg
          ) args in
          begin match lvo with
            | None ->
                (* TODO: free memory for structure return, even if not used.
                   Check that no temporary is added in every case, which would
                   make treatment here useless. *)

                let call = Call (lvo, callee, args, loc) in
                ChangeTo [call]
            | Some lv ->
                (* Type of [lv] has not been changed. *)
                let lvty = typeOfLval lv in
                if isStructOrUnionType lvty then
                  let tmpv = makeTempVar !curFundec (mkTRef lvty) in
                  let tmplv = Var tmpv, NoOffset in
                  let call = Call(Some tmplv,callee,args,loc) in
                  let deref =
                    new_exp (Lval(mkMem
                                    (new_exp (Lval(Var tmpv,NoOffset)))
                                    NoOffset))
                  in
                  let assign = mkassign lv deref loc in
                  let free = mkfree tmpv loc in
                  ChangeTo [call;assign;free]
                else
                  let call = Call(lvo,callee,args,loc) in
                  ChangeTo [call]
          end
      | Asm _ | Skip _ | Code_annot _ -> SkipChildren