Fissile Type Analysis: Modular Checking of Almost ... · Fissile Type Analysis: Modular Checking of...

Post on 04-Jul-2020

8 views 0 download

transcript

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