
Interprocedural Shape Analysis in Program Analysis and Verification
Explore interprocedural shape analysis in the context of program analysis and verification, delving into topics such as canonical abstraction, information loss, instrumentation predicates, and abstract semantics. Learn about techniques used for conservatively observing properties and best transformers in analyzing program structures.
Download Presentation

Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.
E N D
Presentation Transcript
Program Analysis and Verification 0368-4479 Noam Rinetzky Lecture 11: Interprocedural Shape Analysis Slides credit: Roman Manevich, Mooly Sagiv, Eran Yahav 1
Canonical Abstraction n n u1 u1 u2 u2 u3 u3 Top 2 [Sagiv, Reps, Wilhelm, TOPLAS02]
Canonical Abstraction n n u1 u1 u2 u2 u3 u3 Top Top 3
Canonical Abstraction ( ) Merge all nodes with the same unary predicate values into a single summary node Join predicate values (u 1 ,..., u k) = { (u1 ,..., uk) | f(u1)=u 1 ,..., f(uk)=u k} Converts a state of arbitrary size into a 3-valued abstract state of bounded size (C) = { (c) | c C } 4
Information Loss Canonical abstraction n n Top Top n n n Top Top n n Top Top 5
Instrumentation Predicates Record additional derived information via predicates rx(v) = v1: x(v1) n*(v1,v) c(v) = v1: n(v1, v) n*(v, v1) Canonical abstraction n n Top Top n n n Top c c c Top 6
Embedding Theorem: Conservatively Observing Properties rTop rTop Top No Cycles No cycles (derived) v: c(v) v1,v2: n(v1, v2) n*(v2, v1)1/2 1 7
Operational Semantics void push(int v){ Node x = malloc(sizeof(Node)); x->d = v; x->n = Top; Top = x; } n n u1 u2 u3 Top int pop(){ if (Top == NULL) return EMPTY; s = Top->n Node *s = Top->n; s (v) = v1: Top(v1) n(v1,v) int r = Top->d; Top = s; return r; n n u1 u2 u3 Top } s 8
Abstract Semantics s = Top n? s (v) = v1: Top(v1) n(v1,v) s rTop rTop rTop rTop Top Top s = Top->n 9
Best Transformer (s = Topn) s Concrete Semantics rTop rTop Top rTop rTop Top s Top rTop rTop rTop s (v) = v1: Top(v1) n(v1,v) ... rTop rTop rTop Top ... Canonical Abstraction ? s rTop rTop Top Abstract Semantics s rTop rTop Top rTop rTop rTop Top 10
Semantic Reduction Improve the precision of the analysis by recovering properties of the program semantics A Galois connection (C, , , A) An operation op:A A is a semantic reduction when l L2 op(l) l and (op(l)) = (l) l op C A
The Focus Operation Focus: Formula ( (3-Struct) Generalizes materialization For every formula Focus( )(X) yields structure in which evaluates to a definite values in all assignments Only maximal in terms of embedding Focus( ) is a semantic reduction But Focus( )(X) may be undefined for some X (3-Struct))
Partial Concretization Based on Transformer (s=Topn) s Abstract Semantics rTop rTop Top rTop rTop Top s rTop rTop rTop Top s (v) = v1: Top(v1) n(v1,v) rTop rTop rTop Top Canonical Abstraction Focus (Top n) Partial u: top(u) n(u, v) Concretization s rTop rTop Top Abstract Semantics s rTop rTop Top rTop rTop rTop Top 13
Partial Concretization Locally refine the abstract domain per statement Soundness is immediate Employed in other shape analysis algorithms [Distefano et.al., TACAS 06, Evan et.al., SAS 07, POPL 08] 14
The Coercion Principle Another Semantic Reduction Can be applied after Focus or after Update or both Increase precision by exploiting some structural properties possessed by all stores (Global invariants) Structural properties captured by constraints Apply a constraint solver
Apply Constraint Solver rTop rTop Top x x rTop rTop rTop rTop Top Top n n n n n n n rx rx,ry rx rx,ry x x rx,ry rx,ry n y y
Sources of Constraints Properties of the operational semantics Domain specific knowledge Instrumentation predicates User supplied
Example Constraints x(v1) x(v2) eq(v1, v2) n(v, v1) n(v,v2) eq(v1, v2) n(v1, v) n(v2,v) eq(v1, v2) is(v) n*(v1, v2) t[n](v1, v2)
Abstract Transformers: Summary Kleene evaluation yields sound solution Focus is a statement-specific partial concretization Coerce applies global constraints
A Semantics for Procedure Local Heaps and its Abstractions Noam Rinetzky Tel Aviv University J rg Bauer Universit t des Saarlandes Thomas Reps University of Wisconsin Mooly Sagiv Tel Aviv University Reinhard Wilhelm Universit t des Saarlandes
Motivation Interprocedural shape analysis Conservative static pointer analysis Heap intensive programs Imperative programs with procedures Recursive data structures Challenge Destructive update Localized effect of procedures
Main idea Local heaps x x x x call p(x); y y g g t t
Main idea Local heaps Cutpoints x x x x call p(x); y y g g t t
Main Results Concrete operational semantics Large step Functional analysis Storeless Shape abstractions Local heap Observationally equivalent to standard semantics Java and clean C Abstractions Shape analysis [Sagiv, Reps, Wilhelm, TOPLAS 02] May-alias [Deutsch, PLDI 94]
Outline Motivating example Local heaps Cutpoints Why semantics Local heap storeless semantics Shape abstraction
Example static List reverse(List t) { static void main() { n n t n n p n n n n q q List x = reverse(p); n n n p x n n t t r r n n n n List y = reverse(q); List z = reverse(x); return r; } }
Example static List reverse(List t) { static void main() { List x = reverse(p); n t n n n n n n n p p x x n n n t n n n q List y = reverse(q); n n n n n q y t t r r n n n n List z = reverse(x); return r; } }
Example n t n n static List reverse(List t) { static void main() { List x = reverse(p); n t n List y = reverse(q); n n n t n n n n n n p p x x n n n n n n q q y y List z = reverse(x); p n n n x z n n t t r r n n n n return r; } }
Cutpoints Separating objects Not pointed-to by a parameter
Cutpoints Separating objects Not pointed-to by a parameter proc(x) n n n n n n p x Stack sharing
Cutpoints Separating objects Not pointed-to by a parameter proc(x) proc(x) n n n n n n n n n n x n n p x n n y Stack sharing Heap sharing
Cutpoints Separating objects Not pointed-to by a parameter Capture external sharing patterns proc(x) proc(x) n n n n n n n n n n x n n p x n n y Stack sharing Heap sharing
Example static List reverse(List t) { static void main() { List x = reverse(p); List y = reverse(q); n n n t n n n n n n p p x x n n n n n n q q y y List z = reverse(x); p n n n z x n n r r t t n n n n return r; } }
Outline Motivating example Why semantics Local heap storeless semantics Shape abstraction
Abstract Interpretation [Cousot and Cousot, POPL 77] Operational semantics Abstract transformer
Introducing local heap semantics Operational semantics ~ Local heap Operational semantics Abstract transformer
Outline Motivating example Why semantics Local heap storeless semantics Shape abstraction
Programming model Single threaded Procedures Value parameters Recursion Heap Recursive data structures Destructive update No explicit addressing (&) No pointer arithmetic
Simplifying assumptions No primitive values (only references) No globals Formals not modified
Storeless semantics No addresses Memory state: Object: 2Access paths Heap: 2Object Alias analysis n n x x.n.n x x.n y=x x n n x.n.n y.n.n x y x.n y.n y x=null n n y y.n.n y y.n
Example static void main() { static List reverse(List t) { List x = reverse(p); t n n n List y = reverse(q); t.n.n.n t.n.n t.n t n n t n n n n x.n.n.n t.n.n.n p x x.n.n t.n.n x.n t.n x t p n n n n y.n.n y.n.n q q y y y.n y.n y y q q List z = reverse(x); n n n x x z z.n z.n.n z z.n.n.n t t n n n n n n t t r r r.n r.n r.n.n r.n.n r.n.n.n r.n.n.n r r p? return r; } }
Example static void main() { static List reverse(List t) { List x = reverse(p); t L n n n List y = reverse(q); t.n.n.n t.n.n t.n t t L L n n n n n n x.n.n.n t.n.n.n p x x.n.n t.n.n x.n t.n x t p L n n n n y.n.n y.n.n q q y y y.n y.n y y q q List z = reverse(x); n n n p p.n.n.n x p.n.n.n z.n.n.n p z p.n z.n p.n.n z.n.n p p.n.n p.n x z L L t t n n n n n n t L.n.n.n r.n.n.n r.n.n.n t L.n.n.n L r r L L.n r.n r.n L.n L.n.n r.n.n r.n.n L.n.n r r return r; } }
Cutpoint labels Relate pre-state with post-state Additional roots Mark cutpoints at and throughout an invocation
Cutpoint labels Cutpoint label: the set of access paths that point to a cutpoint when the invoked procedure starts t L t.n.n.n t.n.n t.n t L L {t.n.n.n}
Sharing patterns Cutpoint labels encode sharing patterns n n n n n n t.n.n.n t.n.n.n L L t t t.n.n t.n t t.n.n t.n t L L n n w w.n w p Stack sharing Heap sharing L {t.n.n.n}
Observational equivalence L L (Local-heap Storeless Semantics) G G (Global-heap Store-based Semantics) Land Gobservationally equivalent when for every access paths AP1, AP2 AP1= AP2( L) AP1= AP2( G)
Main theorem: semantic equivalence L L (Local-heap Storeless Semantics) G G (Global-heap Store-based Semantics) Land Gobservationally equivalent st, L L and G are observationally equivalent L st, G G LSL GSB
Corollaries Preservation of invariants Assertions: AP1= AP2 Detection of memory leaks