1
Interprocedural pointer analysis for C
• We’ll look at Wilson & Lam PLDI 95, and focus
on two problems solved by this paper:
– how to represent pointer information in the presence
of casts, pointer arithmetic, unions, and all the rest of
C.
– how to perform context-sensitive pointer analysis
interprocedurally in a way that provides good
precision at reasonable costs.
Representing pointer information for C
•
Problem:
– C types can be subverted by type casts: an int can in fact be a
pointer.
– Pointer arithmetic can lead to subobject boundaries being
crossed.
•
So, ignore the type system and subobject boundaries.
Instead use a representation that decides what’s a
pointer based on how it is used.
•
Treat memory as composed of blocks of bits:
– each local, global variable is a block
– each malloc returns a block.
•
Assume that casts and pointer arithmetic do
not
cross
object boundaries.
Location sets
•
Location set is a triple (block,offset,stride), which represents the set
of locations:
–
{ offset + i
stride | i
±
Ints}
(array,0,elmtSize)
array[i]
(p,0,1)
(array,offs(F),elmtSize)
array[i].F
(struct,offs(F),0)
struct.F
(scalar,0,0)
scalar
Location Set
Expression
•
This representation distinguishes between different fields within a
structure, but not the different elements of an array.
F
F
F
stride
offset
stride
Points-to graphs with locations sets
Points-to graph at L3:
struct Complex {
real* r;
real* i;
}
void f(int u,int v,
Complex a[]) {
L1: a[u].r := new real;
L2: a[u].i := new real;
p := a[v].r;
L3: .
..
}
Points-to graphs with locations sets
Points-to graph at L3:
(p,0,0)
(a,offs(r),
sizeof(Complex))
struct Complex {
real* r;
real* i;
}
void f(int u,int v,
Complex a[]) {
L1: a[u].r := new real;
L2: a[u].i := new real;
p := a[v].r;
L3: .
..
}
(S1,0,0)
(a,offs(i),
sizeof(Complex))
(S2,0,0)
Interprocedural pointer analysis
• Context-insensitive
– Smears effects of callers together. We can do better
than that!
• Context-sensitive: total transfer function (bottom