Using data groups to specify and check side effects

Download Report

Transcript Using data groups to specify and check side effects

Using data groups to specify
and check side effects
K. Rustan M. Leino
Microsoft Research
Arnd Poetzsch-Heffter
Universität Kaiserslautern
Yunhong Zhou
HP SRC
Work done at Compaq SRC
18 June 2002
PLDI’02, Berlin, Germany
Introduction
The Problem:
Checking effects in a modular and extensible way.
Motivation:
 Optimizations
 Error detection
Aliasing Restrictions:
 Pivot uniqueness
 Owner exclusion
Modifies clause
method p(x, y)
modifies M;
Grants the implementations of p
the license to modify M
Challenge:
Soundness - Does p(x,y) modify only M?
Context
Pieces of a
Program
Static
program
checker
Warning
messages
Modular checking
 Modular
checking
Access to complete program not necessary
Don’t assume availability of:


implementations of called methods
all of the program’s variables
 Modular


soundness
Only interface properties of checked parts are needed
to check extensions
Checking is sound for any extension of the program
Extension of the code
class Position {
int x, y;
virtual void update() modifies x,y
{...}
}
class Position3D : Position {
int z;
void update() modifies(x,y,z)
{...}
}
Information hiding
Queue
q
method Enqueue(x)
modifies ???;
public
private
head
17
size
8
buf
Buffer
capacity
32
method Enlarge()
modifies capacity, …;
Data groups
Queue
q
group contents;
method Enqueue(x)
modifies contents;
???;
public
private
head
17
size
8
buf
Buffer
capacity
32
method Enlarge()
modifies capacity, …;
Source code
class Queue {
public group contents;
public void Enqueue(object x)
modifies contents;
head  contents
size  contents
private Buffer buf maps capacity into contents;
private int head in contents;
private int size in contents;
buf.capacity  contents
Data Groups




A set of variables and nested data groups
Membership defined incrementally
A field/group can be part of multiple groups
The license to modify a group implies the license
to modify the members of the group
group contents
head
size
buf.elements
capacity
array
Extension of the code - solution
class Position {
GROUP G;
int x in G, y in G;
virtual void update() modifies G
{...}
}
class Position3D : Position {
int z in G;
void update()
{...}
}
new field added to G
same modifies clause
Inclusion types
“Local Inclusion”
private int head in contents;
private int size in contents;
head  contents
size  contents
“pivot field”
Queue
private Buffer buf maps capacity into contents;
buf
buf.capacity  contents
Buffer
capacity
Summary so far

modular checking
modifies clauses
information hiding
data groups!
Extensibility
What about soundness?

next: 2 problems and proposed solutions





Problem 1
Client:
Queue q = new Queue();
Buffer b = q.m();
int c = b.capacity;
q.Enqueue(5);
assert c == b.capacity;
group contents;
method Enqueue(x)
modifies contents;
method Buffer m()
modifies ;
Queue
head
size
buf
q
Buffer
method Buffer m() {
return buf;
}
Buffer buf maps capacity
into contents
b
capacity
Solution 1: Pivot uniqueness restriction

Make pivot fields unique
Queue
group contents;
capacity
Buffer
buf
field buf maps capacity into contents
Three restrictions:
 Pivot fields can only be assigned new or null
 Can’t assign a pivot field to anything. This avoid the
previous problem
 What about function parameters?
Pivot uniqueness - cont
method Enqueue ( object x ) {
if ( size == buf.capacity ) {
buf.Enlarge ();
}
…
}

permit aliasing with parameters, but do not allow assigning
to/from formal parameters
results:
 Pivot fields are either null or unique (Except for formal
parameter aliases on the call stack).
 Static checker will not complain the assertion in the
client regardless of whether declaration of buf is
available to it.
Problem 2
Queue q = new Queue();
Buffer bp(
= q.m(); ,
method
int c = b.capacity;
q.Enqueue(5);
assert c == b.capacity;
}
class Queue {
…
p(this, this.buf);
…
}
Buffer buf maps capacity
into contents
Queue
) modifies contents {
group contents;
buf
head
size
q
Buffer
capacity
b
Problem #2 analysis
Can happen only when all three apply:
 The pivot field is passed as a parameter
(otherwise pivot uniqueness prevents it)
 The owner of the pivot value (q in the
example) is accessible to the callee.

q.contents is modified.
Solution 2: Owner exclusion restriction
For any pivot field:
field buf maps capacity into contents;
and method:
method m(…, T x, …)
modifies …, E.contents, … ;
add to m the following precondition:
E.buf != x
What’s in the paper

Sound formalization



a core object-oriented language (oolong )
pivot uniqueness and owner exclusion
restrictions
translation from oolong to verification
conditions
The Semantic Model
capacity
group contents;
q
buf
Object store: S (q.buf) = b
 Define transitive inclusion relation:
_ in _ : Attrib x Group
bool
_ maps _ into _ : Field x Attrib x Group
b

X.F
S
Y.G

bool
X = Y /\ F in G
\/ X, Z, B, H :: B maps F into H
/\ X = S(Z.B)
/\ Z.H
S(q.buf).capacity
S
q.Contents
S
Y.G
Semantic Model - Field update

Field update commands require that their targets be
assignable according to the modifies list w evaluated in
the store S.
Mod(X.A, w, S)  ¬ alive(S,X) V incl (X.A, w, S)
alive(S,X) : true if X was allocated in store S
incl (X.A, w, S)

( E,f | E.f  w /\ X.A
S
E.f )
Semantic Model – Owner Exclusion

Let p(r) modifies V.a be a method spec.
Owner exclusion for a call p(x) :
ownExcl(x,V.a,S) 
buf
capacity contents
q.buf
For Y, B, G, H: B maps G into H /\ x = S(Y.B) /\ x ≠ null
q.contents
=>


( Y.H
S
S(V).a )
The pivot field buf of object q can be passed as a
parameter to method p only if p doesn’t have permission
to modify q.contents .
Check ownExcl at every call site, and assume it at entry
to the function
Modular checker






Object store – track values of object attributes
and allocated objects.
Inclusion relation – between locations. track
compositions of inclusions (transitive).
Check a function is side-effect correct (Mod)
Check owner inclusion precondition (ownExcl)
Check assignments of pivot fields and formal
parameters
Check assert statements (effect of function call)
using ¬Mod.
Example
field c field d field f
Group g
Proc p(t) modifies t.c.d.g
Proc q(u) modifies u.g
Impl p (t){
Assume t≠null
var y in
ownExcl( t, t.c.d.g, S)
At q function call:
y:=t.f
Mod( u.g, t.c.d.g, S)
q(t.c.d)
ownExcl( u, u.g, S)
assert y=t.f
At assert:
end
}
At p function entry:
¬ Mod( t.f, u.g, S)
Conclusion






Knowing side effects has many applications
Specifying and checking side effects in modular
setting is a difficult problem
Data groups plus alias-confinement restrictions
provide a solution
Sound formalization (oolong )
Implemented checker (oolong )
Current work: build checker for C#
(with Viktor Kuncak)
Limitations


Syntactic aliasing discipline too strict
Array support not implemented : when an
object is implemented in terms of an array
of underlying objects.
Limitations

Cyclic dependencies not handled effectively:
infinite looping of ‘Simplify’ ,the theorem
prover.
class Node {
public:
group g;
void updateAll() modifies g;
private :
int value in g;
Node next maps g into g;
}
void updateAll(){
value = value + 1;
If (next != null)
next->updateAll();
}
The End!