method vstmt_aux s =
    let preaction s = match s.skind with
      | If(e,tbl,fbl,_loc) ->
          begin match destruct_string_test e with _,None -> ()
            | test_to_null,Some(neg,v,off) ->
                if hasAttribute name_of_string_declspec (typeAttrs v.vtype)
                then
                  (* A string should be tested within its bounds, and
                     depending on the result, the offset is either before
                     or equal to the length of the string *)

                  let off =
                    !Db.Properties.Interp.force_exp_to_term locUnknown off
                  in
                  let rel1 = within_bounds ~strict:true v off in
                  let supst = mkStmt(Instr(Skip(CurrentLoc.get()))) in
                  Annotations.add_alarm
                    supst ~before:true Alarms.Other_alarm rel1;

                  let rel2 = reach_upper_bound ~loose:false v off in
                  let eqst = mkStmt(Instr(Skip(CurrentLoc.get()))) in
                  Annotations.add_alarm
                    eqst ~before:true Alarms.Other_alarm rel2;

                  (* Rather add skip statement as blocks may be empty *)
                  if neg then
                    begin
                      fbl.bstmts <- supst :: fbl.bstmts;
                      if test_to_null then tbl.bstmts <- eqst :: tbl.bstmts
                    end
                  else
                    begin
                      tbl.bstmts <- supst :: tbl.bstmts;
                      if test_to_null then fbl.bstmts <- eqst :: fbl.bstmts
                    end
          end; s
      | Instr(Set(lv,e,_loc)) when is_null_expr e ->
          if Jessie_options.HintLevel.get () > 1 then
            match lval_destruct_string_access ~through_tmp:true lv with
              | None -> ()
              | Some(v,off) ->
                  let off =
                    !Db.Properties.Interp.force_exp_to_term locUnknown off
                  in
                  (* Help ATP with proving the bound on [strlen(v)] by
                     asserting the obvious equality *)

                  let lv' = !Db.Properties.Interp.force_lval_to_term_lval
                    locUnknown lv
                  in
                  let e' = !Db.Properties.Interp.force_exp_to_term
                    locUnknown e
                  in
                  let lvt = mkterm (TLval lv') strlen_type locUnknown in
                  let rel =
                    Logic_const.new_predicate (Logic_const.prel (Req,lvt,e'))
                  in
                  let prel = Logic_const.pred_of_id_pred
                    { rel with ip_name = [ name_of_hint_assertion ] }
                  in
                  Annotations.add_alarm
                    s ~before:false Alarms.Other_alarm prel;
                  (* Further help ATP by asserting that index should be
                     positive *)

(*                   let rel = *)
(*                     Logic_const.new_predicate  *)
(*                       (Logic_const.prel (Rle,lzero(),off)) *)
(*                   in *)
(*                   let prel = Logic_const.pred_of_id_pred *)
(*                     { rel with ip_name = [ name_of_hint_assertion ] } *)
(*                   in *)
(*                   Annotations.add_alarm *)
(*                     s ~before:false Alarms.Other_alarm prel; *)
                  (* If setting a character to zero in a buffer, this should
                     be the new length of a string *)

                  let rel = reach_upper_bound ~loose:true v off in
                  Annotations.add_alarm
                    s ~before:false Alarms.Other_alarm rel
          else ();
          s
      | Instr(Set((Var v1,NoOffset),e,_loc)) ->
          begin match
            destruct_string_access ~through_tmp:true ~through_cast:true e
          with
            | None -> ()
            | Some(v2,off) -> VarinfoHashtbl.add temps v1 (v2,off)
          end; s
      | _ -> s
    in
    ChangeDoChildrenPost(preaction s,fun x -> x)