Program Analysis via 3

Program Analysis
via 3-Valued Logic
Thomas Reps
University of Wisconsin
Joint work with Mooly Sagiv and Reinhard Wilhelm
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
NULL
y
1
2
x
3
NULL
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Materialization
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
t
y
NULL
x
Original Problem: Shape Analysis
• Characterize dynamically allocated data
– x points to an acyclic list, cyclic list, tree, dag, etc.
– data-structure invariants
• Identify may-alias relationships
• Establish “disjointedness” properties
– x and y point to structures that do not share cells
Formalizing “.
. .”
Informal:
x
Formal:
x
Summary
node
Why is Shape Analysis Difficult?
• Destructive updating through pointers
– pnext = q
– Produces complicated aliasing relationships
• Dynamic storage allocation
– No bound on the size of run-time data structures
• Data-structure invariants typically only hold
at the beginning and end of operations
– Need to verify that data-structure invariants are
re-established
Applications: Code Optimization
• Machine-independent optimizations
– constant propagation
– loop-invariant code motion
– common subexpression elimination
• Machine-dependent optimizations
– register allocation
– parallelization
– software prefetching
• Insert storage-reclamation operations
• Eliminate or move “checking code”
Applications: Software Tools
• Static detection of memory errors (cleanness)
– dereferencing NULL pointers
– dereferencing dangling pointers
– memory leaks
• Static detection of logical errors
– Is a shape invariant restored?
• What is in the heap?
– list? doubly-linked list? tree? DAG?
– disjoint? intertwined?
Properties of reverse(x)
• On entry: x points to an acyclic list
• On exit: y points to an acyclic list
• On exit: x = = NULL
• On each iteration, x and y point to disjoint
acyclic lists
• All the pointer dereferences are safe
• No memory leaks
A ‘Yacc’ for Shape Analysis: TVLA
• Parametric framework
– Some instantiations  known analyses
– Other instantiations  new analyses
A ‘Yacc’ for Shape Analysis: TVLA
• Parametric framework
– Some instantiations  known analyses
– Other instantiations  new analyses
• Applications beyond shape analysis
– Partial correctness of sorting algorithms
– Safety of mobile code
– Deadlock detection in multi-threaded programs
– Partial correctness of mark-and-sweep gc alg.
A ‘Yacc’ for Static Analysis: TVLA
• Parametric framework
– Some instantiations  known analyses
– Other instantiations  new analyses
• Applications beyond shape analysis
– Partial correctness of sorting algorithms
– Safety of mobile code
– Deadlock detection in multi-threaded programs
– Partial correctness of mark-and-sweep gc alg.
A ‘Yacc’ for Static Analysis
(Using Logic)
• Correctness proofs via inductive-assertion method
• Proof derivation via weakest-precondition calculus
• “Annotate your loops with invariants!”
A ‘Yacc’ for Static Analysis
(Using Logic)
“I learned many things – and equally important
– I unlearned many things.” — S.K. Allison
WP
• Correctness proofs via inductive-assertion method
• Proof derivation via weakest-precondition calculus
• “Annotate your loops with invariants!”
A ‘Yacc’ for Static Analysis
(Using Logic)
• First-order structures (= predicate tables)
– hold recorded information
– model-theoretic approach, not proof-theoretic
• Formulae
– means for observing information
• Predicate-update formulae
– operational semantics
– update recorded information
Recorded Information (for reverse)
Predicate Intended Meaning
x(v)
y(v)
t(v)
n(v1,v2)
Does pointer variable x
point to cell v?
Does pointer variable y
point to cell v?
Does pointer variable t
point to cell v?
Does the n field of v1
point to v2?
Recorded Information (for reverse)
x
y
u1
u2
u3
u4
x(u)
1
0
0
0
u1
u2
y(u) t(u)
1
0
0
0
0
0
0
0
u3
n
u1
u2
u3
u4
u4
u1
0
0
0
0
u2
1
0
0
0
u3
0
1
0
0
u4
0
0
1
0
Formulae for Observing Properties
• Are x and y pointer aliases?
v: x(v)  y(v)
• Does x point to a cell with a self cycle?
v : x(v)  n(v,v)
• Is cell v heap-shared?
v1,v2 : n(v1,v)  n(v2,v)  v1  v2
Are x and y Pointer Aliases? Yes
v: x(v)  y(v) = 1
x
y
u1
u2
u3
u4
x(u)
1
0
0
0
u1
u2
y(u) t(u)
1
0
0
0
0
0
0
0
u3
n
u1
u2
u3
u4
u4
u1
0
0
0
0
u2
1
0
0
0
u3
0
1
0
0
u4
0
0
1
0
Predicate-Update Formulae for ‘y = NULL’
•
•
•
•
x’(v) = x(v)
y’(v) = 0
t’(v) = t(v)
n’(v1,v2) = n(v1,v2)
Predicate-Update Formulae for ‘y = NULL’
y’(v) = 0
x
y
u1
u2
u3
u4
x(u)
1
0
0
0
u1
u2
y(u) t(u)
10
0
0
0
0
0
0
0
u3
n
u1
u2
u3
u4
u4
u1
0
0
0
0
u2
1
0
0
0
u3
0
1
0
0
u4
0
0
1
0
Predicate-Update Formulae for ‘y = x’
•
•
•
•
x’(v) = x(v)
y’(v) = x(v)
t’(v) = t(v)
n’(v1,v2) = n(v1,v2)
Predicate-Update Formulae for ‘y = x’
y’(v) = x(v)
x
y
u1
u2
u3
u4
x(u)
1
0
0
0
u1
u2
y(u) t(u)
10
0
0
0
0
0
0
0
u3
n
u1
u2
u3
u4
u4
u1
0
0
0
0
u2
1
0
0
0
u3
0
1
0
0
u4
0
0
1
0
Predicate-Update Formulae for ‘x = x  n’
•
•
•
•
x’(v) = v1: x(v1)  n(v1,v)
y’(v) = y(v)
t’(v) = t(v)
n’(v1, v2) = n(v1, v2)
Predicate-Update Formulae for ‘x = x  n’
x’(v) = v1: x(v1)  n(v1,v)
x
y
u1
u2
u3
u4
x(u)
01
10
0
0
u1
u2
y(u) t(u)
1
0
0
0
0
0
0
0
u3
n
u1
u2
u3
u4
u4
u1
0
0
0
0
u2
1
0
0
0
u3
0
1
0
0
u4
0
0
1
0
Predicate-Update Formulae for ‘y  n = t’
•
•
•
•
x’(v) = x(v)
y’(v) = y(v)
t’(v) = t(v)
n’(v1,v2) = y(v1)  n(v1,v2)  y(v1)  t(v2)
Outline
•
•
•
•
Logic and box/arrow diagrams
Kleene’s 3-valued logic
The abstraction principle
Using 3-valued structures to represent sets
of stores
• Conservative extraction of store properties
• Abstract interpretation
• More precise abstract interpretation
Two- vs. Three-Valued Logic
Two-valued logic
0
1
Three-valued logic
{0,1}
{0}
{1}
{0}  {0,1}
{1}  {0,1}
Two- vs. Three-Valued Logic
Two-valued logic
Three-valued logic
1 0
1 1 0
0 0 0

