• No results found

5.3 Reverse Example

6.3.3.1 ADD DEALLOC Macro

1 #define ADD DEALLOC(a, b) 2 {

3 PRE DEALLOC(a); 4 a := copy(b);

5 a_dealloc := true; // Add the Deallocation to ’a’ 6 }

ADD DEALLOC(a, b) macro:

• uses pre-deallocation macro to empty variable a and reset its flag value; • creates a fresh copy of variable b, whose memory space is not aliased

with any existing variable;

• assigns the copied b to variable a and add the flag to a

Assumption 2 For an assignment a := copy(b), we include a precondition

e(a)6= e(b)

to ensure when adealloc and bdealloc are both true, variable a and b are not

aliased to the same memory space before the function call. Also, we need an extra precondition

valid(e(b)) = true

to ensure the memory address pointed by variable b is valid and safe to per- form the operation. With above preconditions, we can ensure adealloc must be

false when variable a and b are aliased and also bdealloc is true. Therefore,

PRE DEALLOC(a) will not free the memory at e(a) = e(b), making e(b) an

invalid address and avoid segmentation fault when trying to copy from e(b).

Theorem 6.4 ADD DEALLOC(a, b) macro makes a copy of variable b and as- signs it to a. If INV ande(a)6= e(b) and valid(e(b)) hold before ADD DEALLOC(a, b) macro, then INV still holds true after the macro, as below Hoare Logic:

{INV ∧ (∀i ∈ V ARS • e(i) = e0(i))∧ (∀d ∈ ADR • valid(d) = v0(d))

∧ e(a) 6= e(b) ∧ valid(e(b))} ADD DEALLOC(a, b)

