Fissile Type Analysis: Modular Checking of Almost ... · Fissile Type Analysis: Modular Checking of...
Transcript of Fissile Type Analysis: Modular Checking of Almost ... · Fissile Type Analysis: Modular Checking of...
Fissile Type Analysis:Modular Checking of Almost
Everywhere Invariants
University of Colorado Boulder
Devin Coughlin Bor-Yuh Evan Chang
1
How to type check a program that is
almost well-typed?
2
Type system:dependent re!nement types
In this talk
Example property of interest:safety of re"ective method calls
3
Re"ective method call dispatches based on runtime string value
class Callbackvar sel : Strvar obj : Obj
def call()this.obj.[this.sel]()
4
Re"ective method call dispatches based on runtime string value
class Callbackvar sel : Strvar obj : Obj
def call()this.obj.[this.sel]()
Calls method with name (selector) stored in sel on
object stored in obj
4
Re"ective method call dispatches based on runtime string value
class Callbackvar sel : Strvar obj : Obj
def call()this.obj.[this.sel]()
Calls method with name (selector) stored in sel on
object stored in obj
If sel held string “notifyDidClick” would call notifyDidClick() on obj.
4
Re"ective method call dispatches based on runtime string value
class Callbackvar sel : Strvar obj : Obj
def call()this.obj.[this.sel]()
Calls method with name (selector) stored in sel on
object stored in obj
4
Run time error if obj does not respond to sel — i.e., method does not exist
class Callbackvar sel : Strvar obj : Obj
def call()this.obj.[this.sel]()
Ensure re!ection safety with dependent re!nement type expressing required relationship
5
class Callbackvar sel : Strvar obj : Obj
def call()this.obj.[this.sel]()
Ensure re!ection safety with dependent re!nement type expressing required relationship
| r2 sel
obj must “respond to” sel
5
class Callbackvar sel : Strvar obj : Obj
def call()this.obj.[this.sel]()
Ensure re!ection safety with dependent re!nement type expressing required relationship
| r2 sel
obj must “respond to” sel
Shorthand forobj :: {⌫ : Obj | ⌫ r2 sel}
5
class Callbackvar sel : Strvar obj : Obj
def call()this.obj.[this.sel]()
Ensure re!ection safety with dependent re!nement type expressing required relationship
| r2 sel
obj must “respond to” sel
Shorthand forobj :: {⌫ : Obj | ⌫ r2 sel}
5
Guarantees no MethodNotFound error in call()
class Iteratorvar idx : Int var buf : Obj[]
def get(): Objreturn this.buf[this.idx]
Similar relationship for array bounds safety
| indexedBy idx
6
class Iteratorvar idx : Int var buf : Obj[]
def get(): Objreturn this.buf[this.idx]
Similar relationship for array bounds safety
| indexedBy idx
idx must be a valid index into buf
6
class Iteratorvar idx : Int var buf : Obj[]
def get(): Objreturn this.buf[this.idx]
Similar relationship for array bounds safety
| indexedBy idx
idx must be a valid index into buf
Guarantees no “ArrayOutOfBounds” error
6
class Iteratorvar idx : Int var buf : Obj[]
def get(): Objreturn this.buf[this.idx]
Similar relationship for array bounds safety
| indexedBy idx
idx must be a valid index into buf
6
These kinds of relationships are important to many safety properties
class Callbackvar sel : Strvar obj : Obj | r2 sel
def update(s : Str, o : Obj | r2 s)this.sel = sthis.obj = o
def call()this.obj.[this.sel]()
Updating relationship causes type error
7
class Callbackvar sel : Strvar obj : Obj | r2 sel
def update(s : Str, o : Obj | r2 s)this.sel = sthis.obj = o
def call()this.obj.[this.sel]()
Field type says: obj must always respond to sel
Updating relationship causes type error
7
class Callbackvar sel : Strvar obj : Obj | r2 sel
def update(s : Str, o : Obj | r2 s)this.sel = sthis.obj = o
def call()this.obj.[this.sel]()
o guaranteed to respond to s
Field type says: obj must always respond to sel
Updating relationship causes type error
7
class Callbackvar sel : Strvar obj : Obj | r2 sel
def update(s : Str, o : Obj | r2 s)this.sel = sthis.obj = o
def call()this.obj.[this.sel]()
o guaranteed to respond to s
Type error: old obj may not respond to new sel
Field type says: obj must always respond to sel
Updating relationship causes type error
7
class Callbackvar sel : Strvar obj : Obj | r2 sel
def update(s : Str, o : Obj | r2 s)this.sel = sthis.obj = o
def call()this.obj.[this.sel]()
o guaranteed to respond to s
Type error: old obj may not respond to new sel
False alarm: no runtime error
Field type says: obj must always respond to sel
Updating relationship causes type error
7
| r2 s
class Callbackvar sel : Strvar obj : Obj
def update(s : Str, o : Obj )this.sel = sthis.obj = o
def call()this.obj.[this.sel]()
Two styles of reasoning to determine false alarm
| r2 sel
8
| r2 s
class Callbackvar sel : Strvar obj : Obj
def update(s : Str, o : Obj )this.sel = sthis.obj = o
def call()this.obj.[this.sel]()
Two styles of reasoning to determine false alarm
Reasoning by global invariant: call safe if relationship holds
| r2 sel
8
| r2 s
class Callbackvar sel : Strvar obj : Obj
def update(s : Str, o : Obj )this.sel = sthis.obj = o
def call()this.obj.[this.sel]()
Two styles of reasoning to determine false alarm
Reasoning by global invariant: call safe if relationship holds
| r2 sel
8
| r2 s
class Callbackvar sel : Strvar obj : Obj
def update(s : Str, o : Obj )this.sel = sthis.obj = o
def call()this.obj.[this.sel]()
Two styles of reasoning to determine false alarm
Reasoning by global invariant: call safe if relationship holds
| r2 selReasoning about effects of imperative updates
8
| r2 s
class Callbackvar sel : Strvar obj : Obj
def update(s : Str, o : Obj )this.sel = sthis.obj = o
def call()this.obj.[this.sel]()
Two styles of reasoning to determine false alarm
Reasoning by global invariant: call safe if relationship holds
Relationship violated
| r2 selReasoning about effects of imperative updates
8
| r2 s
class Callbackvar sel : Strvar obj : Obj
def update(s : Str, o : Obj )this.sel = sthis.obj = o
def call()this.obj.[this.sel]()
Two styles of reasoning to determine false alarm
Reasoning by global invariant: call safe if relationship holds
Relationship violated
Relationship restored
| r2 selReasoning about effects of imperative updates
8
Idea: Selectively alternate between reasoning styles in
veri"cation
10
Fissile Type Analysis combines two styles of reasoning
Automated reasoning about global invariants
10
Fissile Type Analysis combines two styles of reasoning
Automated reasoning about global invariants
10
Flow-Insensitive Type Systems
� ` · · ·
Fissile Type Analysis combines two styles of reasoning
Automated reasoning about global invariants
Automated reasoning about execution
10
Flow-Insensitive Type Systems
� ` · · ·
Fissile Type Analysis combines two styles of reasoning
Automated reasoning about global invariants
Automated reasoning about execution
10
Flow-Insensitive Type Systems
� ` · · ·
Abstract Interpretation/Flow Analysis
�(·) = · · ·
Fissile Type Analysis combines two styles of reasoning
Veri"cation of almost-everywhere invariants with intertwined type and !ow analysis
11
Veri"cation of almost-everywhere invariants with intertwined type and !ow analysis
types violated
type analysis
Switch to symbolic analysis when global
type invariant violated
11
Veri"cation of almost-everywhere invariants with intertwined type and !ow analysis
symbolic !ow analysis
types violated
type analysis
types restored
Switch to symbolic analysis when global
type invariant violated
11
Back to types when invariant restored
Veri"cation of almost-everywhere invariants with intertwined type and !ow analysis
symbolic !ow analysis
types violated
type analysis
types restoredtype analysis
types violated
Switch to symbolic analysis when global
type invariant violated
11
Back to types when invariant restored
Veri"cation of almost-everywhere invariants with intertwined type and !ow analysis
symbolic !ow analysis
types violated
type analysis
types restoredtype analysis
symbolic !ow analysis
types violated
types restored
Switch to symbolic analysis when global
type invariant violated
11
Back to types when invariant restored
Veri"cation of almost-everywhere invariants with intertwined type and !ow analysis
symbolic !ow analysis
types violated
type analysis
type analysis
types restoredtype analysis
symbolic !ow analysis
types violated
types restored
Switch to symbolic analysis when global
type invariant violated
11
Back to types when invariant restored
Veri"cation of almost-everywhere invariants with intertwined type and !ow analysis
symbolic !ow analysis
types violated
type analysis
type analysis
types restoredtype analysis
symbolic !ow analysis
types violated
types restored
Switch to symbolic analysis when global
type invariant violated
Not changing type analysis at all: just when applied
11
Back to types when invariant restored
Veri"cation of almost-everywhere invariants with intertwined type and !ow analysis
symbolic !ow analysis
types violated
type analysis
type analysis
types restoredtype analysis
symbolic !ow analysis
types violated
types restored
Effective when global type invariant holds
most of the time
11
Veri"cation of almost-everywhere invariants with intertwined type and !ow analysis
symbolic !ow analysis
types violated
type analysis
type analysis
types restoredtype analysis
symbolic !ow analysis
types violated
types restored
Effective when global type invariant holds
most of the time
11
• Relationship updates
Veri"cation of almost-everywhere invariants with intertwined type and !ow analysis
symbolic !ow analysis
types violated
type analysis
type analysis
types restoredtype analysis
symbolic !ow analysis
types violated
types restored
Effective when global type invariant holds
most of the time
11
• Relationship updates
• Occurrence typing
Veri"cation of almost-everywhere invariants with intertwined type and !ow analysis
symbolic !ow analysis
types violated
type analysis
type analysis
types restoredtype analysis
symbolic !ow analysis
types violated
types restored
Effective when global type invariant holds
most of the time
11
• Relationship updates
• Occurrence typing
• Tagged unions
Play to the strengths of each intertwined analysis
12
Play to the strengths of each intertwined analysis
Flow-Insensitive Types• Easy to specify global invariants• Fast• Natural for modular reasoning• Good error reporting
12
Play to the strengths of each intertwined analysis
Flow-Insensitive Types• Easy to specify global invariants• Fast• Natural for modular reasoning• Good error reporting
Symbolic Flow Analysis• Natural for local reasoning about
heap mutation • Precise• Can be disjunctive/path-sensitive
12
Play to the strengths of each intertwined analysis
Flow-Insensitive Types• Easy to specify global invariants• Fast• Natural for modular reasoning• Good error reporting
Symbolic Flow Analysis• Natural for local reasoning about
heap mutation • Precise• Can be disjunctive/path-sensitive
!ow-sensitive typing?ownership types?alias types?permissions?effects?
12
Play to the strengths of each intertwined analysis
Flow-Insensitive Types• Easy to specify global invariants• Fast• Natural for modular reasoning• Good error reporting
Symbolic Flow Analysis• Natural for local reasoning about
heap mutation • Precise• Can be disjunctive/path-sensitive
!ow-sensitive typing?ownership types?alias types?permissions?effects?
Goal: keep types as simple as
possible
12
Play to the strengths of each intertwined analysis
Flow-Insensitive Types• Easy to specify global invariants• Fast• Natural for modular reasoning• Good error reporting
Symbolic Flow Analysis• Natural for local reasoning about
heap mutation • Precise• Can be disjunctive/path-sensitive
!ow-sensitive typing?ownership types?alias types?permissions?effects?
Goal: keep types as simple as
possible
12
Complexity lies in handoff between analyses and in symbolic analysis
Key Contributions1 Translate type invariant into
symbolic state via “symbolization” of type environment
type analysis
symbolic !owanalysis
type analysis
2 Leverage heap type invariantduring symbolic analysis viatype-consistent materialization and summarization
13
Key Contributions1 Translate type invariant into
symbolic state via “symbolization” of type environment
type analysis
symbolic !owanalysis
type analysis
2 Leverage heap type invariantduring symbolic analysis viatype-consistent materialization and summarization
13
Reason precisely only when type invariant violated
Key Contributions1 Translate type invariant into
symbolic state via “symbolization” of type environment
type analysis
symbolic !owanalysis
type analysis
2 Leverage heap type invariantduring symbolic analysis viatype-consistent materialization and summarization
13
Reason precisely only when type invariant violated
Reason precisely only for locations where type invariant violated
Key Contributions1 Translate type invariant into
symbolic state via “symbolization” of type environment
type analysis
symbolic !owanalysis
type analysis
2 Leverage heap type invariantduring symbolic analysis viatype-consistent materialization and summarization
1
13
Reason precisely only when type invariant violated
Reason precisely only for locations where type invariant violated
Symbolization splits a type environment intofacts about values and storage for those values
Symbolization splits a type environment intofacts about values and storage for those values
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
Symbolization splits a type environment intofacts about values and storage for those values
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
✘
Symbolization splits a type environment intofacts about values and storage for those values
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
Type environment
� this : Callback
s : Stro : Obj | r2 s
Maps local variables to dependent types
Re"nements refer to
variables
Symbolization splits a type environment intofacts about values and storage for those values
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
Type environment
symbolize� this : Callback
s : Stro : Obj | r2 s
Symbolic state
this : eto : eos : es
eo : Obj | r2 eses : Str
et : Callbacke�eE
Maps local variables to dependent types
Re"nements refer to
variables
Symbolization splits a type environment intofacts about values and storage for those values
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
Type environment
symbolize� this : Callback
s : Stro : Obj | r2 s
Symbolic state
this : eto : eos : es
eo : Obj | r2 eses : Str
et : Callbacke�eE
Maps local variables to dependent types
Maps local variables to
symbolic values
Re"nements refer to
variables
Symbolization splits a type environment intofacts about values and storage for those values
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
Type environment
symbolize� this : Callback
s : Stro : Obj | r2 s
Symbolic state
this : eto : eos : es
eo : Obj | r2 eses : Str
et : Callbacke�eE
Maps local variables to dependent types
Maps local variables to
symbolic values
Maps symbolic values to dependent types lifted to symbolic
values (symbolic facts)
Re"nements refer to
variables
Symbolization splits a type environment intofacts about values and storage for those values
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
Type environment
symbolize� this : Callback
s : Stro : Obj | r2 s
Symbolic state
this : eto : eos : es
eo : Obj | r2 eses : Str
et : Callbacke�eE
Maps local variables to dependent types
Maps local variables to
symbolic values
Maps symbolic values to dependent types lifted to symbolic
values (symbolic facts)
Re"nements refer to values
Re"nements refer to
variables
Symbolization splits a type environment intofacts about values and storage for those values
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
� this : Callback
s : Stro : Obj | r2 s
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
15
Symbolization allows local variables to hold values inconsistent with declared types
heap
this
o
s
this.obj this.sel
� this : Callback
s : Stro : Obj | r2 s
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
15
Symbolization allows local variables to hold values inconsistent with declared types
A type environment constrains local
variables
heap
this
o
s
this.obj this.sel
� this : Callback
s : Stro : Obj | r2 s
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
15
Symbolization allows local variables to hold values inconsistent with declared types
A type environment constrains local
variables
heap
this
o
s
this.obj this.sel
But also constrains the reachable heap to be type-consistent: "elds must conform to
declared types
� this : Callback
s : Stro : Obj | r2 s
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
15
Symbolization allows local variables to hold values inconsistent with declared types
A type environment constrains local
variables
heap
this
o
s
this.obj this.sel
But also constrains the reachable heap to be type-consistent: "elds must conform to
declared types
This picture captures the fully type-consistent concrete state
� this : Callback
s : Stro : Obj | r2 s
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
15
Symbolization allows local variables to hold values inconsistent with declared types
symbolize eE e�heap
this.obj this.sel
s
o
this
� this : Callback
s : Stro : Obj | r2 s
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
15
Symbolization allows local variables to hold values inconsistent with declared types
symbolize eE e�heap
this.obj this.sel
s
o
this
Symbolic environment allows, e.g., int in
� this : Callback
s : Stro : Obj | r2 s
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
15
Symbolization allows local variables to hold values inconsistent with declared types
symbolize eE e�heap
this.obj this.sel
s
o
this
Symbolic environment allows, e.g., int in
Immediately type-inconsistent: value stored without dereferences violates a type constraint
� this : Callback
s : Stro : Obj | r2 s
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
15
Symbolization allows local variables to hold values inconsistent with declared types
symbolize eE e�
Symbolic environment allows, e.g., int in
s heapthis.obj this.selo
this
Immediately type-inconsistent: value stored without dereferences violates a type constraint
� this : Callback
s : Stro : Obj | r2 s
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
15
Symbolization allows local variables to hold values inconsistent with declared types
symbolize eE e�
Symbolic environment allows, e.g., int in
s heapthis.obj this.selo
this
Immediately type-inconsistent: value stored without dereferences violates a type constraint
Grey indicates storage that is not immediately type-inconsistent
�
Type environment
Symbolic fact map
symbolizethis : Callback
s : Stro : Obj | r2 s eo : Obj | r2 es
es : Str
et : Callbacke�
16
Symbolization unpacks local cells, but symbolic facts about values still constrain the heap
heapthis.obj this.sel
s
o
this
�
Type environment
Symbolic fact map
symbolizethis : Callback
s : Stro : Obj | r2 s eo : Obj | r2 es
es : Str
et : Callbacke�
Base types same on both sides
16
Symbolization unpacks local cells, but symbolic facts about values still constrain the heap
heapthis.obj this.sel
s
o
this
�
Type environment
Symbolic fact map
symbolizethis : Callback
s : Stro : Obj | r2 s eo : Obj | r2 es
es : Str
et : Callbacke�
Callback , {sel : Str, obj : Obj | r2 sel}
Base types same on both sides
16
Symbolization unpacks local cells, but symbolic facts about values still constrain the heap
heapthis.obj this.sel
s
o
this
Base type "eld re"nements still refer to
!elds
Summarize heap locations that are not immediately type-inconsistent with okheap
Concrete State
Symbolic Heap
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
17
heapthis.obj this.sel
s
o
this
Summarize heap locations that are not immediately type-inconsistent with okheap
Concrete State
Symbolic Heap
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
Formula literal: concretization includes every subheap that is not immediately type inconsistent
17
heapthis.obj this.sel
s
o
this
Summarize heap locations that are not immediately type-inconsistent with okheap
Concrete State
Symbolic Heap
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
Describes storage without explicitly enumerating it
Formula literal: concretization includes every subheap that is not immediately type inconsistent
17
heapthis.obj this.sel
s
o
this
Summarize heap locations that are not immediately type-inconsistent with okheap
Concrete State
Symbolic Heap
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
Describes storage without explicitly enumerating it
Formula literal: concretization includes every subheap that is not immediately type inconsistent
17
heapthis.obj this.sel
s
o
this
Immediately after switch, type invariants still hold so okheap
represents entire heap
Key Contributions1 Translate type invariant into
symbolic state via “symbolization” of type environment
type analysis
symbolic !owanalysis
type analysis
2 Leverage heap type invariantduring symbolic analysis viatype-consistent materialization and summarization
1
18
Key Contributions1 Translate type invariant into
symbolic state via “symbolization” of type environment
type analysis
symbolic !owanalysis
type analysis
2 Leverage heap type invariantduring symbolic analysis viatype-consistent materialization and summarization
2
18
Leverage heap type invariant via type-consistent materialization
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
19
heapthis.obj this.sel
s
o
this
Leverage heap type invariant via type-consistent materialization
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
fsel fobj
⇤ gthis 7! {sel 7! ⇤ obj 7! }
Materialize onto standard separation-logic explicit heap
19
heapthis.obj this.sel
s
o
this
Leverage heap type invariant via type-consistent materialization
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
fsel fobj
⇤ gthis 7! {sel 7! ⇤ obj 7! }
Materialize onto standard separation-logic explicit heap
Must-alias and dis-alias guarantee requires case split on materialization
19
heapthis.obj this.sel
s
o
this
Leverage heap type invariant via type-consistent materialization
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
fsel fobj
⇤ gthis 7! {sel 7! ⇤ obj 7! }
Materialize onto standard separation-logic explicit heap
Must-alias and dis-alias guarantee requires case split on materialization
Materialized storage guaranteed to be not immediately type-
inconsistent
19
heapthis.obj this.sel
s
o
this
Leverage heap type invariant via type-consistent materialization
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
fsel fobj
⇤ gthis 7! {sel 7! ⇤ obj 7! }
Materialize onto standard separation-logic explicit heap
Must-alias and dis-alias guarantee requires case split on materialization
Materialized storage guaranteed to be not immediately type-
inconsistent
19
Value stored in obj responds to value
stored in sel
heapthis.obj this.sel
s
o
this
Leverage heap type invariant via type-consistent materialization
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
fsel fobj
⇤ gthis 7! {sel 7! ⇤ obj 7! }
Materialize onto standard separation-logic explicit heap
Must-alias and dis-alias guarantee requires case split on materialization
Materialized storage guaranteed to be not immediately type-
inconsistent
19
Value stored in obj responds to value
stored in sel
heapthis.obj this.sel
s
o
this
Represent materialized storage
with cutout
Leverage heap type invariant via type-consistent materialization
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
fsel fobj
⇤ gthis 7! {sel 7! ⇤ obj 7! }
Materialize onto standard separation-logic explicit heap
Must-alias and dis-alias guarantee requires case split on materialization
Materialized storage guaranteed to be not immediately type-
inconsistent
19
Value stored in obj responds to value
stored in sel
heapthis.obj this.sel
s
o
this
Analysis can assume that type invariant initially holds on all materialized storage
heapthis.obj this.sel
s
o
this
Strong updates on materialized storage to detect invariant restoration
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
fsel fobj
⇤ gthis 7! {sel 7! ⇤ obj 7! }
20
Strong updates on materialized storage to detect invariant restoration
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
fobj
⇤ gthis 7! {sel 7! ⇤ obj 7! }es
20
heapthis.obj this.sel
s
o
this
Strong updates on materialized storage to detect invariant restoration
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
fobj
⇤ gthis 7! {sel 7! ⇤ obj 7! }es
20
heapthis.obj this.sel
s
o
this
Type invariant violated
Strong updates on materialized storage to detect invariant restoration
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
fobj
⇤ gthis 7! {sel 7! ⇤ obj 7! }es
20
heapthis.obj this.sel
s
o
this
Type invariant violated
Surprising: can soundly permit pointers in and out of the region that is not
immediately type-consistent
Strong updates on materialized storage to detect invariant restoration
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
⇤ gthis 7! {sel 7! ⇤ obj 7! }eoes
20
heapthis.obj this.sel
s
o
this
Strong updates on materialized storage to detect invariant restoration
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
⇤ gthis 7! {sel 7! ⇤ obj 7! }eoes
20
heapthis.obj this.sel
s
o
this
No longer immediately type-inconsistent
Safely summarize storage that is not immediately type inconsistent
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
⇤ gthis 7! {sel 7! ⇤ obj 7! }eoes
21
heapthis.obj this.sel
s
o
this
Safely summarize storage that is not immediately type inconsistent
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
21
heapthis.obj this.sel
s
o
this
Safely summarize storage that is not immediately type inconsistent
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
Only need to reason precisely about part of heap where invariant broken,
so helps manage alias explosion
21
heapthis.obj this.sel
s
o
this
Safely summarize storage that is not immediately type inconsistent
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
Only need to reason precisely about part of heap where invariant broken,
so helps manage alias explosion
21
heapthis.obj this.sel
s
o
this
Entire heap is type consistent so safe to
return to type checking
Safely summarize storage that is not immediately type inconsistent
Concrete State
Symbolic State
eH okheap
def update(s:Str, o:Obj | r2 s)this.sel = sthis.obj = o
Only need to reason precisely about part of heap where invariant broken,
so helps manage alias explosion
21
heap
this
o
s
this.obj this.sel
Entire heap is type consistent so safe to
return to type checking
Key Contributions1 Translate type invariant into
symbolic state via “symbolization” of type environment
type analysis
symbolic !owanalysis
type analysis
2 Leverage heap type invariantduring symbolic analysis viatype-consistent materialization and summarization
2
22
Key Contributions1 Translate type invariant into
symbolic state via “symbolization” of type environment
type analysis
symbolic !owanalysis
type analysis
2 Leverage heap type invariantduring symbolic analysis viatype-consistent materialization and summarization
22
23
Fissile Type Analysis is sound
23
Theorem (Soundness of Handoff). The entire state is type-consistent iff all locations are not immediately type-inconsistent.
Fissile Type Analysis is sound
heap
this
o
s
this.obj this.sel
heapthis.obj this.sel
s
o
this
23
Theorem (Soundness of Handoff). The entire state is type-consistent iff all locations are not immediately type-inconsistent.
Theorem (Soundness of Materialization/Summarization). Storage that is not immediately type-inconsistent can be safely materialized and summarized into okheap.
Fissile Type Analysis is sound
heap
this
o
s
this.obj this.sel
heapthis.obj this.sel
s
o
this
heapthis.obj this.sel
s
o
this
heapthis.obj this.sel
s
o
this
Precision: What is improvement over "ow-insensitive checking alone?
Cost: What is the cost of analysis in running time?
Evaluation
24
Analysis mechanics: How often is symbolic reasoning required?
9 Objective-C benchmarks
Case Study: Re"ection in Objective-C
76 r2 annotations on system libraries
6 libraries and 3 applications
136 annotations on benchmark code
Manual type annotations
1,000 to 176,000 lines of code
Plugin for clang static analyzer in C++
Prototype analysis implementation
25
9 Objective-C benchmarks
Case Study: Re"ection in Objective-C
76 r2 annotations on system libraries
6 libraries and 3 applications
136 annotations on benchmark code
Manual type annotations
1,000 to 176,000 lines of code
Plugin for clang static analyzer in C++
Prototype analysis implementation
25
Including Skim, Adium, and
OmniGraffle
benchmark
size
(loc)symbolicsections
maximummaterializations
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 7 1
2716 2 2
3301 0 0
5289 3 1
14620 59 2
160769 7 1
37327 28 2
60211 0 0
176629 16 1
combined 461080 125 2
Analysis mechanics
26
benchmark
size
(loc)symbolicsections
maximummaterializations
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 7 1
2716 2 2
3301 0 0
5289 3 1
14620 59 2
160769 7 1
37327 28 2
60211 0 0
176629 16 1
combined 461080 125 2
Analysis mechanics
Number of successful switches to symbolic
analysis and back
26
benchmark
size
(loc)symbolicsections
maximummaterializations
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 7 1
2716 2 2
3301 0 0
5289 3 1
14620 59 2
160769 7 1
37327 28 2
60211 0 0
176629 16 1
combined 461080 125 2
Analysis mechanics
A signi!cant number of switches:Approach successfully handles when developers break and restore global invariants
Number of successful switches to symbolic
analysis and back
26
benchmark
size
(loc)symbolicsections
maximummaterializations
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 7 1
2716 2 2
3301 0 0
5289 3 1
14620 59 2
160769 7 1
37327 28 2
60211 0 0
176629 16 1
combined 461080 125 2
Analysis mechanics
Maximum number of simultaneous
materialized storage locations
A signi!cant number of switches:Approach successfully handles when developers break and restore global invariants
26
benchmark
size
(loc)symbolicsections
maximummaterializations
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 7 1
2716 2 2
3301 0 0
5289 3 1
14620 59 2
160769 7 1
37327 28 2
60211 0 0
176629 16 1
combined 461080 125 2
Analysis mechanics
Maximum number of simultaneous
materialized storage locations
A signi!cant number of switches:Approach successfully handles when developers break and restore global invariants
At most 2 simultaneous materializations: Aliasing case splits will not blow up
26
benchmark
size
(loc)symbolicsections
maximummaterializations
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 7 1
2716 2 2
3301 0 0
5289 3 1
14620 59 2
160769 7 1
37327 28 2
60211 0 0
176629 16 1
combined 461080 125 2
Analysis mechanics
A signi!cant number of switches:Approach successfully handles when developers break and restore global invariants
At most 2 simultaneous materializations: Aliasing case splits will not blow up
26
benchmark
size
(loc)symbolicsections
maximummaterializations
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 7 1
2716 2 2
3301 0 0
5289 3 1
14620 59 2
160769 7 1
37327 28 2
60211 0 0
176629 16 1
combined 461080 125 2
Analysis mechanics
A signi!cant number of switches:Approach successfully handles when developers break and restore global invariants
At most 2 simultaneous materializations: Aliasing case splits will not blow up
26
Approaches limited to one-at-a-time materialization not sufficient
benchmark
sizesize false alarmsfalse alarms
(loc)re"ective call
sites"ow-
insensitivealmost-
everywhere
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 7 7 2 (-71%)
2716 12 2 0 (-100%)
3301 28 0 0 (-)
5289 40 4 1 (-75%)
14620 68 50 10 (-80%)
160769 192 82 74 (-10%)
37327 186 59 38 (-36%)
60211 207 43 43 (-0%)
176629 587 87 70 (-20%)
combined 461080 1327 334 238 (-29%)
Precision
27
benchmark
sizesize false alarmsfalse alarms
(loc)re"ective call
sites"ow-
insensitivealmost-
everywhere
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 7 7 2 (-71%)
2716 12 2 0 (-100%)
3301 28 0 0 (-)
5289 40 4 1 (-75%)
14620 68 50 10 (-80%)
160769 192 82 74 (-10%)
37327 186 59 38 (-36%)
60211 207 43 43 (-0%)
176629 587 87 70 (-20%)
combined 461080 1327 334 238 (-29%)
Precision
Baseline: standard, "ow-insensitive type analysis – no switching
27
benchmark
sizesize false alarmsfalse alarms
(loc)re"ective call
sites"ow-
insensitivealmost-
everywhere
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 7 7 2 (-71%)
2716 12 2 0 (-100%)
3301 28 0 0 (-)
5289 40 4 1 (-75%)
14620 68 50 10 (-80%)
160769 192 82 74 (-10%)
37327 186 59 38 (-36%)
60211 207 43 43 (-0%)
176629 587 87 70 (-20%)
combined 461080 1327 334 238 (-29%)
Precision
Baseline: standard, "ow-insensitive type analysis – no switching
27
benchmark
sizesize false alarmsfalse alarms
(loc)re"ective call
sites"ow-
insensitivealmost-
everywhere
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 7 7 2 (-71%)
2716 12 2 0 (-100%)
3301 28 0 0 (-)
5289 40 4 1 (-75%)
14620 68 50 10 (-80%)
160769 192 82 74 (-10%)
37327 186 59 38 (-36%)
60211 207 43 43 (-0%)
176629 587 87 70 (-20%)
combined 461080 1327 334 238 (-29%)
Precision
Baseline: standard, "ow-insensitive type analysis – no switching
Almost everywhere techniques show 29% improvement in false alarms
27
benchmark
sizesize false alarmsfalse alarms
(loc)re"ective call
sites"ow-
insensitivealmost-
everywhere
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 7 7 2 (-71%)
2716 12 2 0 (-100%)
3301 28 0 0 (-)
5289 40 4 1 (-75%)
14620 68 50 10 (-80%)
160769 192 82 74 (-10%)
37327 186 59 38 (-36%)
60211 207 43 43 (-0%)
176629 587 87 70 (-20%)
combined 461080 1327 334 238 (-29%)
Precision
Baseline: standard, "ow-insensitive type analysis – no switching
Almost everywhere techniques show 29% improvement in false alarms
Also found a real re!ection bug in Vienna, which we reported and
which was !xed
27
benchmark
size analysis timeanalysis time
(loc) TimeRate
(kloc/s)
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 0.24s 5.3
2716 0.28s 10.8
3301 0.10s 33.0
5289 0.67s 7.9
14620 0.50s 27.2
160769 4.25s 37.8
37327 2.79s 13.4
60211 2.49s 24.1
176629 8.79s 20.1
combined 461080 20.09s 23.0
Cost: Analysis time
28
benchmark
size analysis timeanalysis time
(loc) TimeRate
(kloc/s)
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 0.24s 5.3
2716 0.28s 10.8
3301 0.10s 33.0
5289 0.67s 7.9
14620 0.50s 27.2
160769 4.25s 37.8
37327 2.79s 13.4
60211 2.49s 24.1
176629 8.79s 20.1
combined 461080 20.09s 23.0
Includes analysis time but not parsing, base
type checking
Cost: Analysis time
28
benchmark
size analysis timeanalysis time
(loc) TimeRate
(kloc/s)
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 0.24s 5.3
2716 0.28s 10.8
3301 0.10s 33.0
5289 0.67s 7.9
14620 0.50s 27.2
160769 4.25s 37.8
37327 2.79s 13.4
60211 2.49s 24.1
176629 8.79s 20.1
combined 461080 20.09s 23.0
Includes analysis time but not parsing, base
type checking
Cost: Analysis time
Does not include system
headers
28
benchmark
size analysis timeanalysis time
(loc) TimeRate
(kloc/s)
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 0.24s 5.3
2716 0.28s 10.8
3301 0.10s 33.0
5289 0.67s 7.9
14620 0.50s 27.2
160769 4.25s 37.8
37327 2.79s 13.4
60211 2.49s 24.1
176629 8.79s 20.1
combined 461080 20.09s 23.0
Cost: Analysis time
Fast: 5 to 38 kloc/s with most time spent analyzing system headers
28
benchmark
size analysis timeanalysis time
(loc) TimeRate
(kloc/s)
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 0.24s 5.3
2716 0.28s 10.8
3301 0.10s 33.0
5289 0.67s 7.9
14620 0.50s 27.2
160769 4.25s 37.8
37327 2.79s 13.4
60211 2.49s 24.1
176629 8.79s 20.1
combined 461080 20.09s 23.0
Cost: Analysis time
Fast: 5 to 38 kloc/s with most time spent analyzing system headers Interactive
speeds
28
benchmark
size analysis timeanalysis time
(loc) TimeRate
(kloc/s)
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 0.24s 5.3
2716 0.28s 10.8
3301 0.10s 33.0
5289 0.67s 7.9
14620 0.50s 27.2
160769 4.25s 37.8
37327 2.79s 13.4
60211 2.49s 24.1
176629 8.79s 20.1
combined 461080 20.09s 23.0
Higher rate for projects with larger translation units
Cost: Analysis time
Fast: 5 to 38 kloc/s with most time spent analyzing system headers
28
benchmark
size analysis timeanalysis time
(loc) TimeRate
(kloc/s)
OAUTH
SCRECORDER
ZIPKIT
SPARKLE
ASIHTTPREQUEST
OMNIFRAMEWORKS
VIENNA
SKIM
ADIUM
1248 0.24s 5.3
2716 0.28s 10.8
3301 0.10s 33.0
5289 0.67s 7.9
14620 0.50s 27.2
160769 4.25s 37.8
37327 2.79s 13.4
60211 2.49s 24.1
176629 8.79s 20.1
combined 461080 20.09s 23.0
Higher rate for projects with larger translation units
Cost: Analysis time
Fast: 5 to 38 kloc/s with most time spent analyzing system headersMaintains key bene"t of !ow-
insensitive analyses: speed
28
• Check almost everywhere heap invariants with intertwined type and symbolic "ow analysis
• Translate type environment into symbolic state with symbolization
• Leverage heap type invariant during symbolic analysis via type-consistent materialization and summarization
• Approach is very fast and scales to large programs
Summary
29
Fissile Type Analysis yields signi"cant precision improvement at little cost
in performance
30
Fissile Type Analysis yields signi"cant precision improvement at little cost
in performance
Why?
30
Fissile Type Analysis yields signi"cant precision improvement at little cost
in performance
Because almost-everywhere invariants hold almost everywhere
Why?
30