Transcript PPT

Pointer Aliasing
Analysis for C programs
(Computing PE relation)
A. Aniruddha
What is aliasing?
Two names access same location
during program execution.
E.g. p = &x; p and x refer to same
memory location.
Problems:
Variables may be indirectly affected by
value setting statements.
Why aliasing analysis?
Reverse engineering.
Code understanding.
 Call graph construction.

Program optimization and
transformation.
Version control, run time checking.
Data flow based testing.
The PE relation
PE(pointer related equality) is an
equivalence relation.
Uniquely partitions program statements
into sets.
Terms and Concepts
Object names: Memory locations or
addresses of memory locations.
Accessor: a struct field
access(.field) or a pointer dereference(*).
apply (object, accessor) :
returns object name after application of
the accessor.
E.g: apply(*p,f) = p->f.
Contd…
apply*(object, accessor_list)
applies a sequence of accessors.
E.g: apply*(p, * f) = p->f.
Prefix: o1 is a prefix of o2 if there exists
a list of accessors a1,a2 … an such that
o2 = apply*(o1,a1 a2 … an).
An object of the form &o cannot appear
on the LHS of an assignment.
Set of Object names
The set of object names (B0) is defined as:





If o syntactically appears in the program, then o 
B0.
If o  B0 is of structure type, for each field field
of the structure, apply(o, field)  B0.
If o is of the form &o1, then o1  B0.
If o  B0 and o = apply(o1, field), then o1
 B0.
If o  B0 and o = apply(o1, *), then o1  B0.
Algorithm
MERGE (e1, e2) {
Calculate-PE-relation {
e = UNION (e1, e2); /* Union the two classes */
/* Phase 1 */
/*for
Calculate
prefix relation */
each o the
B0 new
{
INIT-EQUIV-CLASS
(o);
new-prefix
= prefix[e1];
prefix[FIND (o)] = { };
for each (a, o)  prefix[e2]
}
if there
for each
o  B0is (a1, o1)  new-prefix such that a == a1
if (o =={ &o1)
add (*, o1) to prefix[FIND (o)];
(o) (o
 ,
FIND
(o1))
else if if
(o (FIND
== apply
*) )
1
add (*, MERGE
o) to (FIND
prefix[FIND
(o1)];
(o), FIND
(o1))
else if }(o == apply (o1, field) )
add (field, o) to prefix[FIND (o1)];
else2 */
/* Phase
for each pointer-related
= rhs
new-prefix = assignment,
new-prefix lhs
{ (a,
o) }
if (FIND (lhs)  FIND (rhs))
prefix[e] = new-prefix;/* set the new prefix relation */
MERGE (FIND (lhs), FIND (rhs));
}}
Working
The process:
/* Sample program */
• Construct B0.
struct st {int *f, g; };
• Initialize equivalence classes.
main ( ) {
• Compute PE relation.
struct st x, *p;
int z, u, *r, *y;
z = 0;
r
y
u
&u
p = &x;
p
*p
p->f
p->g
x
&x
x.f
x.g
z
&z
p->f = &z;
r = &u;
y = r;
}
P->f,
&z&z
&u
r,
r, &u,
&u r
y
P->f
y
x.f
p
*pp, &x
x.g
x
x*p, &x
z
P->g
u
Conclusion
Pointer analysis is a compile time
analysis – low cost.
Can be used to avoid serious problems
that may not be known until run-time.
Helps understand data usage pattern
and hence to test, modify and maintain
code.