package org.jmlspecs.openjmltest.testcases; import static org.junit.Assert.fail; import org.jmlspecs.openjmltest.RacBase; import org.junit.Ignore; import org.junit.Test; /** These tests exercise the RAC checking. They compile a test class * using RAC and then execute the resulting program, catching that * programs output. All the tests here have valid JML - they are testing * whether the RAC translations work correctly. * @author David R. Cok * */ public class racnew extends RacBase { /** Sets the classpath used for these tests. The bin in the classpath * brings in the currently compiled runtime classes (so we don't have * to build jmlruntime.jar) */ String[] ordrac = new String[]{jdk, "-ea", "-classpath","bin"+z+"../OpenJML/bin-runtime"+z+"testdata",null}; @Override public void setUp() throws Exception { testspecpath1 = "$A"+z+"$B"; rac = ordrac; jdkrac = false; //noCollectDiagnostics = true; print = true; super.setUp(); //main.addOptions("-verboseness=4"); expectedNotes = 0; main.addOptions("-jmltesting"); } /** Basic Hello World test, with no RAC tests triggered */ @Test public void testJava() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { System.out.println(\"HELLO WORLD\"); }}" ,"HELLO WORLD" ); } /** Basic Hello World test, with no RAC tests triggered */ @Test public void testJavaExit() { expectedRACExit = 5; helpTCX("tt.TestJavaExit","package tt; public class TestJavaExit { public static void main(String[] args) { System.exit(5); }}" ); } /** Basic Hello World test, with no RAC tests triggered */ @Test public void testJavaNull() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { }}" ); } /** Simple test of output from a JML set statement */ @Test public void testJML() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { //@ ghost int i = 0; \n //@ set i = 1; \n //@ set System.out.println(i); \n System.out.println(\"END\"); }}" ,"1" ,"END" ); } /** JML assert statement failure */ @Test public void testAssertion() { helpTCX("tt.TestAssert","package tt; public class TestAssert { public static void main(String[] args) { \n//@ assert false; \n System.out.println(\"END\"); }}" ,"/tt/TestAssert.java:2: JML assertion is false" ,"END" ); } /** JML labeled assert statement failure */ @Test public void testAssertion2() { helpTCX("tt.TestAssert","package tt; public class TestAssert { public static void main(String[] args) { \n//@ assert false: \"ABC\"; \n System.out.println(\"END\"); }}" ,"ABC" ,"END" ); } /** Tests that an optional argument on a JML assert is converted to a String and is what is printed as an error message */ @Test public void testAssertion3() { helpTCX("tt.TestAssert","package tt; public class TestAssert { public static void main(String[] args) { //@ assert false: args.length; \n System.out.println(\"END\"); }}" ,"0" ,"END" ); } /** Tests that an optional argument on a JML assert is converted to a String and is what is printed as an error message */ @Test public void testAssertion3a() { helpTCX("tt.TestAssert","package tt; public class TestAssert { public static void main(String[] args) { //@ assert true: args.length; \n System.out.println(\"END\"); }}" ,"END" ); } /** Assumption failure */ @Test public void testAssumption() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { //@ assume false; \n System.out.println(\"END\"); }}" ,"/tt/TestJava.java:1: JML assumption is false" ,"END" ); } /** Labeled assumption failure */ @Test public void testAssumption2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { //@ assume false: \"DEF\"; \n System.out.println(\"END\"); }}" ,"DEF" ,"END" ); } /** Failed unreachable statement */ @Test public void testUnreachable() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { //@ unreachable; \n System.out.println(\"END\"); }}" ,"/tt/TestJava.java:1: JML unreachable statement reached" ,"END" ); } /** Successful precondition */ @Test public void testPrecondition() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { m(0); System.out.println(\"END\"); }\n" + " /*@ requires i == 0; */ static void m(int i) {} " + "}" ,"END" ); } /** Failed precondition */ @Test public void testPrecondition2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { m(0); System.out.println(\"END\"); }\n" + " /*@ requires i != 0; */ \n" + " static public void m(int i) {} " + "}" ,"/tt/TestJava.java:1: JML precondition is false" ,"/tt/TestJava.java:2: Associated declaration" ,"/tt/TestJava.java:2: JML precondition is false" ,"END" ); } /** Failed precondition */ @Test public void testPrecondition3() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m(1); \n" + " m(-1); \n" + " m(0); \n" + " System.out.println(\"END\"); }\n" + " /*@ requires i > 0; */ \n" + " /*@ requires i < 0; */ \n" + " static public void m(int i) {} " + "}" ,"/tt/TestJava.java:2: JML precondition is false" ,"/tt/TestJava.java:6: Associated declaration" ,"/tt/TestJava.java:6: JML precondition is false" ,"/tt/TestJava.java:3: JML precondition is false" ,"/tt/TestJava.java:6: Associated declaration" ,"/tt/TestJava.java:6: JML precondition is false" ,"/tt/TestJava.java:4: JML precondition is false" ,"/tt/TestJava.java:6: Associated declaration" ,"/tt/TestJava.java:6: JML precondition is false" ,"END" ); } /** Failed precondition with nowarn */ @Test public void testPrecondition2NoWarn() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(0); //@ nowarn Precondition;\n" + "System.out.println(\"END\"); }\n" + " /*@ requires i != 0; */ //@ nowarn Precondition;\n" + " static void m(int i) {} \n" + "}" ,"END" ); } @Test public void testNonnullPrecondition() { main.addOptions("-racShowSource=true"); helpTCX("tt.TestJava","package tt; public class TestJava { \n" + "public static void main(String[] args) { \n" + " m(null,1); \n" + " System.out.println(\"END\"); }\n" + " /*@ requires true; */ \n" + " static public void m(/*@non_null*/ Object o, int i) {\n" + " }\n" + "}" ,"/tt/TestJava.java:3: JML precondition is false" ," m(null,1); " ," ^" ,"/tt/TestJava.java:6: Associated declaration" ," static public void m(/*@non_null*/ Object o, int i) {" ," ^" ,"/tt/TestJava.java:5: JML precondition is false" ," /*@ requires true; */ " ," ^" ,"END" ); } @Test public void testNonnullPrecondition2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { m(null,1); System.out.println(\"END\"); }\n" + " static public void m(/*@non_null*/ Object o, int i) {} " + "}" ,"/tt/TestJava.java:1: JML precondition is false" ,"/tt/TestJava.java:2: Associated declaration" ,"/tt/TestJava.java:2: JML precondition is false" ,"END" ); } @Test public void testNonnullPostcondition() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(null,1); \n" + "System.out.println(\"END\"); }\n" + " static public /*@non_null*/Object m( /*@nullable*/Object o, int i)\n" + "{ return null; } " + "}" ,"/tt/TestJava.java:4: JML postcondition is false" ,"/tt/TestJava.java:4: Associated declaration" ,"/tt/TestJava.java:2: JML postcondition is false" ,"/tt/TestJava.java:4: Associated declaration" ,"END" ); } // TODO need multiple requires, multiple spec cases @Test public void testPostcondition() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { m(1); System.out.println(\"END\"); } static int k = 0; \n" + " /*@ ensures k == i; */ static int m(int i) { k = i; return 13; } " + "}" ,"END" ); } @Test public void testPostcondition1() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m(1); System.out.println(\"END\"); } \n" + " static public int k = 0; \n" + " /*@ ensures k == 0; */ \n" + " static public int m(int i) { k = i; return 13; } " + "}" ,"/tt/TestJava.java:5: JML postcondition is false" ,"/tt/TestJava.java:4: Associated declaration" ,"/tt/TestJava.java:2: JML postcondition is false" ,"/tt/TestJava.java:4: Associated declaration" ,"END" ); } @Test public void testPostcondition1Nowarn() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m(1); System.out.println(\"END\"); } /*@ nowarn Postcondition;*/\n" + " static int k = 0; \n" + " /*@ ensures k == 0; */ \n"+ " static int m(int i) { k = i; return 13; }/*@ nowarn Postcondition;*/ " + "}" ,"END" ); } @Test public void testPostcondition2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { m(1); System.out.println(\"END\"); } static int k = 0; \n" + " /*@ requires true; \nalso \nrequires false; \nensures k == 0; */ static void m(int i) { k = i; } " + "}" ,"END" ); } @Test public void testPostcondition3() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { m(1); System.out.println(\"END\"); } static int k = 0; \n" + " /*@ requires true; \nensures true; \nalso \nrequires false; \nensures k == 0; */ static void m(int i) { k = i; } " + "}" ,"END" ); } @Test public void testPostcondition4() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m(1); System.out.println(\"END\"); } \n" + " static public int k = 0; \n" + " /*@ requires true; \n" + " ensures k != i; \n" + " also \n" + " requires true; \n" + " ensures k == 0; */ \n" + " static public void m(int i) { k = i; } " + "}" ,"/tt/TestJava.java:9: JML postcondition is false" ,"/tt/TestJava.java:5: Associated declaration" ,"/tt/TestJava.java:9: JML postcondition is false" ,"/tt/TestJava.java:8: Associated declaration" ,"/tt/TestJava.java:2: JML postcondition is false" ,"/tt/TestJava.java:5: Associated declaration" ,"/tt/TestJava.java:2: JML postcondition is false" ,"/tt/TestJava.java:8: Associated declaration" ,"END" ); } @Test public void testPostcondition5() { expectedRACExit = 1; helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public static void main(String[] args) { \n" +" org.jmlspecs.utils.Utils.useExceptions = true; \n" +" m(1); \n" +" System.out.println(\"END\"); \n" +" } \n" +" static int k = 0; \n" +" /*@ requires true; \n" +" ensures k != i; \n" +" also \n" +" requires true; \n" +" ensures k == 0; */\n" +" static void m(int i) { k = i; } " + "}" ,"Exception in thread \"main\" org.jmlspecs.utils.JmlAssertionError: /tt/TestJava.java:14: JML postcondition is false" ,"/tt/TestJava.java:10: Associated declaration" ,"\tat org.jmlspecs.utils.Utils.createException(Utils.java:99)" ,"\tat org.jmlspecs.utils.Utils.assertionFailureL(Utils.java:52)" ,"\tat tt.TestJava.m(TestJava.java:1)" // FIXME - should be line 14 ,"\tat tt.TestJava.main(TestJava.java:5)" ); } @Test public void testSignals() { helpTCX("tt.TestJava","package tt; public class TestJava {\n" +" public static void main(String[] args) { \n" +" try { m(1); } catch (Exception e) {} System.out.println(\"END\"); \n" +"} \n" +"static int k = 0; \n" +" /*@ requires true; \n" +" signals (java.io.FileNotFoundException e) e == null; */\n" +"static public void m(int i) throws java.io.FileNotFoundException { throw new java.io.FileNotFoundException(); } " +"}" ,"/tt/TestJava.java:8: JML signals condition is false" ,"/tt/TestJava.java:7: Associated declaration" ,"/tt/TestJava.java:3: JML signals condition is false" ,"/tt/TestJava.java:7: Associated declaration" ,"END" ); } @Test public void testSignals2() { helpTCX("tt.TestJava","package tt; public class TestJava {\n" +" public static void main(String[] args) { \n" +" try { m(1); } catch (Exception e) {} System.out.println(\"END\"); \n" +"} \n" +"static public int k = 0; \n" +" /*@ requires true; \nsignals (java.io.FileNotFoundException e) e == null; */\n" +"static public void m(int i) throws Exception, java.io.FileNotFoundException { throw new java.io.FileNotFoundException(); } " +"}" ,"/tt/TestJava.java:8: JML signals condition is false" ,"/tt/TestJava.java:7: Associated declaration" ,"/tt/TestJava.java:3: JML signals condition is false" ,"/tt/TestJava.java:7: Associated declaration" ,"END" ); } @Test public void testSignalsOnly() { helpTCX("tt.TestJava","package tt; public class TestJava {\n" +" public static void main(String[] args) { \n" +" try { m(1); } catch (Exception e) {} System.out.println(\"END\"); \n" +"} \n" +"static int k = 0; \n" +" /*@ requires true; \nsignals_only \\nothing; */\n" +"static public void m(int i) throws Exception, java.io.FileNotFoundException { throw new java.io.FileNotFoundException(); } " +"}" ,"/tt/TestJava.java:8: JML unexpected exception for the signals_only clause: java.io.FileNotFoundException" // check by callee ,"/tt/TestJava.java:7: Associated declaration" ,"/tt/TestJava.java:3: JML unexpected exception for the signals_only clause: java.io.FileNotFoundException" // check of postcondition assumption by caller ,"/tt/TestJava.java:7: Associated declaration" ,"END" ); } @Test public void testSignalsOnly1() { helpTCX("tt.TestJava","package tt; public class TestJava {\n" +" public static void main(String[] args) { \n" +" try { m(1); } catch (Exception e) {} System.out.println(\"END\"); \n" +"} \n" +"static int k = 0; \n" +" /*@ requires true; \nsignals_only java.io.FileNotFoundException; */\n" +"static void m(int i) throws Exception, java.io.FileNotFoundException { throw new java.io.FileNotFoundException(); } " +"}" ,"END" ); } @Test public void testSignalsOnly2() { helpTCX("tt.TestJava","package tt; public class TestJava {\n" +" public static void main(String[] args) { \n" +" try { m(1); } catch (Exception e) {} System.out.println(\"END\"); \n" +"} \n" +"static int k = 0; \n" +" /*@ requires true; \nsignals_only java.io.FileNotFoundException; */\n" +"static void m(int i) throws Exception, java.io.FileNotFoundException { throw new Exception(); } " +"}" ,"/tt/TestJava.java:8: JML unexpected exception for the signals_only clause: java.lang.Exception" ,"/tt/TestJava.java:7: Associated declaration" ,"/tt/TestJava.java:3: JML unexpected exception for the signals_only clause: java.lang.Exception" ,"/tt/TestJava.java:7: Associated declaration" ,"END" ); } @Test public void testSignalsOnlyDefault() { helpTCX("tt.TestJava","package tt; public class TestJava {\n" +" public static void main(String[] args) { \n" +" try { m(1); } catch (Exception e) {} System.out.println(\"END\"); \n" +"} \n" +"static int k = 0; \n" +" /*@ requires true; \n*/\n" +"static void m(int i) throws java.io.FileNotFoundException { throw new RuntimeException(); } " +"}" // ,"/tt/TestJava.java:8: JML unexpected exception for the signals_only clause" // ,"/tt/TestJava.java:8: Associated declaration" // ,"/tt/TestJava.java:3: JML unexpected exception for the signals_only clause" // ,"/tt/TestJava.java:8: Associated declaration" ,"END" ); } @Test public void testSignalsOnlyDefault1() { helpTCX("tt.TestJava","package tt; public class TestJava {\n" +" public static void main(String[] args) { \n" +" try { m(1); } catch (Exception e) {} System.out.println(\"END\"); \n" +"} \n" +"static int k = 0; \n" +" /*@ requires true; \n*/\n" +"static void m(int i) throws java.io.FileNotFoundException { throw new java.io.FileNotFoundException(); } " +"}" ,"END" ); } @Test public void testSignalsOnlyDefault2() { helpTCX("tt.TestJava","package tt; public class TestJava {\n" +" public static void main(String[] args) throws RuntimeException { \n" +" try { m(1); } catch (Exception e) {} System.out.println(\"END\"); \n" +"} \n" +"static int k = 0; \n" +" \n" +"static void m(int i) \n" +" throws java.io.FileNotFoundException \n" +" { throw new RuntimeException(); }\n" +"}" // ,"/tt/TestJava.java:7: JML unexpected exception for the signals_only clause" // ,"/tt/TestJava.java:7: Associated declaration" // ,"/tt/TestJava.java:3: JML unexpected exception for the signals_only clause" // ,"/tt/TestJava.java:7: Associated declaration" ,"END" ); } @Test public void testResult() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { m(1); System.out.println(\"END\"); } static int k = 0; \n" + " /*@ ensures \\result == 4; */ static int m(int i) { return 4; } " + "}" ,"END" ); } @Test public void testResult1() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" +" m(1); \n" +" System.out.println(\"END\"); } \n" +" static int k = 0; \n" +" /*@ ensures \\result == 4; */ \n" +" static public int m(int i) { \n" +" return 5; } " +"}" ,"/tt/TestJava.java:6: JML postcondition is false" ,"/tt/TestJava.java:5: Associated declaration" ,"/tt/TestJava.java:2: JML postcondition is false" ,"/tt/TestJava.java:5: Associated declaration" ,"END" ); } @Test public void testLabel() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { m(1); m(0); System.out.println(\"END\"); } static int k = 0; \n" + " /*@ ensures (\\lbl ENS \\result == 1); */ static public int m(int i) { return i; } " + "}" ,"LABEL ENS = true" ,"LABEL ENS = true" ,"LABEL ENS = false" ,"/tt/TestJava.java:2: JML postcondition is false" ,"/tt/TestJava.java:2: Associated declaration" ,"LABEL ENS = false" ,"/tt/TestJava.java:1: JML postcondition is false" ,"/tt/TestJava.java:2: Associated declaration" ,"END" ); } @Test public void testLabel2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { m(1); m(0); System.out.println(\"END\"); } static int k = 0; \n" + " /*@ ensures (\\lbl ENS (\\lbl RES \\result) == 1); */ static public int m(int i) { return i; } " + "}" ,"LABEL RES = 1" ,"LABEL ENS = true" ,"LABEL RES = 1" ,"LABEL ENS = true" ,"LABEL RES = 0" ,"LABEL ENS = false" ,"/tt/TestJava.java:2: JML postcondition is false" ,"/tt/TestJava.java:2: Associated declaration" ,"LABEL RES = 0" ,"LABEL ENS = false" ,"/tt/TestJava.java:1: JML postcondition is false" ,"/tt/TestJava.java:2: Associated declaration" ,"END" ); } @Test public void testOld() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { m(1); m(0); System.out.println(\"END\"); } static public int k = 0; \n" + " /*@ ensures (\\lbl ENS \\old(k)) == k; */ static public int m(int i) { k=i; return i; } " + "}" ,"LABEL ENS = 0" // k==0 at beginning of m(1) ,"/tt/TestJava.java:2: JML postcondition is false" // postcondition false because k is now 1 ,"/tt/TestJava.java:2: Associated declaration" ,"LABEL ENS = 0" ,"/tt/TestJava.java:1: JML postcondition is false" // caller check, after m(1) ,"/tt/TestJava.java:2: Associated declaration" ,"LABEL ENS = 1" // k==1 at beginning of m(0) ,"/tt/TestJava.java:2: JML postcondition is false" // callee check ,"/tt/TestJava.java:2: Associated declaration" ,"LABEL ENS = 1" ,"/tt/TestJava.java:1: JML postcondition is false" // caller check, after m(0) ,"/tt/TestJava.java:2: Associated declaration" ,"END" ); } @Test public void testOld2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { m(1); m(0); System.out.println(\"END\"); } static int k = 0; \n" + " static int m(int i) { //@ assert (\\lbl AST \\old(k)) == 0; \n k=i; //@ assert (\\lbl AST2 \\old(k)) == 0;\n //@ assert (\\lbl AST3 k) == 0; \n return i; } " + "}" ,"LABEL AST = 0" ,"LABEL AST2 = 0" ,"LABEL AST3 = 1" ,"/tt/TestJava.java:4: JML assertion is false" ,"LABEL AST = 1" ,"/tt/TestJava.java:2: JML assertion is false" ,"LABEL AST2 = 1" ,"/tt/TestJava.java:3: JML assertion is false" ,"LABEL AST3 = 0" ,"END" ); } @Test public void testOld3() { // FIXME - \old at a label not working for RAC helpTCX("tt.TestJava","package tt; public class TestJava { \n" + "public static void main(String[] args) { \n" + " m(1); m(0); \n" + " System.out.println(\"END\"); " + "} \n" + "static int k = 0; \n" + "static int m(int i) { \n" + " //@ ghost int p = (\\lbl AST \\old(k)); \n" + " k=i; \n" + " lab: k = 9+i; \n" + " //@ ghost int kk = (\\lbl AST2 \\old(k));\n " + " //@ set kk = (\\lbl AST3 k); \n " + " //@ set kk = (\\lbl AST4 \\old(k,lab)); \n " + " return i; } " + "}" ,"LABEL AST = 0" // k==0 at beginning of m(1) ,"LABEL AST2 = 0" // k==0 at beginning of m(1) ,"LABEL AST3 = 10" // k currently 10 in m(1) ,"LABEL AST4 = 1" // k was 1 at lab // k is 10 at exit of m(1) ,"LABEL AST = 10" // so k is 10 at beginning of m(0) ,"LABEL AST2 = 10" // k is 10 at beginning of m(0) ,"LABEL AST3 = 9" // k is 9 just after lab ,"LABEL AST4 = 0" // k was 0 (== i) at lab ,"END" ); } @Test public void testInformal() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { m(1); m(0); System.out.println(\"END\"); } static int k = 0; \n" + " static int m(int i) { System.out.println(i); //@ assert (i==0) <==> (* informal *); \n return i; } " + "}" ,"1" ,"/tt/TestJava.java:2: JML assertion is false" ,"0" ,"END" ); } @Test public void testElemtype() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" +"Object o = new String[3]; Object oo = new int[5]; Object o3 = new Integer(4);\n" +"//@ ghost nullable java.lang.Class t; ghost nullable \\TYPE tt; \n" +"//@ set tt = (\\lbl A \\elemtype(\\typeof(o)));\n" +"//@ set tt = (\\lbl B \\elemtype(\\typeof(oo)));\n" +"//@ set tt = (\\lbl C \\elemtype(\\typeof(o3)));\n" +"//@ set t = (\\lbl D \\elemtype(java.lang.Class.class));\n" +"//@ set t = (\\lbl E \\elemtype(java.lang.Boolean[].class));\n" +"System.out.println(\"END\"); } \n" +"}" ,"LABEL A = class java.lang.String" ,"LABEL B = int" ,"LABEL C = null" ,"LABEL D = null" ,"LABEL E = class java.lang.Boolean" ,"END" ); } @Test public void testTypeOfA() { helpTCX("tt.TestJava","package tt; import static org.jmlspecs.lang.JML.*; public class TestJava { public static void main(String[] args) { \n" + "m(new Object()); m(new String()); m(Boolean.TRUE); System.out.println(\"END\"); } \n" + " //@ requires JML.informal(\"asd\") && (\\lbl CLS \\erasure(\\typeof(i))) == Object.class; \n" + " static public void m(/*@nullable*/Object i) { System.out.println(\"CLASS \" + i.getClass()); } " + "}" ,"LABEL CLS = class java.lang.Object" ,"LABEL CLS = class java.lang.Object" ,"CLASS class java.lang.Object" ,"LABEL CLS = class java.lang.String" ,"/tt/TestJava.java:2: JML precondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"LABEL CLS = class java.lang.String" ,"/tt/TestJava.java:3: JML precondition is false" ,"CLASS class java.lang.String" ,"LABEL CLS = class java.lang.Boolean" ,"/tt/TestJava.java:2: JML precondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"LABEL CLS = class java.lang.Boolean" ,"/tt/TestJava.java:3: JML precondition is false" ,"CLASS class java.lang.Boolean" ,"END" ); } @Test public void testTypeOf1() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(new Object[1]); m(new String[2]); System.out.println(\"END\"); } \n" + " //@ requires (\\lbl CLS \\typeof(i)) == \\type(Object); \n" + " static public void m(/*@nullable*/Object i) { System.out.println(\"CLASS \" + i.getClass()); } " + "}" ,"LABEL CLS = class [Ljava.lang.Object;" ,"/tt/TestJava.java:2: JML precondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"LABEL CLS = class [Ljava.lang.Object;" ,"/tt/TestJava.java:3: JML precondition is false" ,"CLASS class [Ljava.lang.Object;" ,"LABEL CLS = class [Ljava.lang.String;" ,"/tt/TestJava.java:2: JML precondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"LABEL CLS = class [Ljava.lang.String;" ,"/tt/TestJava.java:3: JML precondition is false" ,"CLASS class [Ljava.lang.String;" ,"END" ); } @Test public void testTypeOf2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(0); System.out.println(\"END\"); } \n" + " //@ requires (\\lbl CLS \\typeof(i)) == \\type(Object); \n" + " static public void m(int i) { \n" + "//@ assert (\\lbl AST \\typeof(true)) == \\typeof(true); \n" + "//@ assert (\\lbl AST2 \\typeof((short)0)) != \\typeof(true); \n" + "//@ assert (\\lbl AST3 \\typeof((long)0)) != \\typeof(true); \n" + "//@ assert (\\lbl AST4 \\typeof((byte)0)) != \\typeof(true); \n" + "//@ assert (\\lbl AST5 \\typeof('c')) != \\typeof(true); \n" + "//@ assert (\\lbl AST6 \\typeof(\"c\")) != \\typeof(true); \n" + "//@ assert (\\lbl AST7 \\typeof((float)0)) != \\typeof(true); \n" + "//@ assert (\\lbl AST8 \\typeof((double)0)) != \\typeof(true); \n" + "} " + "}" ,"LABEL CLS = int" ,"/tt/TestJava.java:2: JML precondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"LABEL CLS = int" ,"/tt/TestJava.java:3: JML precondition is false" ,"LABEL AST = boolean" ,"LABEL AST2 = short" ,"LABEL AST3 = long" ,"LABEL AST4 = byte" ,"LABEL AST5 = char" ,"LABEL AST6 = class java.lang.String" ,"LABEL AST7 = float" ,"LABEL AST8 = double" ,"END" ); } @Test public void testTypeOf3() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(0); System.out.println(\"END\"); } \n" + " static void m(int i) { \n" + "//@ assert (\\lbl AST9 \\typeof(5/0)) == \\typeof(5/0); \n" + "//@ assert (\\lbl AST10 \\typeof(5.0/0.0)) != \\typeof(5/0); \n" + "} " + "}" ,"LABEL AST9 = int" ,"LABEL AST10 = double" ,"END" ); } // FIXME - want typeof to return a JML type with type parameter information @Test public void testTypeOf4() { helpTCX("tt.TestJava","package tt; import java.util.*; public class TestJava { public static void main(String[] args) { \n" + "m(new LinkedList<String>()); m(new LinkedList<Integer>()); m(new HashSet<Integer>()); System.out.println(\"END\"); } \n" + " //@ requires (\\lbl CLS \\typeof(i)) == ( \\type(LinkedList<Integer>) ); \n" + " static public void m(/*@nullable*/Object i) { System.out.println(\"CLASS \" + i.getClass()); } " + "}" ,"LABEL CLS = class java.util.LinkedList" // ,"/tt/TestJava.java:2: JML precondition is false" // ,"/tt/TestJava.java:3: Associated declaration" ,"LABEL CLS = class java.util.LinkedList" // ,"/tt/TestJava.java:3: JML precondition is false" ,"CLASS class java.util.LinkedList" ,"LABEL CLS = class java.util.LinkedList" ,"LABEL CLS = class java.util.LinkedList" ,"CLASS class java.util.LinkedList" ,"LABEL CLS = class java.util.HashSet" ,"/tt/TestJava.java:2: JML precondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"LABEL CLS = class java.util.HashSet" ,"/tt/TestJava.java:3: JML precondition is false" ,"CLASS class java.util.HashSet" ,"END" ); } // FIXME - want typeof to return a JML type with type parameter information @Test public void testTypeOf5() { helpTCX("tt.TestJava","package tt; import java.util.*; public class TestJava { public static void main(String[] args) { \n" + "m(new LinkedList<String>()); m(new LinkedList<Integer>()); m(new HashSet<Integer>()); System.out.println(\"END\"); } \n" + " //@ requires (\\lbl CLS \\typeof(i)) == ( \\type(LinkedList<Integer>) ); \n" + " static public void m(/*@nullable*/Object i) { System.out.println(\"CLASS \" + i.getClass()); } " + "}" ,"LABEL CLS = class java.util.LinkedList" // ,"/tt/TestJava.java:2: JML precondition is false" // ,"/tt/TestJava.java:3: Associated declaration" ,"LABEL CLS = class java.util.LinkedList" // ,"/tt/TestJava.java:3: JML precondition is false" ,"CLASS class java.util.LinkedList" ,"LABEL CLS = class java.util.LinkedList" ,"LABEL CLS = class java.util.LinkedList" ,"CLASS class java.util.LinkedList" ,"LABEL CLS = class java.util.HashSet" ,"/tt/TestJava.java:2: JML precondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"LABEL CLS = class java.util.HashSet" ,"/tt/TestJava.java:3: JML precondition is false" ,"CLASS class java.util.HashSet" ,"END" ); } // FIXME - want typeof to return a JML type with type parameter information @Test public void testTypeOf6() { helpTCX("tt.TestJava","package tt; import java.util.*; public class TestJava { public static void main(String[] args) { \n" + "m(new LinkedList<String>()); m(new HashSet<Integer>()); System.out.println(\"END\"); } \n" + " //@ requires (\\lbl CLS \\typeof(i)) != ( \\type(LinkedList<Integer>) ); \n" + " static public void m(/*@nullable*/Object i) { System.out.println(\"CLASS \" + i.getClass()); } " + "}" ,"LABEL CLS = class java.util.LinkedList" ,"/tt/TestJava.java:2: JML precondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"LABEL CLS = class java.util.LinkedList" ,"/tt/TestJava.java:3: JML precondition is false" ,"CLASS class java.util.LinkedList" ,"LABEL CLS = class java.util.HashSet" ,"LABEL CLS = class java.util.HashSet" ,"CLASS class java.util.HashSet" ,"END" ); } @Test public void testNonnullelement() { expectedRACExit = 1; helpTCX("tt.TestJava","package tt; public class TestJava { static int z = 0; public static void main(String[] args) { \n" + "String[] s2null = new String[]{null,\"B\"}; \n" + "String[] s2 = new String[]{\"A\",\"B\"}; \n" + "m(new Object[]{}); \n" + "m(new String[]{\"A\"}); \n" + "m(s2); \n" + "m(s2null); \n" + "//@ assert \\nonnullelements(s2,s2null); \n" + "//@ assert \\nonnullelements(s2,s2); \n" + // Tests shortcut evaluation - should evaluate all arguments first "//@ assert \\nonnullelements(s2null,new Integer[]{5/z}); \n" + "System.out.println(\"END\"); } \n" + " static void m(Object[] o) { \n" + "//@ assert (\\lbl ELEM \\nonnullelements(o)); \n" + "} " + "}" ,"LABEL ELEM = true" ,"LABEL ELEM = true" ,"LABEL ELEM = true" ,"LABEL ELEM = false" ,"/tt/TestJava.java:13: JML assertion is false" ,"/tt/TestJava.java:8: JML assertion is false" ,"/tt/TestJava.java:10: JML Division by zero" ,"Exception in thread \"main\" java.lang.ArithmeticException: / by zero" ,"\tat tt.TestJava.main(TestJava.java:10)" ); } @Test public void testNonnullelement2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(null); \n" + "System.out.println(\"END\"); } \n" + " static void m(/*@nullable*/Object[] o) { \n" + "//@ assert (\\lbl ELEM \\nonnullelements((\\lbl O o))); \n" + "} " + "}" ,"LABEL O = null" ,"LABEL ELEM = false" ,"/tt/TestJava.java:5: JML assertion is false" ,"END" ); } @Test public void testLbl() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(null); \n" + "System.out.println(\"END\"); } \n" + "static int i = 0; static String n = \"asd\";\n" + " static void m(/*@nullable*/ Object o) { \n" + "//@ assert (\\lbl STRING \"def\") != null; \n" + "++i; //@ assert (\\lbl SHORT (short)(i)) != 0; \n" + "++i; //@ assert (\\lbl LONG (long)(i)) != 0; \n" + "++i; //@ assert (\\lbl BYTE (byte)(i)) != 0; \n" + "++i; //@ assert (\\lbl INT (int)(i)) != 0; \n" + "++i; //@ assert (\\lbl FLOAT (float)(i)) != 0; \n" + "++i; //@ assert (\\lbl DOUBLE (double)(i)) != 0; \n" + "//@ assert (\\lbl CHAR n.charAt(0)) != 0; \n" + "//@ assert (\\lbl BOOLEAN (i == 0)) ; \n" + "//@ assert (\\lbl OBJECT o) == null; \n" + "//@ assert (\\lbl STRING \"abc\") != null; \n" + "} " + "}" ,"LABEL STRING = def" ,"LABEL SHORT = 1" ,"LABEL LONG = 2" ,"LABEL BYTE = 3" ,"LABEL INT = 4" ,"LABEL FLOAT = 5.0" ,"LABEL DOUBLE = 6.0" ,"LABEL CHAR = a" ,"LABEL BOOLEAN = false" ,"/tt/TestJava.java:14: JML assertion is false" ,"LABEL OBJECT = null" ,"LABEL STRING = abc" ,"END" ); } @Test public void testLblConst() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(null); \n" + "System.out.println(\"END\"); } static int i = 0; \n" + " static void m(/*@nullable*/ Object o) { \n" + "//@ assert (\\lbl OBJECT null) == null; \n" + "//@ assert (\\lbl INT (int)(4)) != 0; \n" + "//@ assert (\\lbl SHORT (short)(1)) != 0; \n" + "//@ assert (\\lbl LONG (long)(2)) != 0; \n" + "//@ assert (\\lbl BYTE (byte)(3)) != 0; \n" + "//@ assert (\\lbl FLOAT (float)(5)) != 0; \n" + "//@ assert (\\lbl DOUBLE (double)(6)) != 0; \n" + "//@ assert (\\lbl CHAR 'a') != 0; \n" + "//@ assert (\\lbl BOOLEAN true) ; \n" + "//@ assert (\\lbl STRING \"abc\") != null; \n" + "} " + "}" ,"LABEL OBJECT = null" ,"LABEL INT = 4" ,"LABEL SHORT = 1" ,"LABEL LONG = 2" ,"LABEL BYTE = 3" ,"LABEL FLOAT = 5.0" ,"LABEL DOUBLE = 6.0" ,"LABEL CHAR = a" ,"LABEL BOOLEAN = true" ,"LABEL STRING = abc" ,"END" ); } @Test public void testLblX() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(); mm(); ma(); mg(); \n" + "System.out.println(\"END\"); } \n" + " static void m() { \n" + "//@ ghost \\TYPE c; \n" + "//@ set c = \\type(int); \n" + "//@ set c = (\\lbl TYP1 c); \n" + "//@ set c = \\type(boolean); \n" + "//@ set c = (\\lbl TYP2 c); \n" + "}\n" + " static void mm() { \n" + "//@ ghost \\TYPE c; \n" + "//@ set c = \\type(java.lang.Object); \n" + "//@ set c = (\\lbl TYP1 c); \n" + "//@ set c = \\type(Object); \n" + "//@ set c = (\\lbl TYP2 c); \n" + "//@ set c = \\type(java.lang.String); \n" + "//@ set c = (\\lbl TYP3 c); \n" + "//@ set c = \\type(String); \n" + "//@ set c = (\\lbl TYP4 c); \n" + "}\n" + " static void ma() { \n" + "//@ ghost \\TYPE c; \n" + "//@ set c = \\type(java.lang.String[]); \n" + "//@ set c = (\\lbl TYP1 c); \n" + "//@ set c = \\type(String[]); \n" + "//@ set c = (\\lbl TYP2 c); \n" + "//@ set c = \\type(java.lang.String[][]); \n" + "//@ set c = (\\lbl TYP3 c); \n" + "//@ set c = \\type(String[][]); \n" + "//@ set c = (\\lbl TYP4 c); \n" + "} \n" + " static void mg() { \n" + "//@ ghost \\TYPE c; \n" + "//@ set c = \\type(java.lang.Class<Integer>); \n" + "//@ set c = (\\lbl TYP1 c); \n" + "//@ ghost boolean bbb = (\\lbl TRUE Class.class == \\erasure(\\type(Class))); \n" + "//@ set c = (\\lbl TYP2 c); \n" + "} " + "}" ,"LABEL TYP1 = int" ,"LABEL TYP2 = boolean" ,"LABEL TYP1 = class java.lang.Object" ,"LABEL TYP2 = class java.lang.Object" ,"LABEL TYP3 = class java.lang.String" ,"LABEL TYP4 = class java.lang.String" ,"LABEL TYP1 = class [Ljava.lang.String;" ,"LABEL TYP2 = class [Ljava.lang.String;" ,"LABEL TYP3 = class [[Ljava.lang.String;" ,"LABEL TYP4 = class [[Ljava.lang.String;" ,"LABEL TYP1 = class java.lang.Class<class java.lang.Integer>" ,"LABEL TRUE = true" ,"LABEL TYP2 = class java.lang.Class<class java.lang.Integer>" ,"END" ); } @Test public void testTypelc() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(); mm(); ma(); mg(); \n" + "System.out.println(\"END\"); } \n" + " static void m() { \n" + "//@ ghost \\TYPE c; \n" + "//@ set c = \\type(int); \n" + "//@ set c = (\\lbl TYP1 c); \n" + "//@ set c = \\type(boolean); \n" + "//@ set c = (\\lbl TYP2 c); \n" + "}\n" + " static void mm() { \n" + "//@ ghost \\TYPE c; \n" + "//@ set c = \\type(java.lang.Object); \n" + "//@ set c = (\\lbl TYP1 c); \n" + "//@ set c = \\type(Object); \n" + "//@ set c = (\\lbl TYP2 c); \n" + "//@ set c = \\type(java.lang.String); \n" + "//@ set c = (\\lbl TYP3 c); \n" + "//@ set c = \\type(String); \n" + "//@ set c = (\\lbl TYP4 c); \n" + "}\n" + " static void ma() { \n" + "//@ ghost \\TYPE c; \n" + "//@ set c = \\type(java.lang.String[]); \n" + "//@ set c = (\\lbl TYP1 c); \n" + "//@ set c = \\type(String[]); \n" + "//@ set c = (\\lbl TYP2 c); \n" + "//@ set c = \\type(java.lang.String[][]); \n" + "//@ set c = (\\lbl TYP3 c); \n" + "//@ set c = \\type(String[][]); \n" + "//@ set c = (\\lbl TYP4 c); \n" + "} \n" + " static void mg() { \n" + "//@ ghost \\TYPE c; \n" + "//@ set c = \\type(java.lang.Class<Integer>); \n" + "//@ set c = (\\lbl TYP1 c); \n" + "} " + "}" ,"LABEL TYP1 = int" ,"LABEL TYP2 = boolean" ,"LABEL TYP1 = class java.lang.Object" ,"LABEL TYP2 = class java.lang.Object" ,"LABEL TYP3 = class java.lang.String" ,"LABEL TYP4 = class java.lang.String" ,"LABEL TYP1 = class [Ljava.lang.String;" ,"LABEL TYP2 = class [Ljava.lang.String;" ,"LABEL TYP3 = class [[Ljava.lang.String;" ,"LABEL TYP4 = class [[Ljava.lang.String;" ,"LABEL TYP1 = class java.lang.Class<class java.lang.Integer>" ,"END" ); } @Test public void testSubtype() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(); mm(); \n" + "System.out.println(\"END\"); } \n" + "static Object o = new Object(); \n" + "static Object oo = new String(); \n" + "static Object ob = Boolean.FALSE; \n" + "static String s = new String(); \n" + "static Boolean b = Boolean.TRUE; \n" + " static void m() { \n" + "//@ ghost boolean c; \n" + "//@ set c = o.getClass() <: o.getClass(); \n" + // Object <: Object // Class "//@ set c = (\\lbl TYP1 c); \n" + "//@ set c = \\typeof(o) <: \\typeof(o); \n" + // Object <: Object // \TYPE "//@ set c = (\\lbl TYP2 c); \n" + "//@ set c = \\typeof(o) <: \\typeof(oo); \n" + // Object <: String // \TYPE "//@ set c = (\\lbl TYP3 c); \n" + "//@ set c = \\typeof(oo) <: \\typeof(o); \n" + // String <: Object // \TYPE "//@ set c = (\\lbl TYP4 c); \n" + "//@ set c = \\typeof(ob) <: \\typeof(oo); \n" + // Boolean <: String // \TYPE "//@ set c = (\\lbl TYP5 c); \n" + "}\n" + " static void mm() { \n" + "//@ ghost boolean c; \n" + "//@ set c = s.getClass() <: b.getClass(); \n" + // String <: Boolean // Class "//@ set c = (\\lbl TYP1 c); \n" + "//@ set c = \\typeof(s) <: \\typeof(b); \n" + // String <: Boolean // \TYPE "//@ set c = (\\lbl TYP2 c); \n" + "//@ set c = \\type(int) <: \\typeof(o); \n" + // int <: Object // \TYPE "//@ set c = (\\lbl TYP3 c); \n" + "//@ set c = \\type(int) <: \\type(int); \n" + // int <: int // false "//@ set c = (\\lbl TYP4 c); \n" + "//@ set c = \\type(int) <: \\type(boolean); \n" + // int <: boolean "//@ set c = (\\lbl TYP5 c); \n" + "}\n" + "}" ,"LABEL TYP1 = true" ,"LABEL TYP2 = true" ,"LABEL TYP3 = false" ,"LABEL TYP4 = true" ,"LABEL TYP5 = false" ,"LABEL TYP1 = false" ,"LABEL TYP2 = false" ,"LABEL TYP3 = false" ,"LABEL TYP4 = true" ,"LABEL TYP5 = false" ,"END" ); } @Test public void testUndefined() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(0); m(1); m(2); System.out.println(\"END\"); } \n" + " //@ requires 10/i != 0; \n" + " //@ ensures 10/(i-1) == 0; \n" + " static public void m(int i) { \n" + " System.out.println(\"VALUE \" + i); \n" + "} " + "}" ,"/tt/TestJava.java:3: JML Division by zero" ,"JML undefined precondition - exception thrown" // FIXME - this should have a line number ,"java.lang.ArithmeticException: / by zero" ,"\tat tt.TestJava.main(TestJava.java:3)" ,"/tt/TestJava.java:2: JML precondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"/tt/TestJava.java:3: JML Division by zero" ,"Runtime exception while evaluating preconditions - preconditions are undefined in JML" ,"java.lang.ArithmeticException: / by zero" ,"\tat tt.TestJava.m(TestJava.java:3)" ,"\tat tt.TestJava.main(TestJava.java:2)" ,"VALUE 0" ,"VALUE 1" ,"/tt/TestJava.java:4: JML Division by zero" ,"Runtime exception while evaluating postconditions - postconditions are undefined in JML" ,"java.lang.ArithmeticException: / by zero" ,"\tat tt.TestJava.m(TestJava.java:4)" ,"\tat tt.TestJava.main(TestJava.java:2)" ,"/tt/TestJava.java:4: JML Division by zero" ,"JML undefined postcondition - exception thrown" ,"java.lang.ArithmeticException: / by zero" ,"\tat tt.TestJava.main(TestJava.java:4)" ,"VALUE 2" ,"/tt/TestJava.java:5: JML postcondition is false" ,"/tt/TestJava.java:4: Associated declaration" ,"/tt/TestJava.java:2: JML postcondition is false" ,"/tt/TestJava.java:4: Associated declaration" ,"END" ); // FIXME - would like to make the stack traces above more helpful } // tests that requires clauses in the same spec case are evaluated in order as if connected by && // (if not, in this case we would get an exception) @Test public void testUndefined2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + "m(0); m(1); System.out.println(\"END\"); } \n" + " //@ requires i != 0; \n" + " //@ requires 10/i == 10; \n" + " static public void m(int i) { \n" + "} " + "}" ,"/tt/TestJava.java:2: JML precondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"/tt/TestJava.java:3: JML precondition is false" ,"END" ); } @Test public void testSpecFile() { addMockFile("$A/tt/A.jml","package tt; public class A { //@ ghost public static int i = 0;\n //@ public invariant i == 0; \n //@ requires i == 1;\n static public int m(); }"); helpTCX("tt.A","package tt; public class A { static public int m() { return 0; } \n public static void main(String[] args) { m(); System.out.println(\"END\"); }}" ,"/tt/A.java:2: JML precondition is false" ,"/$A/tt/A.jml:3: Associated declaration" ,"/$A/tt/A.jml:3: JML precondition is false" ,"END" ); } @Test public void testSpecFile2() { addMockFile("$A/tt/A.jml","package tt; public class A { //@ ghost static int i = 0;\n //@ invariant i == 0; \n //@ ensures i == 1;\n static int m(); }"); helpTCX("tt.A","package tt; public class A { static int m() { //@ set i = 1; \n return 0; } \n public static void main(String[] args) { m(); System.out.println(\"END\"); }}" ,"END" ); } @Test public void testSpecModelMethod() { addMockFile("$A/tt/A.jml","package tt; public class A { \n" +"/*@ model static pure public int mm() { return 5; } */ \n" +"//@ ghost static public int i = 0;\n " +"//@ public invariant i == 0; \n //@ ensures i == 1;\n static public int m(); " +"}" ); helpTCX("tt.A","package tt; public class A { static public int m() { \n" +" //@ set i = mm(); \n" +" return 0; } \n" +" public static void main(String[] args) { m(); System.out.println(\"END\"); }}" ,"/tt/A.java:1: JML postcondition is false" ,"/$A/tt/A.jml:5: Associated declaration" ,"/tt/A.java:4: JML postcondition is false" ,"/$A/tt/A.jml:5: Associated declaration" ,"END" ); } @Test public void testSpecModelClass() { helpTCX("tt.A","package tt; public class A { \n" +"/*@ model public static class AA { static public int mm() { return 5; }} */ \n" +"//@ ghost public static int i = 0;\n " +"//@ public invariant i == 0; \n " +"//@ ensures i == 0;\n " +"static public int m() { \n" +" //@ set i = AA.mm(); \n" +" return 0; \n" +"} \n " +"public static void main(String[] args) { \n" +" m(); \n" +" System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:6: JML postcondition is false" // TODO: Would like this to be line 8 ,"/tt/A.java:5: Associated declaration" ,"/tt/A.java:11: JML postcondition is false" ,"/tt/A.java:5: Associated declaration" ,"END" ); } @Test public void testSpecModelClass2() { addMockFile("$A/tt/A.jml","package tt; public class A { \n" +"/*@ model public static class AB { static public int mm() { return 5; }} */ \n" +"//@ ghost public static int i = 0;\n " +"//@ public invariant i == 0; \n " +"//@ ensures i == 0;\n " +"static public int m(); \n" +"}" ); helpTCX("tt.A","package tt; public class A { \n" +"static public int m() { \n" +" //@ set i = AB.mm(); \n" +" return 0; \n" +"} \n " +"public static void main(String[] args) { \n" +" m(); \n" +" System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:2: JML postcondition is false" // TODO: Would like this to be line 4 ,"/$A/tt/A.jml:5: Associated declaration" ,"/tt/A.java:7: JML postcondition is false" ,"/$A/tt/A.jml:5: Associated declaration" ,"END" ); } @Test public void testStaticInvariant() { addMockFile("$A/tt/A.jml","package tt; public class A { \n" +"//@ static public invariant i == 0; \n " +"public static void m(); \n" +"}" ); helpTCX("tt.A","package tt; public class A { \n" +"static public int i = 0; \n " +"static public void m() { i = 1-i; } \n " +"public static void main(String[] args) { \n" +"m(); \n" +"System.out.println(\"MID\"); \n" +"m(); \n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:3: JML invariant is false on leaving method tt.A.m()" // callee invariant by callee ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:5: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" // callee invariant by caller ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:5: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" // caller on reentering after calling m ,"/$A/tt/A.jml:2: Associated declaration" ,"MID" ,"/tt/A.java:7: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" // caller on leaving to call m ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:7: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" // callee invariant by caller ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:3: JML invariant is false on entering method tt.A.m()" // callee invariant by callee ,"/$A/tt/A.jml:2: Associated declaration" ,"END" ); } @Test public void testStaticInvariant2() { addMockFile("$A/tt/A.jml","package tt; public class A { \n" +"//@ static public invariant i == 0; \n " +"public void m(); \n" +"}" ); helpTCX("tt.A","package tt; public class A { \n" +"static public int i = 0; \n " +"public void m() { i = 1-i; } \n " +"public static void main(String[] args) { \n" +"new A().m(); \n" +"System.out.println(\"MID\"); \n" +"new A().m(); i = 5; \n" +"System.out.println(\"MID\"); \n" +"new A().m(); \n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:3: JML invariant is false on leaving method tt.A.m()" // Leaving m ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:5: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:5: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" // Reentering main from m ,"/$A/tt/A.jml:2: Associated declaration" ,"MID" ,"/tt/A.java:7: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.A())" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:1: JML invariant is false on entering method tt.A.A()" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:1: JML invariant is false on leaving method tt.A.A()" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:7: JML invariant is false on leaving method tt.A.A(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:7: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.A())" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:7: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:7: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:3: JML invariant is false on entering method tt.A.m()" ,"/$A/tt/A.jml:2: Associated declaration" ,"MID" ,"/tt/A.java:9: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.A())" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:1: JML invariant is false on entering method tt.A.A()" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:1: JML invariant is false on leaving method tt.A.A()" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:9: JML invariant is false on leaving method tt.A.A(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:9: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.A())" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:9: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:9: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:3: JML invariant is false on entering method tt.A.m()" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:3: JML invariant is false on leaving method tt.A.m()" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:9: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:9: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/A.jml:2: Associated declaration" ,"END" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.main(java.lang.String[])" ,"/$A/tt/A.jml:2: Associated declaration" ); } @Test public void testInvariant() { main.addOptions("-racShowSource=true"); addMockFile("$A/tt/A.jml","package tt; public class A { \n" +"//@ public invariant i == 0;\n" +"public void m(); \n" +"}" ); helpTCX("tt.A","package tt; public class A { \n" +"public int i = 0; static int j; \n" +"public void m() { i = 1-i; } \n" +"public static void main(String[] args) { \n" +"new A().m();\n" +"j = 0; System.out.println(\"MID\"); j = 1;\n" +"new A().m();\n" +"j = 2; System.out.println(\"END\");\n" +"}}" ,"/tt/A.java:3: JML invariant is false on leaving method tt.A.m()" // Leaving m(), Line 5 ,"public void m() { i = 1-i; } " ," ^" ,"/$A/tt/A.jml:2: Associated declaration" ,"//@ public invariant i == 0;" ," ^" ,"/tt/A.java:5: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" ,"new A().m();" ," ^" ,"/$A/tt/A.jml:2: Associated declaration" ,"//@ public invariant i == 0;" ," ^" ,"MID" ,"/tt/A.java:3: JML invariant is false on leaving method tt.A.m()" ,"public void m() { i = 1-i; } " ," ^" ,"/$A/tt/A.jml:2: Associated declaration" ,"//@ public invariant i == 0;" ," ^" ,"/tt/A.java:7: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" ,"new A().m();" ," ^" ,"/$A/tt/A.jml:2: Associated declaration" ,"//@ public invariant i == 0;" ," ^" ,"END" ); } @Test public void testInitially() { addMockFile("$A/tt/A.jml","package tt; public class A { \n" +"//@ public initially i == 1; \n " +"//@ public initially j == 1; \n " +"//@ public invariant i == j; \n " +" public void m(); \n" +"/*@ assignable i,j; */\n " +"public A(); \n" +"}" ); helpTCX("tt.A","package tt; public class A { \n" +"public int i = 0; \n" +"static public int j = 0; \n" +"public A() { i++; j++; } \n" +"public void m() { i++; j++; } \n" +"public static void main(String[] args) { \n" +"System.out.println(\"START\"); \n" +"new A().m(); \n" +"System.out.println(\"MID\"); \n" +"new A().m(); \n" +"System.out.println(\"END\");\n " +"}}" ,"START" ,"MID" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.A()" ,"/$A/tt/A.jml:4: Associated declaration" ,"/tt/A.java:4: JML initially clause is false at exit from constructor" ,"/$A/tt/A.jml:3: Associated declaration" ,"/tt/A.java:10: JML invariant is false on leaving method tt.A.A(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/A.jml:4: Associated declaration" ,"/tt/A.java:10: JML initially clause is false at exit from constructor" ,"/$A/tt/A.jml:3: Associated declaration" ,"/tt/A.java:10: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/A.jml:4: Associated declaration" ,"/tt/A.java:10: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/A.jml:4: Associated declaration" ,"/tt/A.java:5: JML invariant is false on entering method tt.A.m()" ,"/$A/tt/A.jml:4: Associated declaration" ,"/tt/A.java:5: JML invariant is false on leaving method tt.A.m()" ,"/$A/tt/A.jml:4: Associated declaration" ,"/tt/A.java:10: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/A.jml:4: Associated declaration" ,"END" ); } @Test public void testConstraint() { addMockFile("$A/tt/A.jml","package tt; public class A { \n" +"//@ constraint i == \\old(i)+1; \n " +"void m(); \n" +"}" ); helpTCX("tt.A","package tt; public class A { \n" +"int i = 1; \n " +"void m() { i *= 2; } \n " +"public static void main(String[] args) { \n" +"A a = new A();\n" +"System.out.println(\"START\"); \n" +"a.m(); \n" +"System.out.println(\"MID\"); \n" +"a.m(); \n" +"System.out.println(\"END\"); \n" +"}}" ,"START" ,"MID" ,"/tt/A.java:3: JML constraint clause is false on leaving method" ,"/$A/tt/A.jml:2: Associated declaration" ,"/tt/A.java:9: JML constraint clause is false on leaving method" ,"/$A/tt/A.jml:2: Associated declaration" ,"END" ); } @Test public void testHelper() { addMockFile("$A/tt/A.jml","package tt; public class A { \n" +"//@ invariant i == 0; \n " +"/*@ private helper */ void m(); \n" +"}" ); helpTCX("tt.A","package tt; public class A { \n" +"int i = 0; \n " +"private void m() { i = 1-i; } \n " +"public static void main(String[] args) { \n" +"new A().m(); " +"System.out.println(\"MID\"); " +"new A().m(); " +"System.out.println(\"END\"); " +"}}" ,"MID" ,"END" ); } @Test public void testSuchThat() { helpTCX("tt.A","package tt; public class A { \n" +"static int j = 5; \n" +"//@ static model int i; \n" +"//@ static represents i \\such_that i == j+1; \n" +"public static void main(String[] args) { \n" +"System.out.println(\"END\"); " +"}" +"}" ,"/tt/A.java:4: Note: Not implemented for runtime assertion checking: relational represents clauses (\\such_that)",12 ,"/tt/A.java:3: warning: JML model field is not implemented: i",22 ,"END" ); } @Test public void testModelField() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"static int j = 5; \n " +"//@ static model int i; \n " +"//@ static represents i = j+1; \n " +"public static void main(String[] args) { \n" +"//@ debug System.out.println(\"A \" + i); \n" +" j = 10; \n" +"//@ debug System.out.println(\"A \" + i); \n" +"System.out.println(\"END\"); " +"}" +"//@ static ghost int ii; \n " +"}" ,"A 6" ,"A 11" ,"END" ); } // FIXME - this results of this test are different when run standalone @Test public void testModelFieldST() { main.addOptions("-keys=DEBUG"); expectedNotes = 0; helpTCX("tt.A","package tt; public class A { \n" +"static int j = 5; \n " +"//@ static model int i; \n " +"//@ static represents i \\such_that i==j+1; \n " +"//@ static represents i =j+1; \n " +"public static void main(String[] args) { \n" +"//@ debug System.out.println(\"A \" + i); \n" +" j = 10; \n" +"//@ debug System.out.println(\"A \" + i); \n" +"System.out.println(\"END\"); " +"}" +"//@ static ghost int ii; \n " +"}" ,"/tt/A.java:4: Note: Not implemented for runtime assertion checking: relational represents clauses (\\such_that)",13 ,"A 6" ,"A 11" ,"END" ); } /** Duplicate represents */ @Test public void testModelField1() { main.addOptions("-keys=DEBUG"); continueAnyway = true; helpTCX("tt.A","package tt; public class A { \n" +"static int j = 5; \n " +"//@ static model int i; \n " +"//@ static represents i = j+1; \n " +"//@ static represents i = j; \n " +"public static void main(String[] args) { \n" +"//@ debug System.out.println(\"A \" + i); \n" +" j = 10; \n" +"//@ debug System.out.println(\"A \" + i); \n" +"System.out.println(\"END\"); " +"}}" ,"/tt/A.java:5: warning: Duplicate represents clause - only the first is used for RAC",13 ,"A 6" ,"A 11" ,"END" ); } // TODO - the following two tests fail when the compile policy is // SIMPLE instead of BY_TODO - for some reason the principal class // file (PA or QA) does not get written. /** Represents with super model field */ @Test public void testModelField3() { continueAnyway = true; // That is, even though there are compile errors main.addOptions("-keys=DEBUG"); helpTCX("tt.PA","package tt; public class PA extends PB { \n" +" int j = 5; \n " +"//@ represents i = j+1; \n " +"public static void main(String[] args) { \n" +"PA a = new PA();\n" +"PB b = new PB();\n" +"//@ debug System.out.println(\"A \" + a.i); \n" +"//@ debug System.out.println(\"B \" + b.i); \n" +"b = new PA();\n" +"//@ debug System.out.println(\"B \" + b.i); \n" +"System.out.println(\"END\");\n" +"}}\n" +"class PB { //@ model int i; \n}" ,"/tt/PA.java:13: warning: JML model field is not implemented: i",27 ,"A 6" ,"B 0" ,"B 6" ,"END" ); } /** Represents with super model field */ @Test public void testModelField3a() { main.addOptions("-keys=DEBUG"); helpTCX("tt.PA","package tt; public class PA extends PB { \n" +" int j = 5; \n " +"//@ represents super.i = j+1; \n " +"public static void main(String[] args) { \n" +"PA a = new PA();\n" +"PB b = new PB();\n" +"//@ debug System.out.println(\"A \" + a.i); \n" +"//@ debug System.out.println(\"B \" + b.i); \n" +"b = new PA();\n" +"//@ debug System.out.println(\"B \" + b.i); \n" +"System.out.println(\"END\"); \n" +"}} class PB { //@ model protected int i; }\n" ,"/tt/PA.java:12: warning: JML model field is not implemented: i",39 ,"A 6" ,"B 0" ,"B 6" ,"END" ); } /** Using a model field in a field access */ @Test public void testModelField1a() { main.addOptions("-keys=DEBUG"); helpTCX("tt.PA","package tt; public class PA { \n" +" static int j = 5; \n " +"//@ model int i; represents i = j; \n" +"public static void main(String[] args) { \n" +"PA a = new PA();\n" +"//@ debug System.out.println(\"A \" + a.i); \n" +"PB b = new PB();\n" +"//@ debug System.out.println(\"B \" + b.i); \n" +"System.out.println(\"END\"); " +"}} class PB { //@ model int i; represents i = PA.j+1; \n\n}" ,"A 5" ,"B 6" ,"END" ); } /** Represents with super model field */ @Test public void testModelField4() { main.addOptions("-keys=DEBUG"); helpTCX("tt.QA","package tt; public class QA extends QB { \n" +" int j = 5; \n " +"public static void main(String[] args) { \n" +"QA a = new QA();\n" +"QB b = new QB();\n" +"//@ debug System.out.println(\"A \" + a.i); \n" +"//@ debug System.out.println(\"B \" + b.i); \n" +"b = new QA();\n" +"//@ debug System.out.println(\"B \" + b.i); \n" +"System.out.println(\"END\"); \n" +"}} class QB { //@ model int i; \n}" ,"/tt/QA.java:11: warning: JML model field is not implemented: i",30 ,"A 0" ,"B 0" ,"B 0" ,"END" ); } /** Model field with no represents */ @Test public void testModelField2() { main.addOptions("-keys=DEBUG"); expectedExit = 0; continueAnyway = true; helpTCX("tt.A","package tt; public class A { \n" +"static int j = 5; \n" +"//@ static model int i; \n" +"public static void main(String[] args) { \n" +"//@ debug System.out.println(\"A \" + i); \n" +"System.out.println(\"END\"); " +"}}" ,"/tt/A.java:3: warning: JML model field is not implemented: i",22 ,"A 0" ,"END" ); } /** Forall, exists quantifier */ @Test public void testForallQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost boolean n = (\\forall int i; 0<=i && i<=5; i >= 2); \n " +"//@ ghost boolean nn = (\\exists int i; 0<=i && i<=5; i >= 2); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A false true" ,"END" ); } /** Forall, exists quantifier */ @Test public void testForallQuantifier2() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost boolean n = (\\forall int i; 0<=i && i<=5; i >= 0); \n " +"//@ ghost boolean nn = (\\exists int i; 0<=i && i<=5; i >= 6); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A true false" ,"END" ); } /** Forall, exists quantifier */ @Test public void testForallQuantifier3() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost boolean n = (\\forall int i; ; i >= 0); \n " +"//@ ghost boolean nn = (\\exists int i; i == 4; i >= 6); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"/tt/A.java:3: Note: Runtime assertion checking is not implemented for this type or number of declarations in a quantified expression",25 ,"/tt/A.java:4: Note: Runtime assertion checking is not implemented for this type or number of declarations in a quantified expression",26 ,"A false false" ,"END" ); } @Test public void testForallQuantifier4() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost boolean n = (\\forall int i; 0<i && i<=5; (\\exists int j; 0<=j && j < 5; j<i)); \n " +"//@ ghost boolean nn = (\\forall int i; 0<=i && i<=5; (\\exists int j; 0<=j && j < 5; j<i)); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A true false" ,"END" ); } /** Numof quantifier */ @Test public void testCountQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost long n1 = (\\num_of int i; 0 <= i && i <= 5; true); \n " +"//@ ghost long n2 = (\\num_of int i; 0 < i && i < 5; true); \n " +"//@ debug System.out.println(\"A \" + n1 + \" \" + n2); \n" +"System.out.println(\"END\"); " +"}}" ,"A 6 4" ,"END" ); } /** Numof quantifier */ @Test public void testCountQuantifier3() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost long n = (\\num_of int i; 0 <= i && i < 5; i >= 2); \n " +"//@ ghost long nn = (\\num_of int i; 0 <= i && i < 5; false); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A 3 0" ,"END" ); } /** Numof quantifier */ @Test public void testCountQuantifierExt() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static int m = 2;\n" +"public static void main(String[] argv) { \n " +"// @ ghost int nnn = new org.jmlspecs.utils.Utils.ValueInt() { public int value(final Object[] args) { int count = 0; int lo = (Integer)(args[0]); int hi = (Integer)(args[1]); int i = lo; while (i <= hi) { if (i>=lo && i<=hi) count++; i++; } return count; }}.value(new Object[]{0,5});\n" +"//@ ghost int n = (\\num_of int i; 0 <= i && i < 5; i >= m); \n " +"//@ ghost int nn = (\\num_of int i; 0 <= i && i < 5; m > 0); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn ); \n" +"System.out.println(\"END\"); " +"}}" ,"A 3 5" ,"END" ); } /** Numof quantifier */ @Test public void testCountQuantifierExtE() { helpTCX("tt.A","package tt; public class A { \n" +"public static int m = 2;\n" +"//@ ensures (\\num_of int i; 0 <= i && i < 5; i >= m) == 3;\n" +"//@ ensures (\\num_of int i; 0 <= i && i < 5; i >= m) == 4;\n" +"public static void main(String[] argv) { \n " +"System.out.println(\"END\"); " +"}}" ,"END" ,"/tt/A.java:5: JML postcondition is false" ,"/tt/A.java:4: Associated declaration" ); } // FIXME - quantifiers witrh multiple declarations /** Numof quantifier */ @Test public void testCountTwo() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost long n1 = (\\num_of int i,j; 0 <= i && i <= 5 && 0 <= j && j < i; true); \n " +"//@ debug System.out.println(\"A \" + n1); \n" +"System.out.println(\"END\"); " +"}}" ,"/tt/A.java:3: Note: Runtime assertion checking is not implemented for this type or number of declarations in a quantified expression",23 ,"A 0" ,"END" ); } /** Sum quantifier */ @Test public void testSumQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost int n = (\\sum int i; 0<i && i<=5; i+1); \n " +"//@ ghost int nn = (\\sum int i; 0<i && i<0; i+1); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A 20 0" ,"END" ); } /** Sum quantifier */ @Test public void testProdQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost int n = (\\product int i; 0<i && i<=5; i+1); \n " +"//@ ghost int nn = (\\product int i; 0<i && i<0; i+1); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A 720 1" ,"END" ); } /** Max quantifier */ @Test public void testMaxQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost int n = (\\max int i; 0<=i && i<=5 && (i%2)==0; i+1); \n " +"//@ ghost int nn = (\\max int i; 0<i && i<0; i+1); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A 5 -2147483648" ,"END" ); } /** Max quantifier, with function call */ @Test public void testMaxQuantifier2() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +" public static int inc(int i) { return i + 10; }\n" +"public static void main(String[] argv) { \n " +"//@ ghost int n = (\\max int i; 0<=i && i<=5 && (i%2)==0; inc(i)); \n " +"//@ ghost int nn = (\\max int i; -9<=i && i<=5 ; Math.abs(i)); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A 14 9" ,"END" ); } /** quantifier over short */ @Test public void testShortQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost short n1 = (\\max int i; 0<=i && i<=5; (short)(i+10)); \n " +"//@ ghost short n2 = (\\min int i; 0<=i && i<=5; (short)(i+10)); \n " +"//@ debug System.out.println(\"A \" + n1 + \" \" + n2); \n" +"System.out.println(\"END\"); " +"}}" ,"A 15 10" ,"END" ); } /** quantifier over short */ @Test public void testShortQuantifierB() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost short n1 = (\\max short i; 2<=i && i<=5; i); \n " +"//@ ghost short n2 = (\\min short i; 2<=i && i<=5; i); \n " +"//@ debug System.out.println(\"A \" + n1 + \" \" + n2); \n" +"System.out.println(\"END\"); " +"}}" ,"A 5 2" ,"END" ); } /** quantifier over byte */ @Test public void testByteQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost byte n1 = (\\max int i; 2<=i && i<=5; (byte)i); \n " +"//@ ghost byte n2 = (\\min int i; 2<=i && i<=5; (byte)i); \n " +"//@ debug System.out.println(\"A \" + n1 + \" \" + n2); \n" +"System.out.println(\"END\"); " +"}}" ,"A 5 2" ,"END" ); } /** quantifier over byte */ @Test public void testByteQuantifierB() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost byte n1 = (\\max byte i; 2<=i && i<=5; i); \n " +"//@ ghost byte n2 = (\\min byte i; 2<=i && i<=5; i); \n " +"//@ debug System.out.println(\"A \" + n1 + \" \" + n2); \n" +"System.out.println(\"END\"); " +"}}" ,"A 5 2" ,"END" ); } /** quantifier over long */ @Test public void testLongQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost long n1 = (\\max int i; 0<=i && i<=5; (i+10L)); \n " +"//@ ghost long n2 = (\\min int i; 0<=i && i<=5; (i+10L)); \n " +"//@ debug System.out.println(\"A \" + n1 + \" \" + n2); \n" +"System.out.println(\"END\"); " +"}}" ,"A 15 10" ,"END" ); } /** quantifier over long */ @Test public void testLongQuantifierB() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost long n1 = (\\max long i; 0<=i && i<=5; (i+10L)); \n " +"//@ ghost long n2 = (\\min long i; 0<=i && i<=5; (i+10L)); \n " +"//@ debug System.out.println(\"A \" + n1 + \" \" + n2); \n" +"System.out.println(\"END\"); " +"}}" ,"A 15 10" ,"END" ); } /** quantifier over double */ @Test public void testDoubleQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost double n1 = (\\max int i; 0<=i && i<=5; (double)(i+10.5)); \n " +"//@ ghost double n2 = (\\min int i; 0<=i && i<=5; (double)(i+10.5)); \n " +"//@ debug System.out.println(\"A \" + n1 + \" \" + n2); \n" +"System.out.println(\"END\"); " +"}}" ,"A 15.5 10.5" ,"END" ); } /** quantifier over float */ @Test public void testFloatQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost float n1 = (\\max int i; 0<=i && i<=5; (float)(i+10.5)); \n " +"//@ ghost float n2 = (\\min int i; 0<=i && i<=5; (float)(i+10.5)); \n " +"//@ debug System.out.println(\"A \" + n1 + \" \" + n2); \n" +"System.out.println(\"END\"); " +"}}" ,"A 15.5 10.5" ,"END" ); } /** quantifier over char */ @Test public void testCharQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost char n1 = (\\max int i; 'a'<i && i<='q'; (char)i); \n " +"//@ ghost char n2 = (\\min int i; 'a'<i && i<='q'; (char)i); \n " +"//@ debug System.out.println(\"A \" + n1 + \" \" + n2); \n" +"System.out.println(\"END\"); " +"}}" ,"A q b" ,"END" ); } /** quantifier over char */ @Test public void testCharQuantifierB() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost char n1 = (\\max char i; 'a'<i && i<='q'; i); \n " +"//@ ghost char n2 = (\\min char i; 'a'<i && i<='q'; i); \n " +"//@ debug System.out.println(\"A \" + n1 + \" \" + n2); \n" +"System.out.println(\"END\"); " +"}}" ,"A q b" ,"END" ); } /** Min quantifier */ @Test public void testMinQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost int n = (\\min int i; 0<=i && i<=5 && (i%2)==1; i+1); \n " +"//@ ghost int nn = (\\min int i; 0<i && i<0; i+1); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A 2 2147483647" ,"END" ); } /** Max quantifier */ @Test public void testMaxLongQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost long n = (\\max int i; 0<=i && i<=5 && (i%2)==0; (long)i+1); \n " +"//@ ghost long nn = (\\max int i; 0<i && i<0; i+1); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A 5 -2147483648" ,"END" ); } /** Min quantifier */ @Test public void testMinLongQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost long n = (\\min int i; 0<=i && i<=5 && (i%2)==1; (long)i+1); \n " +"//@ ghost long nn = (\\min int i; 0<i && i<0; i+1); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A 2 2147483647" ,"END" ); } /** Max quantifier */ @Test public void testMaxDoubleQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost double n = (\\max int i; 0<=i && i<=5 && (i%2)==0; (double)i+1); \n " +"//@ ghost double nn = (\\max int i; 0<i && i<0; i+1); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A 5.0 -2.147483648E9" ,"END" ); } /** double quantifier */ @Test public void testMinDoubleQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +"//@ ghost double n = (\\min int i; 0<=i && i<=5 && (i%2)==1; (double)i+1); \n " +"//@ ghost double nn = (\\min int i; 0<i && i<0; (double)i+1); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn); \n" +"System.out.println(\"END\"); " +"}}" ,"A 2.0 1.7976931348623157E308" ,"END" ); } /** boolean quantifier */ @Test public void testBooleanQuantifier() { main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] argv) { \n " +" boolean bb = true;" +"//@ ghost int n = (\\sum boolean i; bb; (i?2:5)); \n " +"//@ ghost int nn = (\\sum boolean i; !i; (i?2:5)); \n " +"//@ ghost int nnn = (\\sum boolean i; i; (i?2:5)); \n " +"//@ ghost int nnnn = (\\sum boolean i; false; (i?2:5)); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn + \" \" + nnn + \" \" + nnnn); \n" +"System.out.println(\"END\"); " +"}}" ,"A 7 5 2 0" ,"END" ); } /** Object quantifier */ @Test public void testObjectQuantifier() { expectedNotes = 0; main.addOptions("-keys=DEBUG"); helpTCX("tt.A","package tt; import java.util.*; public class A { \n" +"public static void main(String[] argv) { \n " +" List<Object> list = new LinkedList<Object>();\n" +"//@ ghost int n = (\\num_of Object o; list.contains(o); true); \n " +" Object oo = new Object(); list.add(new Object());\n" +"//@ ghost int nn = (\\num_of Object o; list.contains(o) && true; true); \n " +" list.add(oo);\n" +"//@ ghost int nnn = (\\num_of Object o; list.contains(o) && o == oo; true); \n " +"//@ debug System.out.println(\"A \" + n + \" \" + nn + \" \" + nnn); \n" +"System.out.println(\"END\"); " +"}}" ,"A 0 1 1" ,"END" ); } /** Represents with super model field */ @Test public void testModelField5a() { continueAnyway = true; addMockFile("$A/tt/B.java","package tt; class B{ //@ model int i; \n}"); helpTCX("tt.A","package tt; public class A extends tt.B { \n" +" int j = 5; \n " +"public static void main(String[] args) { \n" +"A a = new A();\n" +"tt.B b = new tt.B();\n" +"//@ debug System.out.println(\"A \" + a.i); \n" +"//@ debug System.out.println(\"B \" + b.i); \n" +"b = new A();\n" +"//@ debug System.out.println(\"B \" + b.i); \n" +"System.out.println(\"END\"); " +"}}" ,"/$A/tt/B.java:1: warning: JML model field is not implemented: i",36 ,"END" ); } /** Represents with super model field */ @Test public void testModelField5() { continueAnyway = true; main.addOptions("-keys=DEBUG"); addMockFile("$A/tt/B.java","package tt; class B{ //@ model int i; \n}"); helpTCX("tt.A","package tt; public class A extends tt.B { \n" +" int j = 5; \n " +"public static void main(String[] args) { \n" +"A a = new A();\n" +"tt.B b = new tt.B();\n" +"//@ debug System.out.println(\"A \" + a.i); \n" +"//@ debug System.out.println(\"B \" + b.i); \n" +"b = new A();\n" +"//@ debug System.out.println(\"B \" + b.i); \n" +"System.out.println(\"END\"); " +"}}" ,"/$A/tt/B.java:1: warning: JML model field is not implemented: i",36 ,"A 0" //FIXME - check this ,"B 0" ,"B 0" ,"END" ); } @Test public void testNullAssignment() { helpTCX("tt.A","package tt; import org.jmlspecs.annotation.*; @NullableByDefault public class A { \n" +"/*@non_null*/ static String o=\"\",oo=\"\"; static Object ooo;\n" +"public static void main(String[] args) { \n" +" oo = null;\n" +" ooo = null;\n" +" /*@ non_null*/ String local = \"\";\n" +" local = (String)ooo;" +"System.out.println(\"END\"); " +"}} class B { //@ model int i; represents i = 0; \n}" ,"/tt/A.java:4: JML assignment of null to a non_null variable" ,"/tt/A.java:7: JML assignment of null to a non_null variable" ,"END" ,"/tt/A.java:2: JML non-null field is null" ); } @Test public void testNullAssignment2() { helpTCX("tt.A","package tt; import org.jmlspecs.annotation.*; @NullableByDefault public class A { \n" +"/*@non_null*/ static Object o,oo; static Object ooo; \n" +"public static void main(String[] args) { \n" +" A.oo = null;\n" +" A.ooo = null;\n" +"System.out.println(\"END\"); " +"}} " ,"/tt/A.java:2: JML static initialization may not be correct: non-null static field has null value: o" ,"/tt/A.java:2: JML static initialization may not be correct: non-null static field has null value: oo" ,"/tt/A.java:4: JML assignment of null to a non_null variable" ,"END" ,"/tt/A.java:2: JML non-null field is null" ,"/tt/A.java:2: JML non-null field is null" ); } @Test public void testNullReference() { expectedRACExit = 1; helpTCX("tt.A","package tt; import org.jmlspecs.annotation.*; public class A { \n" +"/*@nullable*/static A a = null;\n" +"/*@nullable*/ A b = null;\n" +"static int i = 9;\n" +"public static void main(String[] args) { \n" +" int j; j = A.i;\n" +" j = a.i;\n" // No null dereference warning since i is static +" try { j = a.b.i; } catch (NullPointerException e) {} \n" +" //@ ghost int k; set k = A.i;\n" +" //@ set k = a.i;\n" +" //@ set k = a.b.i;\n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:8: JML A null object is dereferenced" ,"/tt/A.java:11: JML A null object is dereferenced within a JML expression" ,"Exception in thread \"main\" java.lang.NullPointerException" ,"\tat tt.A.main(A.java:11)" ); } @Test public void testNullInitialization() { noCollectDiagnostics = true; print = true; helpTCX("tt.A","package tt; /*@nullable_by_default*/ public class A { \n" +"/*@non_null*/ static Object o,oo = null; \n" +"static String ooo = null;\n" +"//@ non_null ghost static Object oooo = null;\n" +"public static void main(String[] args) { \n" +" /*@ non_null*/ String local = ooo;\n" +" //@ ghost non_null String loc = null; \n" +"System.out.println(\"END\"); " +"}} " ,"/tt/A.java:2: JML null initialization of non_null field oo" ,"/tt/A.java:4: JML null initialization of non_null field oooo" ,"/tt/A.java:2: JML static initialization may not be correct: non-null static field has null value: o" ,"/tt/A.java:2: JML static initialization may not be correct: non-null static field has null value: oo" ,"/tt/A.java:4: JML static initialization may not be correct: non-null static field has null value: oooo" ,"/tt/A.java:6: JML null initialization of non_null field local" ,"/tt/A.java:7: JML null initialization of non_null field loc" ,"END" ,"/tt/A.java:2: JML non-null field is null" // FIXME - add the name of the field ,"/tt/A.java:2: JML non-null field is null" ,"/tt/A.java:4: JML non-null field is null" ); } @Test public void testNullDefault() { helpTCX("tt.A","package tt; public class A { \n" +"/*@nullable*/ static Object o,oo = null; \n" +"static Object ooo = null;\n" +"//@ nullable ghost static Object oooo = null;\n" +"public static void main(String[] args) { \n" +" /*@ nullable*/ String local = (String)ooo;\n" +" //@ ghost String loc = null; \n" +"System.out.println(\"END\"); " +"}} class B { \n}" ,"/tt/A.java:3: JML null initialization of non_null field ooo" ,"/tt/A.java:3: JML static initialization may not be correct: non-null static field has null value: ooo" ,"/tt/A.java:6: JML non-null field is null" ,"/tt/A.java:7: JML null initialization of non_null field loc" ,"END" ,"/tt/A.java:3: JML non-null field is null" ); } @Test public void testNullInit() { helpTCX("tt.A","package tt; public class A { \n" +"/*@nullable*/ static Object o,oo = null; \n" +"static Object ooo = null;\n" +"//@ static invariant o != ooo;\n" +"//@ nullable ghost static Object oooo = null;\n" +"public static void main(String[] args) { \n" +" /*@ nullable*/ String local = (String)ooo;\n" +" //@ ghost String loc = null; \n" +"System.out.println(\"END\"); " +"}}" ,"/tt/A.java:3: JML null initialization of non_null field ooo" ,"/tt/A.java:3: JML static initialization may not be correct: non-null static field has null value: ooo" ,"/tt/A.java:1: JML static initialization may not be correct: invariant is false" ,"/tt/A.java:4: Associated declaration" ,"/tt/A.java:6: JML invariant is false on entering method tt.A.main(java.lang.String[])" ,"/tt/A.java:4: Associated declaration" ,"/tt/A.java:7: JML non-null field is null" ,"/tt/A.java:8: JML null initialization of non_null field loc" ,"END" ,"/tt/A.java:6: JML invariant is false on leaving method tt.A.main(java.lang.String[])" ,"/tt/A.java:4: Associated declaration" ,"/tt/A.java:3: JML non-null field is null" ); } // check readable, writable, monitors for // check modifiers? // check more method clauses // check other expression types // what about assignable // check any problems with grouped clauses @Test public void testNotImplemented() { main.addOptions("-keys=DEBUG"); //print = true; expectedExit = 1; helpTCX("tt.A","package tt; public class A { \n" +"//@ axiom true;\n" +"//@ public invariant \\duration(true) == 0;\n" +"//@ public model long i;\n" +"//@ public represents i = \\duration(true);\n" +"//@ public constraint \\duration(true) == 0;\n" +"//@ public initially \\duration(true) == 0;\n" +"public static void main(String[] args) { \n" +" //@ hence_by true; \n" +" //@ assert \\duration(true) == 0;\n" +" //@ assume \\duration(true) == 0;\n" +" //@ ghost long k = \\duration(true);\n" +" //@ set k = \\duration(true);\n" +" //@ debug k = \\duration(true);\n" +" System.out.println(\"END\"); " +"}\n" +"//@ ghost long z = \\duration(true);\n" +"//@ ghost long[] zz = { \\duration(true) } ;\n" +"/*@ requires \\duration(true) == 0;*/" +"int ma() { return 0; }\n" +"//@ ensures \\duration(true) == 0;\n" +"//@ signals (Exception ex) \\duration(true) == 0;\n" // Line 20 +"//@ signals_only RuntimeException;\n" +"//@ diverges \\duration(true) == 0;\n" +"//@ duration \\duration(true);\n" +"//@ working_space \\duration(true);\n" +"int mb() { return 0; }\n" +"}" //,"/tt/A.java:2: Note: Not implemented for runtime assertion checking: axiom clause",5 ,"/tt/A.java:3: Note: Not implemented for runtime assertion checking: invariant clause containing \\duration",31 ,"/tt/A.java:7: Note: Not implemented for runtime assertion checking: initially clause containing \\duration",31 ,"/tt/A.java:9: Note: Not implemented for runtime assertion checking: hence_by statement",9 ,"/tt/A.java:10: Note: Not implemented for runtime assertion checking: assert statement containing \\duration",25 ,"/tt/A.java:11: Note: Not implemented for runtime assertion checking: assume statement containing \\duration",25 ,"/tt/A.java:12: Note: Not implemented for runtime assertion checking: ghost declaration containing \\duration",33 ,"/tt/A.java:13: Note: Not implemented for runtime assertion checking: set statement containing \\duration",26 ,"/tt/A.java:14: Note: Not implemented for runtime assertion checking: debug statement containing \\duration",28 ,"/tt/A.java:16: Note: Not implemented for runtime assertion checking: ghost declaration containing \\duration",29 ,"/tt/A.java:17: Note: Not implemented for runtime assertion checking: ghost declaration containing \\duration",34 ,"/tt/A.java:18: Note: Not implemented for runtime assertion checking: requires clause containing \\duration",23 ,"/tt/A.java:6: Note: Not implemented for runtime assertion checking: constraint clause containing \\duration",32 ,"/tt/A.java:19: Note: Not implemented for runtime assertion checking: ensures clause containing \\duration",22 ,"/tt/A.java:20: Note: Not implemented for runtime assertion checking: signals clause containing \\duration",37 ,"/tt/A.java:22: Note: Not implemented for runtime assertion checking: diverges clause containing \\duration",23 ,"/tt/A.java:23: Note: Not implemented for runtime assertion checking: duration clause containing \\duration",24 ,"/tt/A.java:24: Note: Not implemented for runtime assertion checking: working_space clause containing \\duration",28 ,"/tt/A.java:5: Note: Not implemented for runtime assertion checking: represents clause containing \\duration",37 ,"/tt/A.java:5: Unrecoverable situation: Unimplemented construct in a method or model method or represents clause",37 ,"END" ); } @Test public void testNotImplemented2() { helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] args) { \n" +" m();\n" +" System.out.println(\"END\"); " +"}\n" +"//@ requires \\duration(true) == 0;\n" +"//@ ensures true;\n" +"//@ also\n" +"//@ requires \\duration(true) == 0;\n" +"//@ signals (Exception ex) true;\n" +"//@ also\n" +"//@ requires \\duration(true) == 0;\n" +"//@ signals_only RuntimeException;\n" +"//@ also\n" +"//@ ensures true;\n" +"static int m() { return 0; }\n" +"}" ,"/tt/A.java:5: Note: Not implemented for runtime assertion checking: requires clause containing \\duration",25 ,"/tt/A.java:8: Note: Not implemented for runtime assertion checking: requires clause containing \\duration",25 ,"/tt/A.java:11: Note: Not implemented for runtime assertion checking: requires clause containing \\duration",25 ,"END" ); } @Test public void testSuperInvariant() { helpTCX("tt.A","package tt; public class A extends B { \n" +" public void m() {} //@public invariant i == 1; \n" +"public static void main(String[] args) { \n" +" new A().m(); \n" +"System.out.println(\"MID\"); \n" +" new B().m(); \n" +"System.out.println(\"MID\"); \n" +" new C().m(); \n" +"System.out.println(\"END\"); \n" +"}} \n" +"class B extends C { //@ public invariant i == 2; \n" +"}\n" +"class C { \n" // Line 13 +" Object o = this; \n" +" public int i=0; \n" +" public void m() {} \n" +" //@ public invariant i == 3; \n" +"}\n" // FIXME - should check invariants on reentering caller after returning from super call ,"/tt/A.java:13: JML invariant is false on leaving method tt.C.C()" // Invariant in C, exiting C() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:11: JML invariant is false on leaving method tt.B.B()" // Invariant in C, exiting B() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:11: JML invariant is false on leaving method tt.B.B()" // Invariant in B, exiting B() ,"/tt/A.java:11: Associated declaration" ,"/tt/A.java:1: JML invariant is false on leaving method tt.A.A()" // Invariant in C, exiting A() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:1: JML invariant is false on leaving method tt.A.A()" // Invariant in B, exiting A() ,"/tt/A.java:11: Associated declaration" ,"/tt/A.java:1: JML invariant is false on leaving method tt.A.A()" // Invariant in A, exiting A() ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.A(), returning to tt.A.main(java.lang.String[])" // Invariant in C, exiting caller ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.A(), returning to tt.A.main(java.lang.String[])" // Invariant in B, exiting caller ,"/tt/A.java:11: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.A(), returning to tt.A.main(java.lang.String[])" // Invariant in A, exiting caller ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:4: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" // Invariant in C, entering m ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:4: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" // Invariant in C, entering m ,"/tt/A.java:11: Associated declaration" ,"/tt/A.java:4: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" // Invariant in C, entering m ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:4: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" // Invariant in C, entering m ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:4: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" // Invariant in B, entering m ,"/tt/A.java:11: Associated declaration" ,"/tt/A.java:4: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" // Invariant in A, entering m ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:2: JML invariant is false on entering method tt.A.m()" // Invariant in C, beginning m() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:2: JML invariant is false on entering method tt.A.m()" // Invariant in B, beginning m() ,"/tt/A.java:11: Associated declaration" ,"/tt/A.java:2: JML invariant is false on entering method tt.A.m()" // Invariant in A, beginning m() ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:2: JML invariant is false on leaving method tt.A.m()" // Invariant in C, completing m() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:2: JML invariant is false on leaving method tt.A.m()" // Invariant in B, completing m() ,"/tt/A.java:11: Associated declaration" ,"/tt/A.java:2: JML invariant is false on leaving method tt.A.m()" // Invariant in A, completing m() ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" // Invariant in C, leaving m() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" // Invariant in B, leaving m() ,"/tt/A.java:11: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" // Invariant in A, leaving m() ,"/tt/A.java:2: Associated declaration" ,"MID" ,"/tt/A.java:13: JML invariant is false on leaving method tt.C.C()" // Invariant in C, exiting C() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:11: JML invariant is false on leaving method tt.B.B()" // Invariant in C, exiting B() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:11: JML invariant is false on leaving method tt.B.B()" // Invariant in B, exiting B() ,"/tt/A.java:11: Associated declaration" ,"/tt/A.java:6: JML invariant is false on leaving method tt.B.B(), returning to tt.A.main(java.lang.String[])" ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:6: JML invariant is false on leaving method tt.B.B(), returning to tt.A.main(java.lang.String[])" ,"/tt/A.java:11: Associated declaration" ,"/tt/A.java:6: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" // Invariant in C, entering m() - this is C.m() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:6: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" // Invariant in C, entering m() - this is C.m() ,"/tt/A.java:17: Associated declaration" // FIXME should be checking B's invariants as well, since the receiver is B, above ,"/tt/A.java:16: JML invariant is false on entering method tt.C.m()" // Invariant in C, beginning m() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:16: JML invariant is false on leaving method tt.C.m()" // Invariant in C, completing m() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:6: JML invariant is false on leaving method tt.C.m(), returning to tt.A.main(java.lang.String[])" // Invariant in C, exiting m() ,"/tt/A.java:17: Associated declaration" ,"MID" ,"/tt/A.java:13: JML invariant is false on leaving method tt.C.C()" // Invariant in C, exiting C() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:8: JML invariant is false on leaving method tt.C.C(), returning to tt.A.main(java.lang.String[])" // Invariant in C, exiting C() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:8: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:8: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" // Invariant in C, entering m() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:16: JML invariant is false on entering method tt.C.m()" // Invariant in C, entering m() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:16: JML invariant is false on leaving method tt.C.m()" // Invariant in C, leaving m() ,"/tt/A.java:17: Associated declaration" ,"/tt/A.java:8: JML invariant is false on leaving method tt.C.m(), returning to tt.A.main(java.lang.String[])" // Invariant in C, leaving m() ,"/tt/A.java:17: Associated declaration" ,"END" ); } // Testing inheritance of invariants; here m() is implemented for classes A and C, but not B @Test public void testSuperInvariantB() { addMockFile("$A/tt/B.java","package tt; public class B extends tt.C { \n" +"//@ public invariant i == 2; \n" +"}\n" ); addMockFile("$A/tt/C.java","package tt; public class C { \n" +"public int i=0; public void m() {} \n" +"//@ public invariant i == 3; \n" +"}\n" ); helpTCX("tt.A","package tt; public class A extends B { \n" +" public void m() {} //@public invariant i == 1; \n" +"public static void main(String[] args) { \n" +" new A().m(); \n" +"System.out.println(\"MID\"); \n" +" new B().m(); \n" +"System.out.println(\"MID\"); \n" +" new C().m(); \n" +"System.out.println(\"END\"); \n" +"}} \n" // FIXME _ review all these output messages against expected invariants ,"/$A/tt/C.java:1: JML invariant is false on leaving method tt.C.C()" // leaving C() in A(), invariant in C ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/B.java:1: JML invariant is false on leaving method tt.B.B()" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/B.java:1: JML invariant is false on leaving method tt.B.B()" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:1: JML invariant is false on leaving method tt.A.A()" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:1: JML invariant is false on leaving method tt.A.A()" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:1: JML invariant is false on leaving method tt.A.A()" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.A(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.A(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.A(), returning to tt.A.main(java.lang.String[])" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:4: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:4: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:4: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:4: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:4: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:4: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:2: JML invariant is false on entering method tt.A.m()" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:2: JML invariant is false on entering method tt.A.m()" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:2: JML invariant is false on entering method tt.A.m()" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:2: JML invariant is false on leaving method tt.A.m()" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:2: JML invariant is false on leaving method tt.A.m()" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:2: JML invariant is false on leaving method tt.A.m()" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" ,"/tt/A.java:2: Associated declaration" ,"MID" ,"/$A/tt/C.java:1: JML invariant is false on leaving method tt.C.C()" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/B.java:1: JML invariant is false on leaving method tt.B.B()" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/B.java:1: JML invariant is false on leaving method tt.B.B()" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:6: JML invariant is false on leaving method tt.B.B(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:6: JML invariant is false on leaving method tt.B.B(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:6: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:6: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/C.java:2: JML invariant is false on entering method tt.C.m()" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/C.java:2: JML invariant is false on leaving method tt.C.m()" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:6: JML invariant is false on leaving method tt.C.m(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/C.java:3: Associated declaration" ,"MID" ,"/$A/tt/C.java:1: JML invariant is false on leaving method tt.C.C()" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:8: JML invariant is false on leaving method tt.C.C(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:8: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:8: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/C.java:2: JML invariant is false on entering method tt.C.m()" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/C.java:2: JML invariant is false on leaving method tt.C.m()" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:8: JML invariant is false on leaving method tt.C.m(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/C.java:3: Associated declaration" ,"END" ); } @Test public void testStaticInhInvariant() { //main.addOptions("-show"); addMockFile("$A/tt/B.java","package tt; public class B extends tt.C { \n" +"//@ static public invariant i == 2; \n" +"}\n" ); addMockFile("$A/tt/C.java","package tt; public class C { \n" +"static public int i=0; static public void m() {} \n" +"//@ static public invariant i == 3; \n" +"}\n" ); helpTCX("tt.A","package tt; public class A extends tt.B { \n" +" //@ static public invariant i == 1; \n" +" static public void m() {}\n" +"public static void main(String[] args) { \n" +"System.out.println(\"A\"); \n" +" A.m(); \n" +"System.out.println(\"B\"); \n" +" tt.B.m(); \n" +"System.out.println(\"C\"); \n" +" tt.C.m(); \n" +"System.out.println(\"END\"); \n" +"}} \n" ,"/$A/tt/C.java:1: JML static initialization may not be correct: invariant is false" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/B.java:1: JML static initialization may not be correct: invariant is false" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/B.java:1: JML static initialization may not be correct: invariant is false" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:1: JML static initialization may not be correct: invariant is false" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:1: JML static initialization may not be correct: invariant is false" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:1: JML static initialization may not be correct: invariant is false" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:4: JML invariant is false on entering method tt.A.main(java.lang.String[])" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:4: JML invariant is false on entering method tt.A.main(java.lang.String[])" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:4: JML invariant is false on entering method tt.A.main(java.lang.String[])" ,"/tt/A.java:2: Associated declaration" ,"A" ,"/tt/A.java:6: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:6: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:6: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:6: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:6: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:6: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:3: JML invariant is false on entering method tt.A.m()" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:3: JML invariant is false on entering method tt.A.m()" ,"/$A/tt/B.java:2: Associated declaration" // ,"/tt/A.java:3: JML invariant is false on entering method tt.A.m()" // ,"/$A/tt/C.java:3: Associated declaration" // ,"/tt/A.java:3: JML invariant is false on entering method tt.A.m()" // ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:3: JML invariant is false on entering method tt.A.m()" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:3: JML invariant is false on leaving method tt.A.m()" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:3: JML invariant is false on leaving method tt.A.m()" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:3: JML invariant is false on leaving method tt.A.m()" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:6: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:6: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:6: JML invariant is false on leaving method tt.A.m(), returning to tt.A.main(java.lang.String[])" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:6: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:6: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:6: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.A.m())" ,"/tt/A.java:2: Associated declaration" ,"B" ,"/tt/A.java:8: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/$A/tt/C.java:3: Associated declaration" // ,"/tt/A.java:8: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" // ,"/$A/tt/B.java:2: Associated declaration" // ,"/tt/A.java:8: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" // ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:8: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/C.java:2: JML invariant is false on entering method tt.C.m()" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/C.java:2: JML invariant is false on leaving method tt.C.m()" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:8: JML invariant is false on leaving method tt.C.m(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:8: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:8: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:8: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/tt/A.java:2: Associated declaration" ,"C" ,"/tt/A.java:10: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/$A/tt/C.java:3: Associated declaration" // ,"/tt/A.java:10: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" // ,"/$A/tt/B.java:2: Associated declaration" // ,"/tt/A.java:10: JML caller invariant is false on leaving calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" // ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:10: JML invariant is false on entering method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/C.java:2: JML invariant is false on entering method tt.C.m()" ,"/$A/tt/C.java:3: Associated declaration" ,"/$A/tt/C.java:2: JML invariant is false on leaving method tt.C.m()" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:10: JML invariant is false on leaving method tt.C.m(), returning to tt.A.main(java.lang.String[])" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:10: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:10: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:10: JML caller invariant is false on reentering calling method (Caller: tt.A.main(java.lang.String[]), Callee: tt.C.m())" ,"/tt/A.java:2: Associated declaration" ,"END" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.main(java.lang.String[])" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.main(java.lang.String[])" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.main(java.lang.String[])" ,"/tt/A.java:2: Associated declaration" ); } // FIXME - many outputs need column numbers @Test public void testInheritedMethod() { addMockFile("$A/tt/B.java","package tt; public class B extends tt.C implements I { \n" +"//@ also ensures i == 2; \n" +"public void m() {} ; \n" +"}\n" ); addMockFile("$A/tt/C.java","package tt; public class C implements I { \n" +"static public int i=0; \n" +"//@ ensures i == 3; \n" +" public void m() {} ; \n" +"}\n" ); addMockFile("$A/tt/I.java","package tt; public interface I { \n" +"//@ ensures false; \n" +"public void m(); \n" +"}\n" ); helpTCX("tt.A","package tt; public class A extends tt.B { \n" +"//@ also ensures i == 2; \n" +"public void m() {} ; \n" +"public static void main(String[] args) { \n" +"System.out.println(\"A\"); \n" +" (new A()).m(); \n" +"System.out.println(\"END\"); \n" +"}} \n" ,"A" ,"/tt/A.java:3: JML postcondition is false" ,"/$A/tt/I.java:2: Associated declaration" ,"/tt/A.java:3: JML postcondition is false" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:3: JML postcondition is false" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:3: JML postcondition is false" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:6: JML postcondition is false" ,"/$A/tt/I.java:2: Associated declaration" ,"/tt/A.java:6: JML postcondition is false" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:6: JML postcondition is false" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:6: JML postcondition is false" ,"/tt/A.java:2: Associated declaration" ,"END" ); } @Test public void testInheritedMethod2() { addMockFile("$A/tt/B.java","package tt; public class B extends ttt.C implements I { \n" +"//@ also private behavior ensures i == 2; \n" +"public void m() {} ; \n" +"}\n" ); addMockFile("$A/ttt/C.java","package ttt; public class C implements tt.I { \n" +"static public int i=0; \n" +"//@ ensures i == 3; \n" +" public void m() {} ; \n" +"}\n" ); addMockFile("$A/tt/I.java","package tt; public interface I { \n" +"//@ ensures false; \n" +"public void m(); \n" +"}\n" ); helpTCX("tt.A","package tt; public class A extends tt.B { \n" +"//@ also ensures i == 2; \n" +"public void m() {} ; \n" +"public static void main(String[] args) { \n" +"System.out.println(\"A\"); \n" +" (new A()).m(); \n" +"System.out.println(\"END\"); \n" +"}} \n" ,"A" ,"/tt/A.java:3: JML postcondition is false" ,"/$A/tt/I.java:2: Associated declaration" ,"/tt/A.java:3: JML postcondition is false" ,"/$A/ttt/C.java:3: Associated declaration" ,"/tt/A.java:3: JML postcondition is false" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:6: JML postcondition is false" ,"/$A/tt/I.java:2: Associated declaration" ,"/tt/A.java:6: JML postcondition is false" ,"/$A/ttt/C.java:3: Associated declaration" ,"/tt/A.java:6: JML postcondition is false" ,"/tt/A.java:2: Associated declaration" ,"END" ); } @Test public void testInheritedMethod3() { addMockFile("$A/tt/C.java","package tt; public class C { \n" +"static public int i=0; \n" +"//@ requires kc == 3; ensures i == 3; \n" +" public void m(int kc) {} ; \n" +"}\n" ); addMockFile("$A/tt/B.java","package tt; public class B extends C { \n" +"//@ also requires kb == 2; ensures i == 2; \n" +"public void m(int kb) {} ; \n" +"}\n" ); helpTCX("tt.A","package tt; public class A extends tt.B { \n" +"//@ also requires ka==1; ensures i == 1; \n" +"public void m(int ka) {} ; \n" +"public static void main(String[] args) { \n" +" System.out.println(\"C\"); (new A()).m(3); \n" +" System.out.println(\"B\"); (new A()).m(2); \n" +" System.out.println(\"A\"); (new A()).m(1); \n" +" System.out.println(\"NONE\"); (new A()).m(0); \n" +"System.out.println(\"END\"); \n" +"}} \n" ,"C" ,"/tt/A.java:3: JML postcondition is false" ,"/$A/tt/C.java:3: Associated declaration" ,"/tt/A.java:5: JML postcondition is false" ,"/$A/tt/C.java:3: Associated declaration" ,"B" ,"/tt/A.java:3: JML postcondition is false" ,"/$A/tt/B.java:2: Associated declaration" ,"/tt/A.java:6: JML postcondition is false" ,"/$A/tt/B.java:2: Associated declaration" ,"A" ,"/tt/A.java:3: JML postcondition is false" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:7: JML postcondition is false" ,"/tt/A.java:2: Associated declaration" ,"NONE" ,"/tt/A.java:8: JML precondition is false" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:2: JML precondition is false" ,"END" ); } @Test public void testAssignable() { helpTCX("tt.A","package tt; public class A {\n" +" static public int j=0,k;\n" +" //@ requires i > 0;\n" +" //@ modifies j;\n" +" //@ ensures j == i;\n" +" public static void setj(int i) {\n" +" j = i;\n" +" }\n" +" //@ ensures j == 1;\n" +" public static void main(String[] args) {\n" +" setj(0);\n" +" }\n" +"}\n" ,"/tt/A.java:11: JML precondition is false" ,"/tt/A.java:3: Associated declaration" ,"/tt/A.java:3: JML precondition is false" ,"/tt/A.java:10: JML postcondition is false" ,"/tt/A.java:9: Associated declaration" ); } @Test public void testAssignable2() { helpTCX("tt.A","package tt; public class A {\n" +" static public int j=0,k;\n" +" //@ requires i > 0;\n" +" //@ modifies j;\n" +" //@ ensures j == i;\n" +" public static void setj(int i) {\n" +" k = i;\n" // Intentionally k - but precondition is false, so does not violate the assignable clause +" }\n" +" //@ ensures j == 1;\n" +" public static void main(String[] args) {\n" +" setj(0);\n" +" }\n" +"}\n" ,"/tt/A.java:11: JML precondition is false" ,"/tt/A.java:3: Associated declaration" ,"/tt/A.java:3: JML precondition is false" ,"/tt/A.java:10: JML postcondition is false" ,"/tt/A.java:9: Associated declaration" ); } @Ignore // FIXME - assignable turned off for RAC @Test public void testAssignable3() { helpTCX("tt.A","package tt; public class A {\n" +" static public int j=0,k;\n" +" //@ requires i > 0;\n" +" //@ modifies k;\n" +" //@ ensures j == i;\n" +" public static void setj(int i) {\n" +" j = i;\n" +" }\n" +" //@ ensures j == 1;\n" +" public static void main(String[] args) {\n" +" setj(1);\n" +" }\n" +"}\n" ,"/tt/A.java:7: JML An item is assigned that is not in the assignable statement: .tt.A.j" ,"/tt/A.java:4: Associated declaration" // FIXME - this does not make sense ); } @Test public void testLabelledStatement() { helpTCX("tt.A","package tt; class A { public static void main(String[] args) { new A().m(); }\n public void m() { int i=5; \n outer: while (i > 0) { --i; } \n /*@ assert i == 0; */ \n System.out.println(\"END\"); }}" ,"END"); } @Test public void testLabelledStatement2() { helpTCX("tt.A","package tt; class A { public static void main(String[] args) { new A().m(); }\n public void m() { int i=5; \n outer: while (i > 0) { --i; } \n /*@ assert i == -1; */ }}" ,"/tt/A.java:4: JML assertion is false" ); } @Test public void testInitializer() { helpTCX("tt.A","package tt; public class A { public static void main(String[] args) { }\n { //@ assert false; \n } " + "}" ); // The assert is not executed } @Test public void testInitializer2() { helpTCX("tt.A","package tt; public class A { public static void main(String[] args) { A a = new A(); System.out.println(\"END\"); }\n { //@ assert false; \n \n } " + "}" ,"/tt/A.java:2: JML assertion is false" ,"END"); } @Test public void testInitializer2a() { helpTCX("tt.A","package tt; public class A { public static void main(String[] args) { A a = new A(); System.out.println(\"END\"); }\n " + "}" ,"END"); } @Test public void testInitializer3() { helpTCX("tt.A","package tt; public class A { public static void main(String[] args) { }\n static { //@ assert false; \n } " + "}" ,"/tt/A.java:2: JML assertion is false"); } @Test public void testChangedParam() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" //@ ensures \\result == i;\n" +" public static int m1bad(int i) {\n" +" return (i+=1) ;\n" +" }\n" +" //@ ensures \\result == i+1;\n" +" public static int m1good(int i) {\n" +" return (i+=1) ;\n" +" }\n" +" public static void main(String ... args) {\n" +" m1good(2);\n" +" m1bad(4);\n" +" }\n" +"}" ,"/tt/TestJava.java:4: JML postcondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"/tt/TestJava.java:13: JML postcondition is false" ,"/tt/TestJava.java:3: Associated declaration" ); } @Test public void testSynchronized() { helpTCX("tt.A","package tt; class A { public static void main(String[] args) { new A().m(); }\n public void m() { int i; \n synchronized (this) { i = 0; } \n}}" ); } @Test public void testForEach3() { helpTCX("tt.A","package tt; class A { public static void main(String[] args) { java.util.List<Integer> list = new java.util.LinkedList<Integer>(); list.add(0); m(list); }" +"static void m(java.util.List<Integer> list) { \n " +"int sum = 0; \n" +"//@ loop_invariant sum >= 0; \n" +"for (int o: list) { sum += o; } \n" +"//@ assert sum >= 0; \n" +"}}" ); } @Test public void testForEach3bad() { helpTCX("tt.A","package tt; class A { public static void main(String[] args) { java.util.List<Integer> list = new java.util.LinkedList<Integer>(); list.add(0); m(list);}" +"static void m(java.util.List<Integer> list) { \n " +"int sum = 0; \n" +"//@ loop_invariant sum >= 0; \n" +"for (int o: list) { sum += o; } \n" +"//@ assert sum > 0; \n" +"}}" ,"/tt/A.java:5: JML assertion is false" ); } @Test public void testForEach4() { helpTCX("tt.A","package tt; class A { public static void main(String[] args) { Integer[] aa = new Integer[]{1,2,3}; m(aa); }" +"static void m(Integer[] list) { \n " +"int sum = 0; \n" +"//@ loop_invariant sum >= 0; \n" +"for (int o: list) { /*@ assume o >= 0; */ sum += o; } \n" +"//@ assert sum >= 0; \n" +"}}" ); } @Test public void testForEach4bad() { helpTCX("tt.A","package tt; class A { public static void main(String[] args) { Integer[] aa = new Integer[]{0,0,0}; m(aa); }" +"static void m(Integer[] list) { \n " +"int sum = 0; \n" +"//@ loop_invariant sum >= 0; \n" +"for (int o: list) { /*@ assume o >= 0; */ sum += o; } \n" +"//@ assert sum > 0; \n" +"}}" ,"/tt/A.java:5: JML assertion is false" ); } @Test public void testOldClause() { helpTCX("tt.TestJava", "package tt; \n" + "public class TestJava { public static void main(String[] args) { m(6); k = 6; m(6); } \n" + " static public int k = 5;\n" + " //@ old int kk = k; requires i > kk; assignable k; ensures k == i+1; ensures kk == 5;\n" + " //@ also\n" + " //@ old int kk = k+1; requires i < kk; assignable k; ensures k == i-1; ensures kk == 7;\n" + " static public void m(int i) {\n" + " if (i>k) k = i+1; else k = i-1;\n" + " }\n" + "}" ); } @Test public void testOldClause2() { helpTCX("tt.TestJava", "package tt; \n" + "public class TestJava { public static void main(String[] args) { m(6); k = 6; m(4); } \n" + " static public int k = 5;\n" + " //@ old int kk = k;\n" + " //@ {| requires i > kk; assignable k; ensures k == i+1; ensures kk == 5;\n" + " //@ also\n" + " //@ requires i < kk; assignable k; ensures k == i-1; ensures kk == 6;\n" + " //@ |}\n" + " static public void m(int i) {\n" + " if (i>k) k = i+1; else k = i-1;\n" + " }\n" + "}" ); } }