From: Gabriel K. <ke...@pp...> - 2009-12-17 23:24:16
|
Hi, On Thu, Dec 17, 2009 at 03:46:32PM -0700, ThanhVu (Vu) Nguyen wrote: > 1) After I change the original statement s to a new one s' , I want > s'.id to be the same as s.id. Using the "method vinst", I cannot do > this. You can, but you have to use the mutable property of the fields rather than returning ChangeTo (which will build a new statement, i.e. generate a new id). In that case, you seem to be stuck with hacking things in vstmt as you originally did (but I might have overlooked some clever way to proceed). I juste realized that the following could work (to be tested): method vstmt s = match s.skind with | Instr l -> ChangeDoChildrenPost (s, fun new_s -> new_s.sid <- s.sid; new_s) | _ -> DoChildren This should restore the sid (no idea if anything bad can happen). > 2) Does it look correct ? No. > method vinst i = ( > match i with > |Call (None,Lval(Var v,os),expl,loc) -> ( > v.vname <- v.vname ^ "_NEW" ; This is an example of mutating things directly, but you have to remember that the varinfo is *shared* across your program (i.e. a given single varinfo is used everywhere you need to invoke some variable). Hence, here, you are adding _NEW not only in some precise spots, but everywhere in your program as a side-effect. You should build a copy of the variable with a different vname, and use this one instead: let v' = { v with vname = v.vname ^ "_NEW" } in ChangeTo([ ... v' ... ]) This might break some CIL invariant, though, since the v' variable is not declared in the AST. > ChangeTo([Call(None,Lval(Var v,os),expl,loc)]) > ) > |_ -> SkipChildren > ) > What I intend to do eventually is changing statements "sprintf" to > "snprintf". Note that I don't want to change _all_ of these sprintf > statements but only specific ones based on their sid's. The clean solution in your case is to use Cil.findOrCreateFunc to initialize some varinfo (with snprintf) and use it directly in vinst: class sprintfV file = let snprintf_typ = (* you have to figure it out manually... *) in let snprintf_vi = findOrCreateFunc file "snprintf" snprintf_typ in object ... method vinst i = ... use snprintf_vi here instead of v' ... ... end Regards, -- Gabriel Kerneis |