{INV ∧ (∀i ∈ V ARS • i 6≡ a ∧ i 6≡ adealloc =⇒ e(i) = e0(i))

∧ (∀d ∈ ADR • d 6= e0(a)∧ d 6= e(a) =⇒ valid(d) = v0(d))

98

1 {INV ∧ (∀i ∈ V ARS • e(i) = e0(i))∧ (∀d ∈ ADR • valid(d) = v0(d))∧ 2 e(a)6= e(b) ∧ valid(e(b))}

1

3 PRE_DEALLOC(a);

4 {INV ∧ (∀i ∈ V ARS • i 6≡ a ∧ i 6≡ adealloc =⇒ e(i) = e0(i)) 5 ∧(∀d ∈ ADR • d 6= e0(a) =⇒ valid(d) = v0(d))∧ 6 e0(a)6= e(b) ∧ valid(e(b))}

2

7

8 {INV ∧ valid(e(b)) ∧ (∀i ∈ V ARS • e(i) = e1(i)) 9 ∧(∀d ∈ ADR • valid(d) = v1(d))

3

10 a:=copy(b); 11 a_dealloc:=true;

12 {fresh(a) ∧ (∀i ∈ V ARS • i 6≡ a ∧ i 6≡ adealloc =⇒ e(i) = e1(i))

4a∧

13 (∀d ∈ ADR • d 6= e(a) =⇒ valid(d) = v1(d))

4b∧

14 valid(e(a))∧ valid(e(b)) ∧ e(adealloc)

4c}

15

16 {INV

5a ∧ (∀i ∈ V ARS • i 6≡ a ∧ i 6≡ adealloc =⇒ e(i) = e0(i))

5b∧

17 (∀d ∈ ADR • d 6= e0(a)∧ d 6= e(a) =⇒ valid(d) = v0(d))

5c∧

18 valid(e(b))∧ valid(e(a)) ∧ e(adealloc)}

Listing 6.3: Tableau of ADD DEALLOC(a, b) macro

The previous section shows our invariant is preserved before and after pre- deallocation macro. So we are only required to prove our invariant still holds after the last two code statements, as below:

Assumption 1

e(a)6= e(b) and valid(e(b)) are assumed to be true in the entry condition of the macro.

Reasoning about 2

Show e(b) = e0(a) and valid(e(b)) are both true in

the post condition of pre-deallocation macro (refer to Theorem 6.2).

Because e(b) = e0(b) 6= e0(a) and only validity of e0(a) is changed by

pre-deallocation macro, valid(e(b)) is true in the post-state.

Assumption 3

Define e1(i) and v1(d ) to store the addresses and validity

of variables respectively after PRE DEALLOC macro. In doing so, we can focus on the precondition and post condition of line 10 and 11.

Reasoning about

4a and

4b Show e(i) = e1(i) and valid(d) = v1(i) is

true. Since only e(a) and adealloc is changed by line 10 and 11, e(i) remains

the same as e1(i) for all other variables, and the validity is unchanged for all

Assumption

4c Show valid(e(a)), valid(e(b)), fresh(a) and e(adealloc) are

true in the post-condition.

valid(e(a))∧ fresh(a) is included into the post-state from 6.9.

valide(e(b)) remains true in the post-state because our macro in (line 10 and 11) does not de-allocate anything.

e(adealloc) is true from line 11.

Reasoning about

5a Show that INV holds at the end of macro.

IN V :∀i, j ∈ V ARS • inv dealloc(i, j) A

∧ ∀i ∈ ARRV ARS • inv arr(i) B

Proof. [Reasoning Deallocation Invariant ( A

)]

Let i, j ∈ V ARS be the witness variables. We must show that ∀i, j•inv dealloc(i, j) holds true after ADD DEALLOC(a, b) macro. Consider the following four cases:

• Case 1: i, j includes both a and b

Given i≡ a ∧ j ≡ b (or equivalently j ≡ a ∧ i ≡ b), the invariant can be rewritten as:

inv dealloc(a, b) :(e(adealloc)∧ e(bdealloc)∧

a6≡ b) =⇒ e(a) 6= e(b)

(6.19)

From precondition e0(a) 6= e0(b), which implies a 6≡ b, and fresh(a), we

conclude that a6≡ b =⇒ e(a) 6= e(b). That implies that inv dealloc(a, b) still is true in the post-state.

• Case 2: i, j includes a but NOT b

Given i≡ a ∧ j 6≡ b (or equivalently j ≡ a ∧ i 6≡ b), the invariant can be rewritten as:

inv dealloc(a, j) :e(adealloc)∧ e(jdealloc)∧

a6≡ j =⇒ e(a) 6= e(j)

(6.20)

Assume that all the preconditions in (6.20) are true, including a 6≡ j. With true value of f resh(a) : j 6≡ a =⇒ e(j) 6= (a), we have e(j) 6= e(a) in the post-state and conclude inv dealloc(a, j) is true after the macro.

100 • Case 3: i, j includes b but NOT a

Given i≡ b ∧ j 6≡ a (or equivalently j ≡ b ∧ i 6≡ a), the invariant can be rewritten as:

inv dealloc(b, j) :e(bdealloc)∧ e(jdealloc)∧

b6≡ j =⇒ e(b) 6= e(j)

(6.21)

Because j 6≡ a and only variable a and adealloc are changed so variable j

and jdealloc stay unchanged in post-state.

Since inv dealloc(b, j) was true in the pre-state, we have inv dealloc(b, j) hold true in the post-state.

• Case 4: i, j are both different from a, b

The macro does not change any value of variable i and j , so the invariant inv dealloc(i, j ) still holds.

2

Proof. [Reasoning Array Invariant B

]

We must show ∀i ∈ ARRV ARS • e(idealloc) =⇒ valid(e(i)) holds true in the

post-state.

Let i ∈ ARRV ARS such that e(idealloc) is true in the post-state and we

have to show valid(e(i)). • Case 1: i 6≡ a

We know e(i)6= e(a) because of fresh(a). From inv arr(i) in line 8, we have

∀i ∈ ARRV ARS • e1(idealloc) =⇒ v1(e1(i))

From

4a, we have e(i) = e1(i) because i6≡ a ∧ i 6≡ adealloc.

From

4b, we have valid(e(i)) = v1(e(i)) because e(i)6= e(a)

Therefore, the validity must remain unchanged in the post-state. valid(e(i)) = v1(e(i)) = v1(e1(i))

• Case 2: i ≡ a

inv arr(a) : e(adealloc) =⇒ valid(e(a)) holds true because we have

valid(e(a)) in

4c, which comes from post condition of copy.

2

Reasoning about

5b Show ∀i ∈ V ARS • i 6≡ a ∧ i 6≡ adealloc =⇒ e(i) =

e0(i) is true in the post condition.

Proof. Let i∈ V ARS be a variable such that i 6≡ a and i 6≡ adealloc. We must

show e(i) = e0(i).

From

4a because i6≡ a ∧ i 6≡ adealloc, we have e(i) = e1(i).

From 2

and 3

because i6≡ a ∧ i 6≡ adealloc, we have e0(i) = e1(i).

Therefore, by combining the above conditions i 6≡ a ∧ i 6≡ adealloc, we

conclude e(i) = e0(i).

2

Reasoning about

5c Show ∀d ∈ ADR • d 6= e0(a) ∧ d 6= e(a) =⇒

valid(d) = v0(d) is true in the post condition.

Proof. Let d ∈ ADR be an address such that d 6= e0(a) and d 6= e(a). We

must show valid(d) = v0(d).

From

4b because d6= e(a), we have valid(d) = v1(d).

From 2

and 3

because d6= e0(a), we have v0(d) = v1(d).

Therefore, by combining the above conditions (d 6= e0(a)∧ d 6= e(a)), we

conclude valid(d) = v1(d) = v0(d).

102