{1}
{0,1}
{0}
1 0
1 1 1
0 1 0

{1}
{0,1}
{0}
{1} {0,1} {0}
{1} {0,1} {0}
{0,1} {0,1} {0}
{0} {0} {0}
{1}
{1}
{1}
{1}
{0,1}
{1}
{0,1}
{0,1}
{0}
{1}
{0,1}
{0}
Two- vs. Three-Valued Logic
Two-valued logic
0
1
Three-valued logic
{0,1}
{0}
{1}
Two- vs. Three-Valued Logic
Two-valued logic
0
Three-valued logic
1
½
0
1
0 3½
1 3½
Boolean Connectives [Kleene]

0
1/2
1
0
0
0
0
1/2
0
1/2
1/2
1
0
1/2
1

0
1/2
1
0
0
1/2
1
1/2
1/2
1/2
1
1
1
1
1
Three-Valued Logic
• 1: True
• 0: False
• 1/2: Unknown
• A join semi-lattice: 0  1 = 1/2
1/2
Information
order
0
1
Outline
•
•
•
•
Logic and box/arrow diagrams
Kleene’s 3-valued logic
The abstraction principle
Using 3-valued structures to represent sets
of stores
• Conservative extraction of store properties
• Abstract interpretation
• More precise abstract interpretation
Why is Shape Analysis Difficult?
• Destructive updating through pointers
– pnext = q
– Produces complicated aliasing relationships
• Dynamic storage allocation
– No bound on the size of run-time data structures
• Data-structure invariants typically only hold
at the beginning and end of operations
– Need to verify that data-structure invariants are
re-established
The Abstraction Principle
x
x
u2
u1
u1
u2
u3
u4
n
u1
u2
u3
u4
u1
0
0
0
0
u3
u4
x(u) y(u)
1
0
0
0
0
0
0
0
u2
1
0
0
0
u3
0
1
0
0
u4
0
0
1
0
u1
u1
u234
0
1
00
0
u234
x(u) y(u)
1 0
0 0
n u1 u234
u1 0 1
u234 0 1/2
What Stores
Does a 3-Valued Structure Represent?
• Example 3-valued structure
– individuals: {u1}
– predicates:
u1
n u1
u1 0
x y t
1 0 0
• graphical presentation
x
u1
• concrete stores represented
x
81
x
31
x
37
What Stores
Does a 3-Valued Structure Represent?
• Example 3-valued structure
u1
u
n u1 u
u1 0 1/2
u 0 1/2
x y t
1 0 0
0 0 0
• graphical presentation
x
u1
u
• concrete stores
x
1
31
71
91
What Stores
Does a 3-Valued Structure Represent?
• Example 3-valued structure
u1
u
n u1 u
u1 0 1/2
u 0 1/2
x y t
1 0 0
0 0 0
• graphical presentation
x
u1
u
• concrete stores
x
1
31
71
91
Property-Extraction Principle
• Questions about store properties can be
answered conservatively by evaluating
formulae in three-valued logic
• Formula evaluates to 1
 formula always holds in every store

