Analysis of Software Artifacts

Similar documents
Checking Program Properties with ESC/Java

Hoare Logic: Proving Programs Correct

Static program checking and verification

Extended Static Checking for Java

ESC/Java2 vs. JMLForge. Juan Pablo Galeotti, Alessandra Gorla, Andreas Rau Saarland University, Germany

Introduction to JML David Cok, Joe Kiniry, and Erik Poll Eastman Kodak Company, University College Dublin, and Radboud University Nijmegen

FAKULTÄT FÜR INFORMATIK

Advances in Programming Languages

Advances in Programming Languages

Program Verification (6EC version only)

ESC/Java extended static checking for Java Erik Poll, Joe Kiniry, David Cok University of Nijmegen; Eastman Kodak Company

Lecture Notes: Hoare Logic

Advances in Programming Languages

Advances in Programming Languages

ESC/Java2 extended static checking for Java Erik Poll Radboud University Nijmegen

Lecture 10 Notes Linked Lists

Specification tips and pitfalls

Lecture 10 Notes Linked Lists

6. Hoare Logic and Weakest Preconditions

JML Class Specifications The Java Modeling Language (Part 2) A Java Class

Java Modelling Language (JML) References

Java Modeling Language (JML)

ESC/Java2 Warnings David Cok, Joe Kiniry, and Erik Poll Eastman Kodak Company, University College Dublin, and Radboud University Nijmegen

The Java Modeling Language (Part 2)

ESC/Java2 Use and Features

ESC/Java2 Use and Features

JML. Outline. Métodos Formais em Engenharia de Software. MI, Braga these slides were prepared by adopting/adapting teaching material

JML tool-supported specification for Java Erik Poll Radboud University Nijmegen

Programming with Contracts. Juan Pablo Galeotti, Alessandra Gorla Saarland University, Germany

ESC/Java2 Use and Features David Cok, Joe Kiniry, Erik Poll Eastman Kodak Company, University College Dublin, and Radboud University Nijmegen

Lecture 1 Contracts. 1 A Mysterious Program : Principles of Imperative Computation (Spring 2018) Frank Pfenning

Assertions & Design-by-Contract using JML Erik Poll University of Nijmegen

An Annotated Language

Reachability Analysis for Annotated Code

Verifying JML specifications with model fields

The Java Modeling Language JML

CS 112 Introduction to Computing II. Wayne Snyder Computer Science Department Boston University

Lecture 1 Contracts : Principles of Imperative Computation (Fall 2018) Frank Pfenning

Program Verification. Aarti Gupta

Reasoning about Object Structures Using Ownership

References: internet notes; Bertrand Meyer, Object-Oriented Software Construction; 10/14/2004 1

Overview The Java Modeling Language (Part 1) Related Work

Static Analysis in Practice

III. Check if the divisors add up to the number. Now we may consider each of these tasks separately, assuming the others will be taken care of

CnC: Check n Crash. Combining static checking and testing. Christoph Csallner and Yannis Smaragdakis

Assertions, pre/postconditions

Lecture Notes on Memory Layout

Testing Library Specifications by Verifying Conformance Tests

Part II. Hoare Logic and Program Verification. Why specify programs? Specification and Verification. Code Verification. Why verify programs?

Advanced JML. and more tips and pitfalls. David Cok, Joe Kiniry, and Erik Poll

SRC Technical Note. ESC/Java User's Manual

Verifying Java Programs Verifying Java Programs with KeY

Principles of Software Construction: Objects, Design, and Concurrency (Part 2: Designing (Sub )Systems)

Midterm I Exam Principles of Imperative Computation Frank Pfenning. February 17, 2011

The Pointer Assertion Logic Engine

Verification Condition Generation

CS 161 Computer Security

Runtime Checking for Program Verification Systems

Korat: Automated Testing Based on Java Predicates. Jeff Stuckman

Verification of Object-Oriented Programs with Invariants

Lecture Notes on Linear Search

Overview. Verification with Functions and Pointers. IMP with assertions and assumptions. Proof rules for Assert and Assume. IMP+: IMP with functions

The Java Modeling Language (Part 1)

15-122: Principles of Imperative Computation (Section G)

Lecture 10 Design by Contract

Hoare logic. A proof system for separation logic. Introduction. Separation logic

