Sûreté de la programmation orientée objets ESC/Java 1 Un premier exemple Exemple 1 (Bag) 1 2 3 c l a s s Bag { int [ ] a ; int n; 4 Bag ( i n t [ ] i n p u t ) { n = input . length ; a = new i n t [ n ] ; System . a r r a y c o p y ( input , 0 , a , 0 , n ) ; } 5 6 7 8 9 10 i n t extractMin ( ) { i n t m = I n t e g e r .MAX_VALUE; i n t mindex = 0 ; f o r ( i n t i = 1 ; i <= n ; i ++) { i f ( a [ i ] < m) { mindex = i ; m = a[ i ]; } } n−−; a [ mindex ] = a [ n ] ; r e t u r n m; } 11 12 13 14 15 16 17 18 19 20 21 22 23 24 } Erreurs : Bag.java:6: Warning: Possible null dereference (Null) n = input.length; ^ Bag.java:15: Warning: Possible null dereference (Null) if (a[i] < m) { ^ 1 (NFP101) Bag.java:15: Warning: Array index possibly too large (IndexTooBig) if (a[i] < m) { ^ Bag.java:21: Warning: Possible null dereference (Null) a[mindex] = a[n]; ^ Bag.java:21: Warning: Possible negative array index (IndexNegative) a[mindex] = a[n]; ^ 5 warnings Corrections : Exemple 2 (1er warning) Bag.java:6: Warning: Possible null dereference (Null) n = input.length; ^ 1 2 3 //@ r e q u i r e s i n p u t != n u l l ; Bag ( i n t [ ] i n p u t ) { n = input . length ; Exemple 3 (2ème warning) Bag.java:15: Warning: Possible null dereference (Null) if (a[i] < m) { ^ 1 2 c l a s s Bag { /∗@ non_null ∗/ i n t [ ] a ; Exemple 4 (3ème warning) Bag.java:15: Warning: Array index possibly too large (IndexTooBig) if (a[i] < m) { ^ 1 f o r ( i n t i = 0 ; i < n ; i ++) { Exemple 5 (4ème warning) Bag.java:21: Warning: Possible null dereference (Null) a[mindex] = a[n]; ^ 2 Déjà traité (voir le 2ème warning). Exemple 6 (5ème warning) Bag.java:21: Warning: Possible negative array index (IndexNegative) a[mindex] = a[n]; ^ 1 2 //@ r e q u i r e s n >= 1 ; i n t extractMin ( ) { Nouveau programme : Exemple 7 (Bag) 1 2 3 c l a s s Bag { /∗@ non_null ∗/ i n t [ ] a ; int n; 4 //@ r e q u i r e s i n p u t != n u l l ; Bag ( i n t [ ] i n p u t ) { n = input . length ; a = new i n t [ n ] ; System . a r r a y c o p y ( input , 0 , a , 0 , n ) ; } 5 6 7 8 9 10 11 //@ r e q u i r e s n >= 1 ; i n t extractMin ( ) { i n t m = I n t e g e r .MAX_VALUE; i n t mindex = 0 ; f o r ( i n t i = 0 ; i < n ; i ++) { i f ( a [ i ] < m) { mindex = i ; m = a[ i ]; } } n−−; a [ mindex ] = a [ n ] ; r e t u r n m; } 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 } Erreur : Bag.java:17: Warning: Array index possibly too large (IndexTooBig) if (a[i] < m) { ^ 3 Correction : Exemple 8 (Bag) 1 2 3 4 class /∗@ int //@ Bag { non_null ∗/ i n t [ ] a ; n; i n v a r i a n t 0 <= n & n <= a . l e n g t h ; Programme final : Exemple 9 (Bag) 1 2 3 4 class /∗@ int //@ Bag { non_null ∗/ i n t [ ] a ; n; i n v a r i a n t 0 <= n && n <= a . l e n g t h ; 5 //@ r e q u i r e s i n p u t != n u l l ; Bag ( i n t [ ] i n p u t ) { n = input . length ; a = new i n t [ n ] ; System . a r r a y c o p y ( input , 0 , a , 0 , n ) ; } 6 7 8 9 10 11 12 //@ r e q u i r e s n >= 1 ; i n t extractMin ( ) { i n t m = I n t e g e r .MAX_VALUE; i n t mindex = 0 ; f o r ( i n t i = 0 ; i < n ; i ++) { i f ( a [ i ] < m) { mindex = i ; m = a[ i ]; } } n−−; a [ mindex ] = a [ n ] ; r e t u r n m; } 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 } 2 Limitations Exemple 10 (Cohérence) 1 2 3 4 char c ; /∗@ assume s != n u l l && ! s . e q u a l s ( " " ) ; @∗/ c = s . charAt ( 0 ) ; /∗@ a s s e r t c = s . charAt ( 0 ) ; @∗/ 4 1 2 3 4 Object o = n u l l ; /∗@ assume o != n u l l ; @∗/ Object [ ] a = new S t r i n g [ − 5 ] ; a [ −3] = new I n t e g e r ( 2 ) ; > escjava2 -q AssumeFalseTest.java 0 warnings Exemple 11 (Non correction) 1 2 3 4 i n t a [ ] = new i n t [ 6 ] ; f o r ( i n t i = 0 ; i <= 6 ; i ++) { a[ i ] = i ; } > escjava2 -q Test.java 0 warnings > escjava2 -Loop 7 -q Test.java Test.java:15: Warning: Array index possibly too large (IndexTooBig) a[i] = i; ^ 1 warning Exemple 12 (Incomplétude) 1 2 3 4 5 6 /∗@ r e q u i r e s i == 5 && j== 3 ; @ e n s u r e s \ r e s u l t == 1 5 ; @∗/ i n t m( i n t i , i n t j ) { return i ∗ j ; } Test.java:19: Warning: Postcondition possibly not established (Post) } ^ Associated declaration is "Test.java", line 14, col 8: @ ensures \result == 15; 1 2 3 4 i n t m( i n t i , i n t j ) { /∗@ assume 15 == 5 ∗ 3 ; @∗/ return i ∗ j ; } 5