• Formula evaluates to 0
 formula never holds in any store

• Formula evaluates to 1/2
 don’t know

Are x and y Pointer Aliases? Yes
x
y
u1
u
v: x(v)  y(v)
1  1
1
Is Cell u Heap-Shared? Maybe
x
y
u
u1
v1,v2: n(v1,u)  n(v2,u)  v1  v2
1/2

1/2
1/2

1
Outline
•
•
•
•
Logic and box/arrow diagrams
Kleene’s 3-valued logic
The abstraction principle
Using 3-valued structures to represent sets
of stores
• Conservative extraction of store properties
• Abstract interpretation
• More precise abstract interpretation
Abstract Interpretation
f (a,b) = (16 * b + 3) * (2 * a + 1)
*
+
*
16
+ 0
0 0
1 1
2 2
3 3

1
1
2
3
4
2
2
3
4
5
+
3
b
3 ...
3 ...
4 ...
5 ...
6 ...

*
2
1
a
* 0
0 0
1 0
2 0
3 0

1
0
1
2
3
2
0
2
4
6
3 ...
0 ...
3 ...
6 ...
9 ...

Abstract Interpretation
f (a,b) = (16 * b + 3) * (2 * a + 1)
O
O
+
E
*
?
+’
?
O
E
?
?
?
?
O
?
E
O
E
?
O
E
b
O
O E
3
E
16
*
+
O
*
1
E
?
2
a
*’
?
O
E
f:__O
?
?
?
E
O
?
O
E
E
E
E
E
Shape Analysis via
Abstract Interpretation
• Iteratively compute a set of 3-valued
structures for every program point
• Every statement transforms structures
according to the predicate-update formulae
– use 3-valued logic instead of 2-valued logic
– use exactly the predicate-update formulae
of the concrete semantics!!
Predicate-Update Formulae for “y = x”
y’(v) = x(v)
Old:
New:
x
x
y
u1
u
x(u) y(u) t(u)
u1 1
0
10
u 0
0
0
u1
u
n u1 u
u1 0 1/2
u 0 1/2
Predicate-Update Formulae for “x = x  n”
x’(v) =  v1: x(v1)  n(v1,v)
New:
Old:
x
y
u1
u
x(u) y(u) t(u)
u1 0
1
1
0
u 1
0
0
0
y
u1
x
u
n u1 u
u1 0 1/2
u 0 1/2
Abstract Interpretation