Processor. Lecture #2 Number Rep & Intro to C classic components of all computers Control Datapath Memory Input Output

CSCE 548 Building Secure Software Software Analysis Basics

Lecture Notes on Ints

Lecture 18 Restoring Invariants

JPred-P 2. Josh Choi, Michael Welch {joshchoi,

Hardware versus software

CS 315 Software Design Homework 3 Preconditions, Postconditions, Invariants Due: Sept. 29, 11:30 PM

Lecture Notes on Queues

Lecture 3 Notes Arrays

Lecture Notes on Queues

COMP 507: Computer-Aided Program Design

Code verification. CSE 331 University of Washington. Michael Ernst

Static Analysis in Practice

Representation Invariants and Abstraction Functions

CSE 331 Midterm Exam 2/13/12

Symbolic Execution and Proof of Properties

The VeriFast Program Verifier: A Tutorial

We would like guidance on how to write our programs beyond simply knowing correlations between inputs and outputs.

Spark verification features

CSE 331 Midterm Exam Sample Solution 2/13/12

Testing, Debugging, and Verification

Automatic Generation of Program Specifications

Verifying Java Programs Verifying Java Programs with KeY

Midterm 1 Solutions Principles of Imperative Computation. Thursday 6 th October, 2016

CSE331 Spring 2015, Final Examination June 8, 2015

Lecture Notes on Contracts

Outline. iterator review iterator implementation the Java foreach statement testing

CSC 1052 Algorithms & Data Structures II: Recursion

Formal Specification and Verification

Information Hiding and Visibility in Interface Specifications

Introduction to Axiomatic Semantics

Principles of Software Construction: Objects, Design and Concurrency. Static Analysis. toad Spring 2013

Formale Entwicklung objektorientierter Software

Lecture 10 Linked Lists

Transcription:

Analysis of Software Artifacts Properties with ESC/Java Jonathan Aldrich 1

ESC/Java A checker for Java programs Finds null pointers, array dereferences Checks Hoare logic specifications Expressed in Java Modeling Language (JML) Goal: Find errors Increase confidence in correctness Unlike a Hoare Logic proof, not a guarantee of correctness Developed at DEC/Compaq SRC in the 90s Now open sourced as ESC/Java 2 2

ESC/Java Uses JML Specifications /*@ requires len >= 0 && array!= null && array.length == len; @ @ ensures \result == (\sum int j; 0 <= j && j < len; array[j]); @*/ int total(int array[], int len) { int answer = 0; int i = 0; /*@ loop_invariant answer == (\sum int j; 0 <= j && j < i; array[j]); */ while (i < len) { answer = answer + array[i]; i = i + 1; return answer; 3

Modular Checking with Hoare Logic procedure multiply product := 0; i := 0; Modular checking: verifying one procedure using only the specification of other procedures while i < n do product := add(product, m); i := i + 1; // modifies result int add(int n, int m) return n + m 4

Modular Checking with Hoare Logic procedure multiply product := 0; i := 0; while i < n do product := add(product, m); i := i + 1; { product = m*n // modifies result int add(int n, int m) return n + m 5

Modular Checking with Hoare Logic procedure multiply { n > 0 product := 0; i := 0; while i < n do product := add(product, m); i := i + 1; { product = m*n // modifies result int add(int n, int m) return n + m 6

Modular Checking with Hoare Logic procedure multiply { n > 0 product := 0; i := 0; while i < n do product := add(product, m); i := i + 1; { product = m*n // modifies result int add(int n, int m) return n + m { \result = n+m 7

Modular Checking with Hoare Logic procedure multiply { n > 0 product := 0; i := 0; while i < n do product := add(product, m); i := i + 1; { product = m*n // modifies result int add(int n, int m) { true return n + m { \result = n+m 8

Modular Checking with Hoare Logic procedure multiply { n > 0 product := 0; i := 0; { invariant: product = m*i && 0 i n && n > 0 while i < n do product := add(product, m); i := i + 1; { product = m*n // modifies result int add(int n, int m) { true return n + m { \result = n+m 9

Modular Checking with Hoare Logic procedure multiply { n > 0 product := 0; i := 0; { invariant: product = m*i && 0 i n && n > 0 while i < n do product := add(product, m); i := i + 1; { product = m*n // modifies result int add(int n, int m) { true return n + m { \result = n+m Verification condition for loop: { invariant: product = m*i && 0 i n && n > 0 while i < n do {product = m*i && 0 i n && n > 0 && i < n product := add(product, m); i := i + 1; {product = m*i && 0 i n && n>0 10

Modular Checking with Hoare Logic procedure multiply { n > 0 product := 0; i := 0; { invariant: product = m*i && 0 i n && n > 0 while i < n do product := add(product, m); i := i + 1; { product = m*n // modifies result int add(int n, int m) { true return n + m { \result = n+m Verification condition for loop: { invariant: product = m*i && 0 i n && n > 0 while i < n do {product = m*i && 0 i n && n > 0 && i < n product := add(product, m); {product = m*(i+1) && 0 i+1 n && n>0 i := i + 1; {product = m*i && 0 i n && n>0 11

Modular Checking with Hoare Logic procedure multiply { n > 0 product := 0; i := 0; { invariant: product = m*i && 0 i n && n > 0 while i < n do product := add(product, m); i := i + 1; { product = m*n // modifies result int add(int n, int m) { true return n + m { \result = n+m Verification condition for loop: { invariant: product = m*i && 0 i n && n > 0 while i < n do {product = m*i && 0 i n && n > 0 && i < n {add(product,m)=m*(i+1)&&0 i+1 n&&n>0 product := add(product, m); {product = m*(i+1) && 0 i+1 n && n>0 i := i + 1; {product = m*i && 0 i n && n>0 12

Modular Checking with Hoare Logic procedure multiply { n > 0 product := 0; i := 0; { invariant: product = m*i && 0 i n && n > 0 while i < n do product := add(product, m); i := i + 1; { product = m*n // modifies result int add(int n, int m) { true return n + m { \result = n+m Verification condition for loop: { invariant: product = m*i && 0 i n && n > 0 while i < n do {product = m*i && 0 i n && n > 0 && i < n {product+m = m*(i+1) && 0 i+1 n && n>0 {add(product,m)=m*(i+1)&&0 i+1 n&&n>0 product := add(product, m); {product = m*(i+1) && 0 i+1 n && n>0 i := i + 1; {product = m*i && 0 i n && n>0 13

Multiply in ESC/Java (1) class Multiply { int multiply(int m, int n) { int product = 0; int i = 0; while (i < n) { product = add(product, m); i = i + 1; return product; int add(int n, int m) { return n+m; 14

Multiply in ESC/Java (1) class Multiply { //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; Start with postcondition while (i < n) { product = add(product, m); i = i + 1; return product; int add(int n, int m) { return n+m; 15

Multiply in ESC/Java (2) 16

Multiply in ESC/Java (2) 17

Multiply in ESC/Java (2) 18

Multiply in ESC/Java (2) 19

Multiply in ESC/Java (3) class Multiply { //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; while (i < n) { product = add(product, m); i = i + 1; return product; int add(int n, int m) { return n+m; 20

Multiply in ESC/Java (3) class Multiply { //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; while (i < n) { product = add(product, m); i = i + 1; return product; Error occurs when we skip the loop, so n <= i int add(int n, int m) { return n+m; 21

Multiply in ESC/Java (3) class Multiply { //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; while (i < n) { product = add(product, m); i = i + 1; return product; Error occurs when we skip the loop, so n <= i But code is correct if n = i int add(int n, int m) { return n+m; 22

Multiply in ESC/Java (3) class Multiply { //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; while (i < n) { product = add(product, m); i = i + 1; return product; Error occurs when we skip the loop, so n <= i But code is correct if n = i Error comes if n < i int add(int n, int m) { return n+m; 23

Multiply in ESC/Java (3) class Multiply { //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; while (i < n) { product = add(product, m); i = i + 1; return product; int add(int n, int m) { return n+m; Error occurs when we skip the loop, so n <= i But code is correct if n = i Error comes if n < i But this should be illegal! 24

Multiply in ESC/Java (3) class Multiply { //@ requires n > 0 //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; while (i < n) { product = add(product, m); i = i + 1; return product; Add precondition Error occurs when we skip the loop, so n <= i But code is correct if n = i Error comes if n < i int add(int n, int m) { return n+m; But this should be illegal! 25

Multiply in ESC/Java (4) Multiply: multiply(int, int)... ------------------------------------------------------------------------ Multiply.java:12: Warning: Postcondition possibly not established Associated declaration is "Multiply.java", line 2, col 8: //@ ensures \result == m*n; Execution trace information: Reached top of loop after 0 iterations in "Multiply.java", line 7, col 1. Reached top of loop after 1 iteration in "Multiply.java", line 7, col 1. Executed return in "Multiply.java", line 11, col 1. 26

Multiply in ESC/Java (4) Multiply: multiply(int, int)... ------------------------------------------------------------------------ Multiply.java:12: Warning: Postcondition possibly not established Associated declaration is "Multiply.java", line 2, col 8: //@ ensures \result == m*n; Execution trace information: Reached top of loop after 0 iterations in "Multiply.java", line 7, col 1. Reached top of loop after 1 iteration in "Multiply.java", line 7, col1. Executed return in "Multiply.java", line 11, col 1. Unclear what causes this problem. However, it s in a loop, so adding a loop invariant may help 27

Multiply in ESC/Java (5) class Multiply { //@ requires n > 0 //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; while (i < n) { product = add(product, m); i = i + 1; return product; int add(int n, int m) { return n+m; 28

Multiply in ESC/Java (5) class Multiply { //@ requires n > 0 //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; //@ loop_invariant product==m*i && i>=0 && i<=n && n>0; while (i < n) { product = add(product, m); i = i + 1; return product; int add(int n, int m) { return n+m; 29

Multiply in ESC/Java (6) class Multiply { //@ requires n > 0 //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; //@ loop_invariant product==m*i && i>=0 && i<=n && n>0; while (i < n) { product = add(product, m); i = i + 1; return product; Now ESC/Java complains that the loop invariant may not hold after the first loop iteration. int add(int n, int m) { return n+m; 30

Multiply in ESC/Java (6) class Multiply { //@ requires n > 0 //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; //@ loop_invariant product==m*i && i>=0 && i<=n && n>0; while (i < n) { product = add(product, m); i = i + 1; return product; Now ESC/Java complains that the loop invariant may not hold after the first loop iteration. int add(int n, int m) { return n+m; We notice that add was unspecified and we add a postcondition 31

Multiply in ESC/Java (6) class Multiply { //@ requires n > 0 //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; //@ loop_invariant product==m*i && i>=0 && i<=n && n>0; while (i < n) { product = add(product, m); i = i + 1; return product; //@ ensures \result == n + m; int add(int n, int m) { return n+m; Now ESC/Java complains that the loop invariant may not hold after the first loop iteration. We notice that add was unspecified and we add a postcondition 32

Multiply in ESC/Java (6) class Multiply { //@ requires n > 0 //@ ensures \result == m*n; int multiply(int m, int n) { int product = 0; int i = 0; //@ loop_invariant product==m*i && i>=0 && i<=n && n>0; while (i < n) { product = add(product, m); i = i + 1; return product; //@ ensures \result == n + m; int add(int n, int m) { return n+m; Now ESC/Java complains that the loop invariant may not hold after the first loop iteration. We notice that add was unspecified and we add a postcondition ESC/Java report success! 33

Check Your Understanding Consider the following function: intsubtract(intx, inty) { returnx + y; This code clearly does not correctly implement subtraction. However, if you run ESC/Java on it, you will not get any errors. Why not? 34

Specifying Classes public class SimpleSet{ intcontents[]; int size; SimpleSet(int capacity) { Define a SimpleSet class constructor add, contains methods, etc. Representation: sorted array add inserts the element in place contains uses binary search How can we ensure the array is sorted when contains is called? booleanadd(inti) { booleancontains(inti) { 35

Specifying Classes public class SimpleSet{ intcontents[]; int size; //@ ensures sorted(contents); SimpleSet(int capacity) { //@ requires sorted(contents); //@ ensures sorted(contents); booleanadd(inti) { //@ requires sorted(contents); //@ ensures sorted(contents); booleancontains(inti) { Define a SimpleSet class constructor add, contains methods, etc. Representation: sorted array add inserts the element in place contains uses binary search How can we ensure the array is sorted when contains is called? One solution: preconditions and postconditions everywhere Is this a good solution? 36

Data Invariants Data Invariant A predicate that is true on every entry and exit of ADT functions Not usually part of public specification On function entry, you can count on the invariant because the last function left the data in a good state Must verify that all ADT functions preserve invariant Does not have to be true in middle of function May violate invariant temporarily while updating state Motivation Reduces duplication in pre-/post-conditions e.g. sorted(s) Hides representation decision from clients Why should public spec say the array is sorted? That s an internal decision that shouldn t affect clients if it were to change. 37

SimpleSet in ESC/Java (1) public class SimpleSet{ intcontents[]; int size; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; boolean contains(int i) { for (intj = 0; j < size; ++j) if (contents[j] == i) { return true; return false; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; 38

SimpleSet in ESC/Java (1) public class SimpleSet{ intcontents[]; int size; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; boolean contains(int i) { for (intj = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:6: Warning: Possible attempt to allocate array of negative length contents = new int[capacity]; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; 39

SimpleSet in ESC/Java (1) public class SimpleSet{ intcontents[]; int size; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; boolean contains(int i) { for (intj = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:6: Warning: Possible attempt to allocate array of negative length contents = new int[capacity]; Need to add precondition 40

SimpleSet in ESC/Java (1) public class SimpleSet{ intcontents[]; int size; //@ requires capacity >= 0; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; boolean contains(int i) { for (intj = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:6: Warning: Possible attempt to allocate array of negative length contents = new int[capacity]; Need to add precondition 41

SimpleSet in ESC/Java (2) public class SimpleSet{ intcontents[]; int size; //@ requires capacity >= 0; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; boolean contains(int i) { for (intj = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:14: Warning: Possible null dereference (Null) contents[size++]=i; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; 42

SimpleSet in ESC/Java (2) public class SimpleSet{ intcontents[]; int size; //@ requires capacity >= 0; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; boolean contains(int i) { for (intj = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:14: Warning: Possible null dereference (Null) contents[size++]=i; Need to add data invariant 43

SimpleSet in ESC/Java (2) public class SimpleSet{ //@ non_null intcontents[]; int size; //@ requires capacity >= 0; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; boolean contains(int i) { for (intj = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:14: Warning: Possible null dereference (Null) contents[size++]=i; Need to add data invariant 44

SimpleSet in ESC/Java (3) public class SimpleSet{ //@ non_null intcontents[]; int size; //@ requires capacity >= 0; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; boolean contains(int i) { for (intj = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:15: Warning: Possible negative array index contents[size++]=i; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; 45

SimpleSet in ESC/Java (3) public class SimpleSet{ //@ non_null intcontents[]; int size; //@ requires capacity >= 0; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; boolean contains(int i) { for (intj = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:15: Warning: Possible negative array index contents[size++]=i; Need to add data invariant 46

SimpleSet in ESC/Java (3) public class SimpleSet{ //@ non_null intcontents[]; int size; //@ invariant size >= 0; //@ requires capacity >= 0; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; boolean contains(int i) { for (intj = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:15: Warning: Possible negative array index contents[size++]=i; Need to add data invariant 47

SimpleSet in ESC/Java (4) public class SimpleSet{ //@ non_null intcontents[]; int size; //@ invariant size >= 0; //@ requires capacity >= 0; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; boolean contains(int i) { for (intj = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:17: Warning: Array index possibly too large contents[size++]=i; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; 48

SimpleSet in ESC/Java (4) public class SimpleSet{ //@ non_null intcontents[]; int size; //@ invariant size >= 0; //@ requires capacity >= 0; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; boolean contains(int i) { for (int j = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:17: Warning: Array index possibly too large contents[size++]=i; Need to add data invariant and precondition 49

SimpleSet in ESC/Java (4) public class SimpleSet{ //@ non_null intcontents[]; int size; //@ invariant size >= 0; //@ invariant size <= contents.length; //@ requires capacity >= 0; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; //@ requires size < contents.length; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; boolean contains(int i) { for (int j = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:17: Warning: Array index possibly too large contents[size++]=i; Need to add data invariant and precondition 50

SimpleSet in ESC/Java (4) public class SimpleSet{ //@ non_null intcontents[]; int size; //@ invariant size >= 0; //@ invariant size <= contents.length; //@ requires capacity >= 0; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; //@ requires size < contents.length; boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; boolean contains(int i) { for (int j = 0; j < size; ++j) if (contents[j] == i) { return true; return false; SimpleSet.java:17: Warning: Array index possibly too large contents[size++]=i; Need to add data invariant and precondition No more warnings for SimpleSet implementation 51

Adding Test Cases for SimpleSet class SimpleSetDriver{ void testconstructor() { SimpleSet s = new SimpleSet(2); //@ assert!s.contains(5); assert encodes tests ESC/Java tries to prove assert will not fail void testadd() { SimpleSet s = new SimpleSet(2); s.add(5); //@ assert!s.contains(4); //@ assert s.contains(5); s.add(4); //@ assert s.contains(4); s.add(4); 52

Adding Test Cases for SimpleSet class SimpleSetDriver{ void testconstructor() { SimpleSet s = new SimpleSet(2); //@ assert!s.contains(5); void testadd() { SimpleSet s = new SimpleSet(2); s.add(5); //@ assert!s.contains(4); //@ assert s.contains(5); s.add(4); //@ assert s.contains(4); s.add(4); assert encodes tests ESC/Java tries to prove assert will not fail Constructor New object doesn t contain a sample element 53

Adding Test Cases for SimpleSet class SimpleSetDriver{ void testconstructor() { SimpleSet s = new SimpleSet(2); //@ assert!s.contains(5); void testadd() { SimpleSet s = new SimpleSet(2); s.add(5); //@ assert!s.contains(4); //@ assert s.contains(5); s.add(4); //@ assert s.contains(4); s.add(4); assert encodes tests ESC/Java tries to prove assert will not fail Constructor New object doesn t contain a sample element Add Adds the relevant element, not others Can call add multiple times on an element, and it s only added once 54

SimpleSet in ESC/Java (5) public class SimpleSet { //@ non_null int contents[]; int size; //@ invariant size >= 0; //@ invariant size <= contents.length; //@ requires capacity >= 0; //@ ensures contents.length == capacity; //@ ensures size == 0; SimpleSet(int capacity) { contents = new int[capacity]; size = 0; 55

SimpleSet in ESC/Java (6) //@ requires size < contents.length contains(i); //@ ensures \result == (size == \old(size+1)); //@ ensures!\result == (size == \old(size)); //@ ensures (\forallintj; (0 <= j && j < \old(size)) ==> contents[j] == \old(contents[j])); //@ ensures contains(i); boolean add(int i) { if (contains(i)) return false; contents[size++]=i; return true; 56

SimpleSet in ESC/Java (7) //@ ensures \result == (\exists intj; 0 <= j && j < size && contents[j]==i); boolean contains(int i) { for (intj = 0; j < size; ++j) if (contents[j] == i) { return true; return false; 57

Check Your Understanding Consider the following function: void getf(fholder fholder) { return fholder.f; ESC/Java will give an error of the form Warning: Possible null dereference (Null). What is the best way to eliminate this warning? 58

ESC/Java s Limitations Does not check for some errors Infinite loops, arithmetic overflow Functional properties not stated by user Non-functional properties 59

ESC/Java s Limitations Does not check for some errors Infinite loops, arithmetic overflow Functional properties not stated by user Non-functional properties Unsound: may miss some errors Only checks one iteration of loops @modifies is unchecked Assumptions about invariants in referred-to objects Several others as well! 60

Loops in ESC/Java The loop: //@ loop_invariant E; while (B) { S Is treated as: //@ assert E; if (B) { S //@ assert E; //@ assume!b; Can optionally increase # iterations with -loop n 61

ESC/Java s Limitations (con t) May report false positives Often can be solved with an extra precondition or invariant Spurious warnings can also be disabled 62

ESC/Java Tradeoffs Attempts to automate Hoare-logic style checking Benefits Drawbacks Applicability 63

ESC/Java Tradeoffs Attempts to automate Hoare-logic style checking Benefits Easier than manual proof Drawbacks Unsound Still quite labor-intensive Applicability Checking of critical code When it s worth the extra effort to get it right When you can t do a complete Hoare-logic proof Still must use other techniques ESC/Java is unsound The spec must also be validated! 64

Session Summary Tools such as ESC/Java can make Hoare Logic-style checking much more practical Reduces effort relative to proof by hand Still considerable work in writing specifications and invariants Can be useful in documenting code and finding errors The tool may miss some defects 65

Further Reading Cormac Flanagan, K. Runstan M. Leino, Mark Lillibridge, Greg Nelson, James B. Saxe, and Raymie Stata. Extended Static Checking for Java. Proc. Programming Language Design and Implementation, June 2002. 66