Consider this program:
#include<stdio.h> #include<stdlib.h> int main() { int *x = malloc(sizeof(int)); int *y = malloc(sizeof(int)); x = y; }
Ptranal produces this output, showing the internal pointer graph:
Computing points-to sets... tmp(1) -> malloc@3 tmp___0(1) -> malloc@4 x(2) -> malloc@3, malloc@4 y(1) -> malloc@4
This seems reasonable, each allocation site gets its own version of malloc.
However, when you query Ptranal through
Ptranal.resolve_lval (var v)
it conflates all the allocation sites; i.e. resolve_lval returns
a malloc varinfo, the same varinfo for all the sites. The @3, @4, etc.
are forgotten.
I don't know what the right way is to solve this, possibly a change
in the Ptranal interface. For right now, I use the following hack in
Ptranal.ml:
let next_alloc = function Lval (Var v, o) -> let name = Printf.sprintf "%s@%d" v.vname (fresh_index ()) in let vi = Cil.copyVarinfo v v.vname in (* added by CC *) A.address (A.make_lvalue false name (Some vi)) (* check *) | _ -> raise Bad_return
I.e., I create a new varinfo for malloc, for each call site, each
having a different vid. Presumably, this could break other things
downstream... Another possibility would be to keep the varinfo
vid the same, and change the name to malloc@3, malloc@4, etc.
At the very least, this behavior should be documented.