Low-Level Liquid Types
description
Transcript of Low-Level Liquid Types
http://www.flickr.com/photos/fallsroad/6759129/in/set-125319/
Low-Level Liquid Types Patrick M. Rondon, Ming Kawaguchi, Ranjit Jhala University of California, San Diego
Refinement Type Inference(Invariant Discovery)
Liquid Types
C Program Verification Vs. Liquid Types
x++;
C Program
x : positive int…
Inferred Refinement Types(Discovered Invariants)
How Do We Fit C To Liquid Types?
Positive
Addressing C’s Challenges
void init (string *s, int n) { s->len = n; s->str = malloc(n);}
void reinit (stringlist *sl) { while (sl != NULL) { init (sl->s, random ()); sl = sl->next; }}
struct string { int len; char *str;}
Points To Start Of len Bytes1. Expressing Invariants?
2. Temporary Violations?
3. Unknown Aliasing?
str Hasn’t Been Set Yet
sl, sl->next May Alias
Challenge
Types & Refinement Types
Strong Updates
Check In, Check Out Discipline
Solution
Adapt C To Liquid Types
+
+
Refinement Type Inference(Invariant Discovery)
Liquid Types
C Program Verification With Liquid Types
C Program
x : positive int…
Inferred Refinement Types(Discovered Invariants)
Automatically Adapt C Programs To Fit Liquid Types
C Program+ Types
+ Strong Update+ Check In, Check Out
x++;
Overview
Basic TypesRefinement TypesRefinement Types And Collections
Refinement Type InferenceEvaluation
Basic Types
We first describe the basic structure of the heap
Offset 4Offset 0
After 4-byte int fst
Basic Types And Heaps By Example
struct pair { int fst; int snd;}
p->fst++;p->snd++;
p : ref(L, 0)
0 : int(4, 0)
4 : int(4, 4)Type Given
int(4, ⊤)
int(4, ⊤)L ⟼
Read/Write int(4, ⊤)
At Offset 0 In L
p + 0 : ref(L, 0)
At Offset 4 In L
p + 4 : ref(L, 4)
At Start Of Struct
Pointer To Location L At Byte Offset 04-Byte Integer With
Value 0Pointer To Location L At
Byte Offset 04-Byte Integer With
Value 4*(p + 0)++;*(p + 4)++;
Pointer To Location L At Byte Offset 4
Read/Write int(4, ⊤)
Overview
Basic TypesRefinement TypesRefinement Types And Collections
Refinement Type InferenceEvaluation
Refinement Types
We use refinement types to express invariants
Offset 4Offset 0
Refinement Types And Heaps{ν: type | p(ν)}type
Refinement Predicate
{ν: int(4, ⊤ ) | ν > 0}{ν: ref(L, 0) | ν ≠ 0}
Positive IntegerNon-NULL Pointer
Pair With snd ≥ fst
int(4, ⊤)L ⟼
Denotes fst Field
{ν: int(4, ⊤) | ν ≥ @0}fst
Fieldsnd
Field
Offset 4Offset 0
Maintaining The Invariant
p->fst++;p->snd++;
L ⟼ int {ν ≥ @0}
Requires Flow-Sensitivity And Strong Update
Temporary Invariant Violation
int(4, ⊤)L ⟼ {ν: int(4, ⊤) | ν ≥
@0}
Invariant ReestablishedInvariant
Maintained
Value Names Enable Strong Update
int {ν ≥ @0}L ⟼
{ν = f0} {ν = f4}L ⟼
f0 : int f4 : {ν ≥ f0}
Records Same Invariant With Initial Values Named
Change @0 to f0
Env.
Rename fst To f0
Rename snd To f4
Using Strong Updatesf0 : int f4 : {ν ≥ f0}
p->fst++;
p->snd++;
{ν = f0}L ⟼ {ν = f4}
Env.
{ν = f0 + 1}L ⟼ {ν = f4}
{ν = f0 + 1}L ⟼ {ν = f4 + 1}
intL ⟼ {ν ≥ @0}
p->fst = p->fst + 1;Type {ν
= f0}Type {ν = f0 +
1}snd Unchanged
☑Invariant Reestablished!
p : ref(L, 0)
Is Subsumed By:
Overview
Basic TypesRefinement TypesRefinement Types And Collections
Refinement Type InferenceEvaluation
Refinement Types And Collections
We adapt strong update to handle aliasing
struct pair { int fst; int snd; pair *next;}
Example: Loops and Linked Lists
while (p != NULL) { p->fst++; p->snd++; p = p->next; }
intL ⟼ {ν ≥ @0} ref(L, 0)
Many Items Represented By L
intL ⟼ {ν ≥ @0} ref(L, 0)next FieldAbstract
Location
…
Strong Updates To Abstract Locations Are Unsound!Their Invariants Are “Locked”
Unfold And Fold: Check Out, Check In
All Satisfy L’s Invariant
Unfold p
…
…
p
“Checked Out” Lp
Only Allow Accesses To One “Checked Out” Lp
Must “Check In” (Reestablish Invariant)To Check Out Another Item
All Satisfy L’s Invariant…
Fold
“Check Out” p
“Check In” p
Accessing Other Items Forbidden
Example: Fold & Unfold
p->fst++;p->snd++;
int {ν ≥ @0}L ⟼
{ν = f0}Lp ⟼ {ν = f4}
int {ν ≥ @0}L ⟼ {ν = f0 +
1}Lp ⟼ {ν = f4 + 1}
Fold
int {ν ≥ @0}L ⟼
Unfold p
while (p != NULL) { p->fst++; p->snd++; p = p->next;}
Unfold p At Loop Head
Fold Ensures Validity At Iteration’s End
Fold, Unfold Verify Collection Invariant int {ν ≥ @0}L ⟼
p : ref(L, 0)
☑Invariant Maintained!
Overview
Basic TypesRefinement TypesRefinement Types And Collections
Refinement Type InferenceEvaluation
Inferring Refinement Types
p->fst++;p->snd++;
{R} {S}L ⟼
{ν = f0}Lp ⟼ {ν = f4}
{R} {S}L ⟼ {ν = f0 +
1}Lp ⟼ {ν = f4 + 1}
Fold
{R} {S}L ⟼
Unfold p
{R} {S}L ⟼ ν ≥ *ν = 0
…
ν ≥ f0ν = 0
…
{ν ≥ f0, ν = 0, …}
{ν ≥ f0, ν = 0, …}L ⟼
{ν ≥ f0, ν = 0, …}
{ν ≥ f0, ν = 0, …}L ⟼
int {ν ≥ @0}L ⟼
int {ν ≥ @0}L ⟼
{ν ≥ f0, ν = 0, …}
{ν ≥ f0, ν = 0, …}L ⟼ int {ν ≥ @0}
{ν ≥ f0, ν = 0, …}
{ν ≥ f0, ν = 0, …}L ⟼ int {ν ≥ @0}L ⟼
1. Unknown Refinement Variables2. Subtyping Constraints Over Variables3. Solve To Infer Refinements
Liquid Types Overview:
Hints For Refinement Inference
Instantiate With Value Names
Assign Conjunction To Variables
Keep Only Valid Refinements
Overview
Basic TypesRefinement TypesRefinement Types And Collections
Refinement Type InferenceEvaluation
Evaluation: CSolve
CSolve
C Source
void incpairs(pair *p) { while (p != NULL) { *(p + offsetOf(fst)); *(p + offsetOf(snd)); p = p->next; }}
Hintsν ≥ *ν ≤ *
ν = * + 1
☑Pointer Safe!Spatial Memory Safety:• Array Bounds• Pointer Dereferences• Field Accesses
☒Pointer Unsafe!
BenchmarksProgram Lines Hints Dyn. Checks Time (s)stringlist 72 1 0 2strcpy 77 3 0 4adpcm 198 13 0 42pmap 250 3 0 34mst 309 1 0 16power 620 7 2 111ft 652 2 6 310ks 742 9 7 721Total 2,920 39 15 1,240
Arrays
Arrays
Arrays
Arrays
Arrays
Arrays
Arrays
Arrays
Graphs
Graphs
Graphs
Linked Lists
Linked Lists
Linked Lists
Linked Lists
Linked Lists
Verifying C Programs
2. Temporary Violations? Strong Updates
3. Unknown Aliasing? Check In, Check Out Discipline
4. Annotation Burden? Liquid Types
1. Expressing Invariants?Types & Refinement Types
Challenge Solution
pho.ucsd.edu/liquid