Download presentation
Presentation is loading. Please wait.
1
Spring 2016 Program Analysis and Verification
Lecture 15: Shape Analysis I Roman Manevich Ben-Gurion University
2
Tentative syllabus Program Verification Program Analysis Basics
Operational semantics Hoare Logic Applying Hoare Logic Weakest Precondition Calculus Proving Termination Data structures Automated Verification Program Analysis Basics From Hoare Logic to Static Analysis Control Flow Graphs Equation Systems Collecting Semantics Using Soot Abstract Interpretation fundamentals Lattices Fixed-Points Chaotic Iteration Galois Connections Domain constructors Widening/ Narrowing Analysis Techniques Numerical Domains Pointer analysis Shape Analysis Interprocedural Analysis
3
Previously Points-to analysis and alias analysis
4
Agenda Going beyond pointer analysis Shape analysis
Property-based summarization Materialization Specialized analysis for singly-linked lists (3-valued Shape Analysis Framework / TVLA)
5
Limitations of pointer analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } // Singly-linked list // data type. class SLL { int data; public SLL n; // next cell SLL(Object data) { this.data = data; this.n = null; } }
6
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; }
7
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null t
8
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null t n L1
9
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null t n L1 tmp
10
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null t n L1 n tmp L2
11
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null t n L1 n n tmp L2
12
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null t n L1 n n tmp L2
13
Flow&Field-sensitive Analysis
h // Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } null t n L1 n n tmp != null tmp L2 h null t n L1 tmp == null tmp
14
Flow&Field-sensitive Analysis
h // Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } null t n L1 n n tmp L2 h null t n L1 tmp
15
Flow&Field-sensitive Analysis
h // Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } null t n L1 n n tmp L2 tmp == null ?
16
Flow&Field-sensitive Analysis
h // Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } null t n L1 n n tmp L2
17
Flow&Field-sensitive Analysis
h // Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } null t n L1 n n tmp L2 Possible null dereference!
18
Flow&Field-sensitive Analysis
h // Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } null t n L1 n n tmp L2 Fixed-point for first loop
19
Flow&Field-sensitive Analysis
h // Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } null t n L1 n n tmp L2
20
Flow&Field-sensitive Analysis
h // Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } null t n L1 n n tmp L2 Possible null dereference!
21
What was the problem? Pointer analysis abstract all objects allocated at same program location into one summary object. However, objects allocated at same memory location may behave very differently E.g., object is first/last one in the list Assign extra predicates to distinguish between objects with different roles Number of objects represented by summary object 1 – does not allow strong updates Distinguish between concrete objects (#=1) and abstract objects (#1) Join operator very coarse – abstracts away important distinctions (tmp=null/tmp!=null) Apply disjunctive completion
22
Improved solution Pointer analysis abstract all objects allocated at same program location into one summary object. However, objects allocated at same memory location may behave very differently E.g., object is first/last one in the list Add extra instrumentation predicates to distinguish between objects with different roles Number of objects represented by summary object 1 – does not allow strong updates Distinguish between concrete objects (#=1) and abstract objects (#1) Join operator very coarse – abstracts away important distinctions (tmp=null/tmp!=null) Apply disjunctive completion
23
Adding properties to objects
Let’s first drop allocation site information and instead… Define a unary predicate x(v) for each pointer variable x meaning x points to x Predicate holds for at most one node Merge together nodes with same sets of predicates
24
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null t
25
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null t n {h, t}
26
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null t n {h, t} tmp
27
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null t n {h, t} tmp n {tmp} No null dereference
28
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null t n {h, t} tmp n {tmp}
29
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null t n {t} tmp n {h, tmp}
30
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp {h, tmp} h null t n {h, t} tmp
31
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp {h, tmp} h null t n {h, t} tmp Do we need to analyze this shape graph again?
32
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp {h, tmp} h null t n {h, t} tmp
33
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { h} n { tmp} No null dereference
34
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { h} n { tmp}
35
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { } n { h, tmp}
36
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { } n { h, tmp}
37
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { } n { h} n { tmp} No null dereference
38
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { } n { h} n { tmp}
39
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { } n { } n {h, tmp}
40
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { } n n {h, tmp} How many objects does it represent? Summarization
41
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { } n n {h} n { tmp} No null dereference
42
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { } n n {h} n { tmp}
43
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { } n n {h, tmp} Fixed-point for first loop
44
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { } n n {h, tmp}
45
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { } n n {h, tmp}
46
Flow&Field-sensitive Analysis
// Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n tmp { tmp?} n n { tmp}
47
Improving precision via partial concretization
48
Best (induced) transformer
f#(a)= (f((a))) C A 4 f f# 3 1 2 Problem: incomputable directly
49
Best transformer for tmp=tmp.n
null h t {t} tmp n { } {h, tmp} null h n {t} t n { } tmp n n {h, tmp} null h t {t} tmp n { } {h, tmp}
50
Best transformer for tmp=tmp.n:
null h t {t} tmp n { } {h, tmp} null h n {t} t n { } tmp n n {h, tmp} null h t {t} tmp n { } {h, tmp} h null n t {t} n { } { } … { } n tmp {h, tmp}
51
Best transformer for tmp=tmp.n
h null null n h t {t} n {t} n t {tmp } n n { } tmp {h} tmp n n {h, tmp} h h null null n n t {t} t {t} n { } n { } { } { } … tmp {tmp } {tmp } tmp n n {h} {h}
52
Best transformer for tmp=tmp.n:
h null null n h t {t} n {t} n t {tmp } n n { } tmp {h} tmp n n {h, tmp} h h null null n n t {t} t {t} n n { } { } … tmp {tmp } {tmp } tmp n n {h} {h}
53
Handling updates on summary nodes
Transformers accessing only concrete nodes are easy Transformers accessing summary nodes are complicated Can’t concretize summary nodes – represents potentially unbounded number of concrete nodes We need to split into cases by “materializing” concrete nodes from summary node Introduce a new temporary predicate tmp.n Partial concretization
54
Transformer for tmp=tmp.n: ’
null h n {t} ’ t n { } tmp n n {h, tmp} Case 1: Exactly 1 object. Case 2: >1 objects.
55
Transformer for tmp=tmp.n: ’
null h t {t} tmp n {tmp.n } {h, tmp} null h n {t} ’ t n { } tmp n n {h, tmp} Summary node h null n t {t} spaghetti n { } tmp.n is a concrete node {tmp.n } n tmp {h, tmp}
56
Transformer tmp=tmp.n
null h t {t} tmp n {t, tmp.n } {h} null h n {t} t n { } tmp n n {h, tmp} h null n t {t} n { } tmp {t, tmp.n } n {h}
57
Transformer for tmp=tmp.n:
null h t {t} tmp n {h} // Build a list SLL h=null, t = null; L1: h=t= new SLL(-1); SLL tmp = null; while (…) { int data = getData(…); L2: tmp = new SLL(data); tmp.n = h; h = tmp; } // Process elements tmp = h; while (tmp != t) { assert tmp != null; tmp.data += 1; tmp = tmp.n; } h null n t {t} n { } tmp {t} n {h}
58
Transformer via partial-concretization
f#(a)= ’(f#’(’(a))) C A’ A ’ 6 4 f f#’ f# 3 5 1 2 ’
59
Recap Adding more properties to nodes refines abstraction
Can add temporary properties for partial concretization Materialize concrete nodes from summary nodes Allows turning weak updates into strong ones Focus operation in shape-analysis lingo Not-trivial in general and requires more semantic reduction to clean up impossible edges General algorithms available via 3-valued logic and implemented in TVLA system
60
Analyzing singly-linked lists
61
Specialized analysis for SLL
Very simple shape analysis Assumes SLL only data structure Data fields cannot point to SLL nodes No recursive procedures Simple algorithms, quick implementation Implemented in Abstract Interpretation package
62
What is it good for? Supports assertions Check cleanness properties
assertReach(x,y) assertDisjointLists(x,y) Enables parallelization assertAcyclicList(x) assertCyclicList(x) assert(x==y) assert(x!=y) Check cleanness properties Absence of NullPointerException’s Absence of memory leaks (in C) No misuse of dangling pointers (in C)
63
Concrete store class SLL { int data; SLL n; } n n n n n n n n n x n n
y We ignore the value field and consider only the n-links.
64
#interruptions ≤ 2 · #variables (bounded number of sharing patterns)
Interrupting nodes Interruption: node pointed-to by a variable or shared by n fields n n n n n n n n n x n n n n y #interruptions ≤ 2 · #variables (bounded number of sharing patterns)
65
List segments Maximal sub-list between two interruptions not containing interruptions in-between n n n n n n n n n x n n n n y
66
List segments segment 1 segment 2 n n n n n n n n n x n n n n y
67
Abstraction idea Add following instrumentation predicates to each node
x(v) – node v is pointed-to by variable x seg(v) – node v is properly contained in a list segment Merge nodes within the same end points of a segment
68
Instrumented store seg n n n n n n n n n x n n n n y seg seg
69
Abstract store seg n n n n n n x n n n y seg n seg
70
Store it represents seg n n n n n n n n n x n n n n y seg seg
71
Store it does not represent
seg n n n n n n n n n x n n n n y seg seg
72
Simplified representation
Make summary node implicit. Abstract length: how many links in segment {1, >1} >1 1 >1 x >1 y
73
Intuitive meaning of abstraction
Retains overall “shape” of the heap Which important points exist How they are connected via paths Precisely captures disjointness/sharing/cycles Abstracts away Lengths of simple paths Many times not relevant for proving correctness of list-manipulating programs But sometimes is Refinements with numerical abstractions of lengths is needed
74
Abstract transformers for singly-linked lists
75
Abstract transformers
Need transformers for program statements x = new List() x = null x = y x = y.n x.n = y assume x!=y assume x==y
76
Simplifying code transformations
Code transformations that preserve semantics and simplify implementing transformers by eliminating annoying corner cases Precede all assignment to x by x=null E.g., replace x=new List() with x=null; x=new List() Replace x=x.n with t=x.n; x=t Replace x.n=x with t=x; x.n=t Replace x.n=t with x.n=null; x.n=t
77
x = new List()# Recall assumption that x==null before statement (simplifying transformation) Allocate new node and have x point to it Just like concrete semantics t y 1 >1 x null x null >1 x = new List()# >1 n t >1 y
78
x = t# Recall assumption that x==null before statement (simplifying transformation) t points to a concrete node Have x point to that node Just like concrete semantics x null >1 x null >1 x = t# >1 1 >1 1 t t >1 >1 y y
79
x = null# Case 1: x points to an interruption that remains an interruption even without x pointing to it Just have x point to null x >1 x null >1 x = null# >1 1 >1 1 t t >1 >1 y y
80
x = null# Case 2: x points to an interruption that ceases to be an interruption Have x point to null x >1 t 1 >1 x null x = null# >1 1 t
81
x = null# Case 2: x points to an interruption that ceases to be an interruption Step 1: Have x point to null Step 2: Abstract non-maximal list segments x >1 t 1 >1 x null x = null# >1 1 t
82
x = null# Case 2: x points to an interruption that ceases to be an interruption Step 1: Have x point to null Step 2: Abstract non-maximal list segments x >1 x null >1 x = null# >1 1 >1 t t
83
x = y.n# Recall assumption that x==null before statement (simplifying transformation) Case 1: y.n is an interruption (edge with abstract length 1) Just have x point to the successor of y x null >1 x >1 x = y.n# >1 1 >1 1 t t 1 1 y y
84
x = y.n# Recall assumption that x==null before statement (simplifying transformation) Case 2: y.n is not an interruption (edge with abstract length >1) Apply partial concretization and then do case 1 x null >1 x = y.n# >1 1 t >1 y What lengths does it represent?
85
x = y.n# Recall assumption that x==null before statement (simplifying transformation) Case 2: y.n is not an interruption (edge with abstract length >1) Apply partial concretization and then do case 1 x null >1 x = y.n# >1 1 t >1 y >1 = 2 or >2
86
x = y.n# Recall assumption that x==null before statement (simplifying transformation) Case 2: y.n is not an interruption (edge with abstract length >1) Apply partial concretization and then do case 1 x >1 1 t null x 1 1 ’ y >1 1 t null >1 y x >1 1 t null 1 >1 y
87
x = y.n# Recall assumption that x==null before statement (simplifying transformation) Case 2: y.n is not an interruption (edge with abstract length >1) Apply partial concretization and then do case 1 x >1 1 t null x 1 1 x = y.n ’ y >1 1 t null >1 y x >1 1 t null 1 >1 y
88
x.n = null# Can be used to detect memory leaks
(Also x=null) Again two cases: x.n is a concrete node / x.n is a summary node
89
x.n = null# Can be used to detect memory leaks
Again two cases: x.n is a concrete node / x.n is a summary node Case 1: x.n is a concrete node Follow concrete semantics Need to merge non-maximal segment x.n = null# >1 1 t null >1 1 t null 1 x 1 x
90
x.n = null# Can be used to detect memory leaks
Again two cases: x.n is a concrete node / x.n is a summary node Case 1: x.n is a concrete node Follow concrete semantics x.n = null# >1 1 t null >1 t null 1 x 1 x
91
x.n = null# Can be used to detect memory leaks
Again two cases: x.n is a concrete node / x.n is a summary node Case 2: x.n is a summary node Apply partial concretization and do case 1 x.n = null# >1 1 t … null >1 x What can go wrong here in C?
92
x.n = y# Trivial after x.n=null y t x null 1 >1 y x.n = y#
93
assume x==y# assume x!=y#
How do we check these?
94
Checking assertions How do we check these? assertReach(x,y)
assertDisjointLists(x,y) assertAcyclicList(x) assertCyclicList(x)
95
see you next time
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.