T
T#

Abstract
Concrete
Sets of stores

Descriptors of
sets of stores
Abstract Interpretation


T
T#

Abstract
Concrete
Ordinarily: Must define both T and T#
Abstract Interpretation


T
T#

Abstract
Concrete
Ordinarily: Complicated proof of correctness!
Abstract Interpretation


T
T#

Abstract
Concrete
Our approach: Same formula for T and T#
Abstract Interpretation


T
T#

Abstract
Concrete
Our approach: No proof! We did it for you!
The Embedding Theorem
x
No
y
v: x(v)  y(v)
No
No
Maybe
u1
y
u1
y
u3,4
u2
x
u1
x
u4
u3
u2
x
u2,3,4
y
u1,2,3,4
How Are We Doing?
• Conservative

• Convenient

• But not very precise 
– Advancing a pointer down a list loses
precision
– Cannot distinguish an acyclic list from a
cyclic list
Cyclic versus Acyclic Lists
x
1
31
71
x
u1
u
91
Outline
•
•
•
•
Logic and box/arrow diagrams
Kleene’s 3-valued logic
The abstraction principle
Using 3-valued structures to represent sets
of stores
• Conservative extraction of store properties
• Abstract interpretation
• More precise abstract interpretation
The Instrumentation Principle
• Increase precision by storing the truthvalue of some chosen formulae
• Introduce predicate-update formulae to
update the extra predicates
Example: Heap Sharing
is(v) = v1,v2: n(v1,v)  n(v2,v)  v1  v2
x
1
31
71
91
is = 0
is = 0
is = 0
is = 0
x
u1
is = 0
u
is = 0
Example: Heap Sharing
is(v) = v1,v2: n(v1,v)  n(v2,v)  v1  v2
x
1
31
71
91
is = 0
is = 10
is = 0
is = 0
x
u1
u
is = 0
is = 1
is = 0
Is Cell u Heap-Shared?
is = 0
x
y
No!
is = 0
u
u1
v1,v2: n(v1,u)  n(v2,u)  v1  v2
1/2

1/2
1/2

1
Maybe
Predicate-Update Formulae for ‘y = NULL’
•
•
•
•
•
x’(v) = x(v)
y’(v) = 0
t’(v) = t(v)
n’(v1,v2) = n(v1,v2)
is’(v) = is(v)
Predicate-Update Formulae for ‘y = x’
•
•
•
•
•
x’(v) = x(v)
y’(v) = x(v)
t’(v) = t(v)
n’(v1,v2) = n(v1,v2)
is’(v) = is(v)
Predicate-Update Formulae for ‘x = x  n’
•
•
•
•
•
x’(v) = v1: x(v1)  n(v1,v)
y’(v) = y(v)
t’(v) = t(v)
n’(v1,v2) = n(v1, v2)
is’(v) = is(v)
Predicate-Update Formulae for ‘y  n = t’
•
•
•
•
•
x’(v) = x(v)
y’(v) = y(v)
t’(v) = t(v)
n’(v1,v2) = y(v1)  n(v1,v2)  y(v1)  t(v2)
is’(v) = v1,v2: (is(v)  n’(v1,v)  n’(v2,v)  v1  v2)
 (t(v)  n(v1,v)  y(v1))
Materialization
Formal:
x
y
x
x = xn
y
Informal:
x
y
x
x = xn
y
Formal:
x
y
x
x = xn
y
The Focusing Principle
• “Bring the structure into better focus”
– Selectively force 1/2 to 0 or 1
– Avoid indefiniteness
• Then apply the predicate-update formulae
(1) Focus on v1: x(v1)  n(v1,v)
x
y
u1
u











x
y
x
y
x
y
u1
u
u1
u
u1
u.1
u.0
(2) Evaluate Predicate-Update Formulae
x’ (v) = v1: x(v1)  n(v1,v)
x
y
u1
y
u
u1
u
x
x
y
u1
y
u
u
u1
x
x
y
u1
u.1
u.0
y
u1
u.1
u.0
(3) Apply Constraint Solver
y
y
u
u1
x
y
u1
x
y
u
u1
u
u1
x
y
u
u1
x
u.1
y
u.0
u1
u.1
u.0
(3) Apply Constraint Solver
x
y
u1
u.1
u.0
n(v1, v )  n(v2, v)  v1  v2 
is(v)
is(v)n(v1,
n(v1,v)
v)v1
v1
v2
v2
n(v2,
n(v2,v)
is(v)
v)
1

1

1

0
(3) Apply Constraint Solver
x
y
u1
u.1
u.0
(3) Apply Constraint Solver
x
y
u1
u.1
u.0
n(v1, v )  n(v2, v)  v1  v2 
is(v)
is(v)  n(v1, v)  v1  v2  n(v2,
v)
1

1

1

0
(3) Apply Constraint Solver
x
y
u1
u.1
u.0
x(v1)  x(v2)  v1 = v2
1

1

1
(3) Apply Constraint Solver
x
y
u1
u.1
u.0
Formalizing “. . .”
Informal:
x
y
Formal:
x
y
Summary
node
Formalizing “. . .”
Informal:
t1
x
y
Formal:
t2
x
t1
y
t2
Formalizing “. . .”
Informal:
x
y
Formal:
reachable from
variable x
reachable from
variable y
x
r[x]
r[x]
r[y]
r[y]
y
Formalizing “. . .”
Informal:
t1
x
y
t2
Formal:
t1
x
r[x]
r[x]
r[y]
r[y]
r[x],r[t1]
r[x],r[t1]
r[y],r[t2]
r[y],r[t2]
y
t2
A ‘Yacc’ for Shape Analysis
%%pointer-field predicates
n(v1,v2)
%%instrumentation-predicate definitions
is(v) = v1,v2: n(v1,v)  n(v2,v)  v1  v2
%%predicate-update formulae
stmt : $x = NULL
{ is’(v) = is(v); }
| $x = $t
{ is’(v) = is(v); }
| $x = $t  n
{ is’(v) = is(v); }
| $x  n = $t
{ is’(v) =
v1,v2: (is(v)  n’(v1,v)  n’(v2,v)  v1  v2)
 (t(v)  n(v1,v)  y(v1));
}
| $x = malloc(INT) { is’(v) = is(v)  NEW(v);}
;
Why is Shape Analysis Difficult?
• Destructive updating through pointers
– pnext = q
– Produces complicated aliasing relationships
– Track aliasing on 3-valued structures
• Dynamic storage allocation
– No bound on the size of run-time data structures
– Abstraction principle  finite-sized 3-valued structures
• Data-structure invariants typically only hold at the
beginning and end of operations
– Need to verify that data-structure invariants are reestablished
– Evaluate formulas over 3-valued structures
Example: In-Situ List Reversal
typedef struct list_cell {
int val;
struct list_cell *next;
} *List;
Run Demo
List reverse (List x) {
List y, t;
y = NULL;
while (x != NULL) {
t = y;
y = x;
x = x  next;
y  next = t;
}
return y;
}
Example: Mark and Sweep
void Mark(Node root) {
if (root != NULL) {
pending = 
pending = pending  {root}
marked = 
while (pending  ) {
x = SelectAndRemove(pending)
marked = marked  {x}
t = x  left
if (t  NULL)
if (t  marked)
pending = pending  {t}
t = x  right
if (t  NULL)
if (t  marked)
pending = pending  {t}
}
}
assert(marked = = Reachset(root))
}
void Sweep() {
unexplored = Universe
collected = 
while (unexplored  ) {
x = SelectAndRemove(unexplored)
if (x  marked)
collected = collected  {x}
}
assert(collected = =
Universe – Reachset(root)
)
}
Run Demo
TVLA vs. Model Checking
TVLA
• Determine properties of a
transition system
• State-space exploration
• State labels: 1st-order
structures
• 3-valued structures
represent commonalities
• Properties checked:
Formulas in FO+TC
Model checking
• Determine properties of a
transition system
• State-space exploration
• State labels: Propositions
• BDDs represent
commonalities
• Properties checked:
Formulas in temporal logic
Summary
• 1/2 arises from abstraction
– One-sided analyses (e.g., 1 means “true”, 0
means “don’t know”) conflate 0 and 1/2
– 1/2 essential; conflation not essential
• For program analysis, 3-valued logic allows:
– Materialization
– Conservative extraction of properties