package org.jmlspecs.openjmltest.testcases; import org.jmlspecs.openjmltest.RacBase; import org.junit.Assert; 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 racnew2 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 { rac = ordrac; jdkrac = false; //noCollectDiagnostics = true; print = true; super.setUp(); //main.addOptions("-verboseness", "4"); expectedNotes = 0; } /** Tests a copying modifiers and annotations */ // We really need to inspect the output to see that the result is OK. But at least this tests that it does not crash @Test public void testMods() { helpTCX("tt.TestJava","package tt; import org.jmlspecs.annotation.*; import java.lang.annotation.*; \n" + " @Retention(RetentionPolicy.RUNTIME) \n" + " @interface A { }\n" + " public class TestJava { public static void main(String... args) {}" + "}" ); } @Test public void testMods2() { helpTCX("tt.TestJava","package tt; import org.jmlspecs.annotation.*; import java.lang.annotation.*; \n" + " public class TestJava { \n" + " @NonNull protected void m() {} \n" + " public static void main(String... args) {}" + "}" ); } @Test public void testMethodCall() { helpTCX("tt.TestJava","package tt; import org.jmlspecs.annotation.*; import java.lang.annotation.*; \n" + " public class TestJava { \n" + " //@ ensures \\result > 0; \n" + " public static int m(int i) {return i;} \n" + " public static void main(String... args) {\n" + " System.out.println(\"START\"); \n" + " int k = m(1);\n" + " System.out.println(\"MID\"); \n" + " k += 5 + m(-1);\n" + " System.out.println(\"END\"); \n" + " }" + "}" ,"START" ,"MID" ,"/tt/TestJava.java:4: JML postcondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"/tt/TestJava.java:9: JML postcondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"END" ); } /** Tests new array */ @Test public void testNewArray() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " String[] a = new String[]{\"abc\",\"def\"};\n" + " int i = a.length; \n" + " //@ assert i == 2; \n" + " String[][] aa = new String[][]{{\"abc\",\"defz\"},{\"g\",\"h\",\"i\"}};\n" + " i = aa.length; \n" + " boolean b = aa[1][0].equals(\"g\"); \n" + " //@ assert i == 2; \n" + " //@ assert aa[1].length == 3; \n" + " //@ assert (new int[]{1,2,3}).length == 3; \n" + " //@ assert (new int[]{1,2,3})[1] == 2; \n" + " String[][] aaa = new String[1][2]; \n" + " //@ assert aaa.length == 1; \n" + " //@ assert aaa[0].length == 2; \n" + " //@ assert aaa[0][0] == null; \n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"END" ); } /** Tests new array */ @Test public void testNewArray2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " int[] x = new int[3]; \n" + " //@ assert x.length == 3; \n" + " //@ assert x[0] == 0; \n" + " String[] a = {\"abc\",\"def\"};\n" + " int i = a.length; \n" + " //@ assert i == 2; \n" + " String[][] aa = {{\"abc\",\"defz\"},{\"g\",\"h\",\"i\"}};\n" + " i = aa.length; \n" + " boolean b = aa[1][0].equals(\"g\"); \n" + " //@ assert i == 2; \n" + " //@ assert aa[1].length == 3; \n" + " String[][] aaa = new String[1][2]; \n" + " //@ assert aaa.length == 1; \n" + " //@ assert aaa[0].length == 2; \n" + " //@ assert aaa[0][0] == null; \n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"END" ); } /** Tests new object */ @Test public void testNewObject() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " TestJava a = new TestJava();\n" + " int i = a.m(10); \n" + " //@ assert i == 11; \n" + " TestJava aa = new TestJava() { public int m(int i) { return i + 2; } };\n" + " i = aa.m(10); \n" + " //@ assert i == 12; \n" + " System.out.println(\"END\"); \n" + " } \n" + " public int m(int i) { return i + 1; } \n" + "}" ,"END" ); } /** Tests new object in JML */ @Test public void testNewObject2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " // @ assert (new TestJava()).m(15) == 16;\n" + " //@ assert (new TestJava() { public int m(int i) { return i + 2; } }).m(15) == 17;\n" + " System.out.println(\"END\"); \n" + " } \n" + " public int m(int i) { return i + 1; } \n" + "}" ,"END" ); } /** Tests new object in JML */ @Test public void testNewObject3() { helpTCX("tt.TestJava","package tt; public class TestJava { \n" + "public int k;\n" + "//@requires i > 0; ensures k == i;\n" + "public TestJava(int i) { k = i < 2 ? i : 5; }\n" + "public static void main(String[] args) { \n" + " System.out.println(\"TestJava - 1\");\n" + " TestJava t = new TestJava(1);\n" + " System.out.println(\"TestJava - 0\");\n" + " t = new TestJava(0);\n" + " System.out.println(\"TestJava - 2\");\n" + " //@ assert (new TestJava(2)).k == 2;\n" + " System.out.println(\"TestJava - 0\");\n" + " //@ assert (new TestJava(0)).k == 0;\n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"TestJava - 1" ,"TestJava - 0" ,"/tt/TestJava.java:9: JML precondition is false" // caller check -- TestJava(0) ,"/tt/TestJava.java:3: Associated declaration" ,"/tt/TestJava.java:3: JML precondition is false" // callee check ,"TestJava - 2" ,"/tt/TestJava.java:4: JML postcondition is false" // callee check ,"/tt/TestJava.java:3: Associated declaration" ,"/tt/TestJava.java:11: JML postcondition is false" // caller check ,"/tt/TestJava.java:3: Associated declaration" ,"/tt/TestJava.java:11: JML assertion is false" ,"TestJava - 0" ,"/tt/TestJava.java:13: JML a method called in a JML expression is undefined because its precondition is false" ,"/tt/TestJava.java:3: Associated declaration" ,"/tt/TestJava.java:3: JML precondition is false" ,"END" ); } /** Tests a simple try-finally block */ @Test public void testTry() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " int i; try { i = 0; } finally { i = 1; } //@ assert i == 1; \n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"END" ); } /** Test skip statement */ @Test public void testSkip() { helpTCX("tt.A","package tt; class A { public static void main(String[] args) { int i ;;; i = 9;;;; //@ assert i == 9; \n }\n \n}" ); } /** Test synchronized statement with this */ @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 synchronized statement with null lock */ @Test public void testSynchronized2() { expectedRACExit = 1; helpTCX("tt.A","package tt; class A { public static void main(String[] args) throws Exception { \n" + "new A().m(); }\n " + "public void m() throws RuntimeException { /*@ nullable*/ Object o = null; int i; \n " + "synchronized (o) { i = 0; } \n}}" ,"/tt/A.java:4: JML An object may be illegally null" ,"Exception in thread \"main\" java.lang.NullPointerException" ,"\tat tt.A.m(A.java:4)" ,"\tat tt.A.main(A.java:2)" ); } /** Tests a simple try-throw-catch block */ @Test public void testThrow() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " int i; try { i = 0; throw new RuntimeException(); } catch (RuntimeException e) { i = 1; } //@ assert i == 1; \n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"END" ); } /** Tests binary operators */ @Test public void testBinary() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " int a=5,b=6,c; boolean f, e= true,d=false; \n" + " c = a + b; \n" + " //@ assert c == a + 6; \n" + " c = a - b; \n" + " //@ assert a - c == 6; \n" + " c = a * b; \n" + " //@ assert b == c / 5; \n" + " c = b / (a - 3); \n" + " //@ assert b == c * 2; \n" + " c = b % a; \n" + " //@ assert a % b == a && c == 1; \n" + " f = a < b ; \n" + // FIXME - this line causes a problem " //@ assert f && a <= b; \n" + " f = a <= b ; \n" + " //@ assert f && a < b; \n" + " f = a > b ; \n" + " //@ assert !f && a >= b; \n" + " f = a >= b ; \n" + " //@ assert !f && a > b; \n" + // FIXME - add equalities among various types, && || & ^ | logical and bit // FIXME - test JML binary " System.out.println(\"END\"); \n" + " } \n" + "}" ,"/tt/TestJava.java:18: JML assertion is false" ,"/tt/TestJava.java:20: JML assertion is false" ,"END" ); } /** Tests binary operators */ @Test public void testShift() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " int a=5,b=6,c=100; \n" + " int d = a << b; \n" + " d = a << c; \n" + // ERROR " d = a >> b; \n" + " d = a >> c; \n" + // ERROR " d = a >>> b; \n" + " d = a >>> c; \n" + // ERROR " long e = 20L << b; \n" + " e = 20L << (b+40); \n" + // OK " e = 20L << c; \n" + // ERROR " System.out.println(\"END\"); \n" + " } \n" + "}" ,"/tt/TestJava.java:4: JML shift amount is out of expected range" ,"/tt/TestJava.java:6: JML shift amount is out of expected range" ,"/tt/TestJava.java:8: JML shift amount is out of expected range" ,"/tt/TestJava.java:11: JML shift amount is out of expected range" ,"END" ); } /** Tests binary operators */ @Test public void testConditional() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " int a=5,b=6,c=100; \n" + " int d = a < 10 ? b + 3 : c-40; \n" + " System.out.println(d); \n" + " //@ assert (c > 4? a + 3 : b + 3) == 9; \n" + // ERROR " System.out.println(\"END\"); \n" + " } \n" + "}" ,"9" ,"/tt/TestJava.java:5: JML assertion is false" ,"END" ); } /** Tests unary operators */ // FIXME - test unary with expressions in ++ -- @Test public void testUnary() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " int a=5,b=0,c=0; boolean e=true,d=false; \n" + " b = a++; \n" + " //@ assert b+1 == a; \n" + " b = a--; \n" + " //@ assert b-1 == a; \n" + " c = a; b = ++a; \n" + " //@ assert b == a && c+1 == b; \n" + " b = --a; \n" + " //@ assert b == a && c == b; \n" + " b = -a; \n" + " //@ assert b == -5; \n" + " e = d ; \n" + " //@ assert !d; \n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"END" ); } /** Tests parens operators */ @Test public void testParens() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " int a=5,b=6,c=0; boolean e=true,d=false; \n" + " c = (a*b)+3*b-2*(a-(((b)))); \n" + " //@ assert ((((c) == 50))); \n" + " c = b / (((a))); \n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"END" ); } /** Tests switch statement */ @Test public void testBreak() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m(0); m(2); m(3); m(5); \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(int i) { \n" + " out: { \n" + " in: { \n" + " System.out.print(i + \"A\");\n" + // Unlabelled breaks are not allowed for blocks " if (i == 2) break in;\n" + " if (i == 3) break out;\n" + " System.out.print(\"B\");\n" + " }\n" + " System.out.print(\"C\");\n" + " if (i == 5) break out;\n" + " System.out.print(\"D\");\n" + " }\n" + " System.out.println(\"Z\");\n" + " } \n" + "}" ,"0ABCDZ" ,"2ACDZ" ,"3AZ" ,"5ABCZ" ,"END" ); } @Test public void testSimpleBreak() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m(0); m(2); \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(int i) { \n" + " in: { \n" + " System.out.print(i + \"A\");\n" + // Unlabelled breaks are not allowed for blocks " if (i == 2) break in;\n" + " System.out.print(\"B\");\n" + " }\n" + " System.out.println(\"C\");\n" + " }\n" + "}" ,"0ABC" ,"2AC" ,"END" ); } /** Tests switch statement */ @Test public void testSwitch() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m(0); m(1); m(2); m(3); \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(int i) { \n" + " switch (i) { \n" + " case 0: //@ assert i == 0; \n break; \n" + " case 1: //@ assert i == 0; \n break; \n" + " case 2: //@ assert i == 2; \n break; \n" + " default: //@ assert i == 0; \n break; \n" + " }}\n" + "}" ,"/tt/TestJava.java:9: JML assertion is false" ,"/tt/TestJava.java:13: JML assertion is false" ,"END" ); } /** Tests switch statement with declaration in a case*/ @Test public void testSwitch2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m(0); m(1); m(2); m(3); \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(int i) { \n" + " switch (i) { \n" + " case 0: int k = 0; //@ assert i == k; \n \n" + " case 1: k=1; //@ assert i == k; \n break; \n" + " case 2: k=2; //@ assert i == k; \n break; \n" + " default: //@ assert i == 0; \n break; \n" + " }}\n" + "}" ,"/tt/TestJava.java:9: JML assertion is false" // case 0 falls through ,"/tt/TestJava.java:13: JML assertion is false" ,"END" ); } /** Tests switch statement with block breaks */ @Test public void testSwitch3() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m(0); m(1); m(2); m(3); \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(int i) { \n" + " System.out.print(i); \n" + " out: { switch (i) { \n" + " case 0: break; \n" + " case 1: break out; \n" + " case 2: in: { break in; } System.out.print(\"X\"); break; \n" + " default: in: { if (i == 3) break; } System.out.print(\"Y\"); break; \n" + " }\n" + " System.out.print(\"Z\"); }\n" + " }\n" + "}" ,"0Z12XZ3ZEND" ); } /** Tests switch statement */ @Test public void testSwitchShort() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m((short)0); m((short)1); m((short)2); m((short)3); \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(short i) { \n" + " switch (i) { \n" + " case 0: //@ assert i == 0; \n break; \n" + " case 1: //@ assert i == 0; \n break; \n" + " case 2: //@ assert i == 2; \n break; \n" + " default: //@ assert i == 0; \n break; \n" + " }}\n" + "}" ,"/tt/TestJava.java:9: JML assertion is false" ,"/tt/TestJava.java:13: JML assertion is false" ,"END" ); } /** Tests switch statement */ @Test public void testSwitchShort2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m((short)0); m((short)1); m((short)2); m((short)3); \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(short s) { Short i = new Short(s); \n" + " switch (i) { \n" + " case 0: //@ assert i == 0; \n break; \n" + " case 1: //@ assert i == 0; \n break; \n" + " case 2: //@ assert i == 2; \n break; \n" + " default: //@ assert i == 0; \n break; \n" + " }}\n" + "}" ,"/tt/TestJava.java:9: JML assertion is false" ,"/tt/TestJava.java:13: JML assertion is false" ,"END" ); } /** Tests switch statement */ @Test public void testSwitchByte() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m((byte)0); m((byte)1); m((byte)2); m((byte)3); \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(byte i) { \n" + " switch (i) { \n" + " case 0: //@ assert i == 0; \n break; \n" + " case 1: //@ assert i == 0; \n break; \n" + " case 2: //@ assert i == 2; \n break; \n" + " default: //@ assert i == 0; \n break; \n" + " }}\n" + "}" ,"/tt/TestJava.java:9: JML assertion is false" ,"/tt/TestJava.java:13: JML assertion is false" ,"END" ); } /** Tests switch statement */ @Test public void testSwitchByte2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m((byte)0); m((byte)1); m((byte)2); m((byte)3); \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(byte s) { Byte i = new Byte(s); \n" + " switch (i) { \n" + " case 0: //@ assert i == 0; \n break; \n" + " case 1: //@ assert i == 0; \n break; \n" + " case 2: //@ assert i == 2; \n break; \n" + " default: //@ assert i == 0; \n break; \n" + " }}\n" + "}" ,"/tt/TestJava.java:9: JML assertion is false" ,"/tt/TestJava.java:13: JML assertion is false" ,"END" ); } /** Tests switch statement */ @Test public void testSwitchInteger2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m(0); m(1); m(2); m(3); \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(int s) { Integer i = new Integer(s); \n" + " switch (i) { \n" + " case 0: //@ assert i == 0; \n break; \n" + " case 1: //@ assert i == 0; \n break; \n" + " case 2: //@ assert i == 2; \n break; \n" + " default: //@ assert i == 0; \n break; \n" + " }}\n" + "}" ,"/tt/TestJava.java:9: JML assertion is false" ,"/tt/TestJava.java:13: JML assertion is false" ,"END" ); } /** Tests switch statement */ @Test public void testSwitchInteger2Null() { helpTCX("tt.TestJava","package tt; /*@ nullable_by_default*/public class TestJava { public static void main(String[] args) { \n" + " try { m(0); } catch (Exception e) { System.out.println(\"EXCEPTION THROWN\"); } \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(int s) { Integer i = null; \n" + " switch (i) { \n" + " case 0: //@ assert i == 0; \n break; \n" + " case 1: //@ assert i == 0; \n break; \n" + " case 2: //@ assert i == 2; \n break; \n" + " default: //@ assert i == 0; \n break; \n" + " }}\n" + "}" ,"/tt/TestJava.java:6: JML Attempt to unbox a null object" ,"EXCEPTION THROWN" ,"END" ); } /** Tests switch statement */ @Test public void testSwitchChar() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m('a'); m('b'); m('c'); m('d'); \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(char i) { \n" + " switch (i) { \n" + " case 'a': //@ assert i == 'a'; \n break; \n" + " case 'b': //@ assert i == 'a'; \n break; \n" + " case 'c': //@ assert i == 'c'; \n break; \n" + " default: //@ assert i == 'a'; \n break; \n" + " }}\n" + "}" ,"/tt/TestJava.java:9: JML assertion is false" ,"/tt/TestJava.java:13: JML assertion is false" ,"END" ); } /** Tests switch statement */ @Test public void testSwitchChar2() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " m('a'); m('b'); m('c'); m('d'); \n" + " System.out.println(\"END\"); \n" + " } \n" + " static void m(char s) { Character i = new Character(s);\n" + " switch (i) { \n" + " case 'a': //@ assert i == 'a'; \n break; \n" + " case 'b': //@ assert i == 'a'; \n break; \n" + " case 'c': //@ assert i == 'c'; \n break; \n" + " default: //@ assert i == 'a'; \n break; \n" + " }}\n" + "}" ,"/tt/TestJava.java:9: JML assertion is false" ,"/tt/TestJava.java:13: JML assertion is false" ,"END" ); } /** Tests type test and type cast expressions */ @Test public void testTypeCast() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " Integer i = new Integer(10); \n" + " Object o = i; \n" + " Integer ii = (Integer)o; \n" + " System.out.println(ii); \n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"10" ,"END" ); } /** Tests a bad cast */ @Test public void testTypeCast2() { expectedRACExit = 1; main.addOptions("-racShowSource"); helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " Boolean i = Boolean.TRUE; \n" + " Object o = i; \n" + " Integer ii = (Integer)o;\n" + " System.out.println(ii); \n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"/tt/TestJava.java:4: JML A cast is invalid - from java.lang.Object to java.lang.Integer" ," Integer ii = (Integer)o;" ," ^" ,"Exception in thread \"main\" java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Integer" ,"\tat tt.TestJava.main(TestJava.java:4)" ); } /** Tests a type test with a cast */ @Test public void testTypeCast3() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " Boolean b = Boolean.TRUE; \n" + " Integer i = new Integer(10); /*@ nullable */Integer ii = null; \n" + " Object o = i; \n" + " if (o instanceof Integer) { ii = (Integer)o; }\n" + " o = b; \n" + " if (o instanceof Integer) { ii = (Integer)o; }\n" + " System.out.println(ii); \n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"10" ,"END" ); } /** Test a type tests and casts in JML */ @Test public void testTypeTest4() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " Boolean b = Boolean.TRUE; \n" + " Integer i = new Integer(10); /*@ nullable */Integer ii = null; \n" + " Object o = i; \n" + " //@ assert o instanceof Integer; \n" + " o = b; \n" + " //@ assert o instanceof Integer; \n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"/tt/TestJava.java:7: JML assertion is false" ,"END" ); } /** Test a type tests and casts in JML */ @Test public void testTypeCast5() { expectedRACExit = 1; helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " Boolean b = Boolean.TRUE; \n" + " Integer i = new Integer(10); /*@ nullable */Integer ii = null; \n" + " Object o = i; \n" + " //@ assert (Integer)o != null; \n" + " o = b; \n" + " //@ assert (Integer)o != null; \n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"/tt/TestJava.java:7: JML A cast is invalid - from java.lang.Object to java.lang.Integer" ,"Exception in thread \"main\" java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Integer" ,"\tat tt.TestJava.main(TestJava.java:7)" ); } /** Test a type tests and casts in JML */ @Test public void testTypeCast6() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " Boolean b = Boolean.TRUE; \n" + " Integer i = new Integer(10); /*@ nullable */Integer ii = null; \n" + " Object o = i; \n" + " //@ assert o instanceof Integer && (Integer)o != null; \n" + " o = b; \n" + " //@ assert o instanceof Integer && (Integer)o != null; \n" + " System.out.println(\"END\"); \n" + " } \n" + "}" ,"/tt/TestJava.java:7: JML assertion is false" ,"END" ); } /** Tests the JML lbl lblpos and lblneg expressions */ @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 (char)(i+60) ) != 0; \n" + "//@ assert (\\lbl BOOLEAN (i == 0)) ; \n" + "//@ assert (\\lbl OBJECT o) == null; \n" + "//@ assert (\\lbl NULL null) == null; \n" + "//@ assert (\\lbl STRING \"abc\") != null; \n" + "//@ assert (\\lblpos POST (i!=0)); \n" + "//@ assert !(\\lblpos POSF (i==0)); \n" + "//@ assert (\\lblneg NEGT (i!=0)); \n" + "//@ assert !(\\lblneg NEGF (i==0)); \n" + "//@ assert !(\\lblpos POST (i!=0)); \n" + "//@ assert (\\lblneg NEGF (i==0)); \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 = B" ,"LABEL BOOLEAN = false" ,"/tt/TestJava.java:14: JML assertion is false" ,"LABEL OBJECT = null" ,"LABEL NULL = null" ,"LABEL STRING = abc" ,"LABEL POST = true" ,"LABEL NEGF = false" ,"LABEL POST = true" ,"/tt/TestJava.java:22: JML assertion is false" ,"LABEL NEGF = false" ,"/tt/TestJava.java:23: JML assertion is false" ,"END" ); } /** Tests the JML lbl expression when the argument is a literal */ @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 4) != 0; \n" + "//@ assert (\\lbl SHORT (short)(1)) != 0; \n" + "//@ assert (\\lbl LONG 2L) != 0; \n" + "//@ assert (\\lbl BYTE (byte)(3)) != 0; \n" + "//@ assert (\\lbl FLOAT 5.0f) != 0; \n" + "//@ assert (\\lbl DOUBLE 6.0) != 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" ); } /** A misc early test case for lbl expressions */ @Test public void testLabel() { main.addOptions("-racShowSource"); helpTCX("tt.TestJava","package tt; public class TestJava { /*@ assignable \\everything; */ public static void main(String[] args) { \n" + " m(1); m(0); \n" + " System.out.println(\"END\"); } static public int k = 0; \n" + " /*@ assignable \\everything; ensures (\\lbl ENS k == 1); */ \n" + " static public void m(int i) { System.out.println(\"i = \" + i ); k = i; } " + "}" ,"i = 1" ,"LABEL ENS = true" ,"LABEL ENS = true" ,"i = 0" ,"LABEL ENS = false" ,"/tt/TestJava.java:5: JML postcondition is false" ," static public void m(int i) { System.out.println(\"i = \" + i ); k = i; } }" ," ^" ,"/tt/TestJava.java:4: Associated declaration: /tt/TestJava.java:5: " ," /*@ assignable \\everything; ensures (\\lbl ENS k == 1); */ " ," ^" ,"LABEL ENS = false" ,"/tt/TestJava.java:2: JML postcondition is false" ," m(1); m(0); " ," ^" ,"/tt/TestJava.java:4: Associated declaration: /tt/TestJava.java:2: " ," /*@ assignable \\everything; ensures (\\lbl ENS k == 1); */ " ," ^" ,"END" ); } /** A misc early test case for lbl expressions */ @Test public void testLabel2() { helpTCX("tt.TestJava","package tt; public class TestJava { /*@ assignable \\everything; */ public static void main(String[] args) { \n" + " m(1); m(0); \n" + " System.out.println(\"END\"); } static public int k = 0; \n" + " /*@ assignable \\everything; ensures (\\lblneg ENS (\\lbl RES k) == 1); */ \n" + " static public void m(int i) { k = i; return; } " + "}" ,"LABEL RES = 1" ,"LABEL RES = 1" ,"LABEL RES = 0" ,"LABEL ENS = false" ,"/tt/TestJava.java:5: JML postcondition is false" ,"/tt/TestJava.java:4: Associated declaration" ,"LABEL RES = 0" ,"LABEL ENS = false" ,"/tt/TestJava.java:2: JML postcondition is false" ,"/tt/TestJava.java:4: Associated declaration" ,"END" ); } /** Checks one can do assignments in a model method. */ @Test public void testModelMethod() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " //@ assert m(); \n" + " //@ assert m(); \n" + " System.out.println(\"END\"); } \n" + " //@ ghost static int i = 0; \n" + " //@ ghost static int j = 0; \n" + " //@ model static boolean m() { j = 1; i+= 1; int k = 2; return i == 1; } " + "}" ,"/tt/TestJava.java:3: JML assertion is false" ,"END" ); } /** Checks select expressions. */ @Test public void testSelect() { expectedRACExit = 1; helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " //@ assert a[0] == 0; \n" + " //@ assert b != null && b[0] == 0; \n" + " //@ assert b[0] == 0; \n" + " System.out.println(\"END\"); } \n" + " static int[] a = { 0,1,2}; \n" + " /*@nullable*/ static int[] b = null;\n" + "}" ,"/tt/TestJava.java:3: JML assertion is false" ,"/tt/TestJava.java:4: JML A null object is dereferenced within a JML expression" ,"Exception in thread \"main\" java.lang.NullPointerException" ,"\tat tt.TestJava.main(TestJava.java:4)" ); } /** Checks select expressions. */ @Test public void testSelect2() { expectedRACExit = 1; helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " System.out.println(a[1]); \n" + " System.out.println(b[1]); \n" + " System.out.println(\"END\"); } \n" + " static int[] a = { 0,1,2}; \n" + " /*@nullable*/ static int[] b = null;\n" + "}" ,"1" ,"/tt/TestJava.java:3: JML A null object is dereferenced" ,"Exception in thread \"main\" java.lang.NullPointerException" ,"\tat tt.TestJava.main(TestJava.java:3)" ); } /** Checks a model class. */ @Test public void testModelClass() { main.addOptions("-keys=DEBUG"); helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " System.out.println(m(1)); \n" + " //@ debug System.out.println(p(new G())); \n" + " System.out.println(\"END\"); } \n" + " static <T> T m(T i) { return i; } \n" + " //@ model static public class G {} \n" + " //@ model static int p(G i) { return 5; } \n" + "}" ,"1" ,"5" ,"END" ); } /** Checks generic method. */ @Test public void testGenMethod() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " System.out.println(m(1)); \n" + " System.out.println(\"END\"); } \n" + " static <T> T m(T i) { return i; } \n" + "}" ,"1" ,"END" ); } /** Checks generic method. */ @Test public void testGenMethod2() { helpTCX("tt.TestJava","package tt; import java.util.*; public class TestJava { public static void main(String[] args) { \n" + " System.out.println(m(1)); \n" + " System.out.println(\"END\"); } \n" + " static /*@nullable*/ <T> List<?> m(T i) { return null; } \n" + "}" ,"null" ,"END" ); } /** Checks generic classes. */ @Test public void testGenClass() { helpTCX("tt.TestJava","package tt; public class TestJava { public static void main(String[] args) { \n" + " System.out.println(m(1)); \n" + " System.out.println(p(new G<Integer>())); \n" + " System.out.println(\"END\"); } \n" + " static <T> T m(T i) { return i; } \n" + " static public class G<T> {} \n" + " static <T> int p(G<?> i) { return 5; } \n" + "}" ,"1" ,"5" ,"END" ); } @Test public void testNoWarn() { helpTCX("tt.A","package tt; public class A { \n" +"static public int i = 0; \n " +"//@ ensures i == 0; \n " +"static public void m(int j) { i = j; } \n " +"public static void main(String[] args) { \n" +"m(1); \n" +"System.out.println(\"MID\"); \n" +"m(2); //@ nowarn Postcondition; \n" +"System.out.println(\"MID\"); \n" +"m(3); //@ nowarn; \n" +"System.out.println(\"MID\"); \n" +"m(4); //@ nowarn InvariantExit; \n" +"System.out.println(\"MID\"); \n" +"m(5); //@ nowarn InvariantExit,Postcondition; \n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:4: JML postcondition is false" ,"/tt/A.java:3: Associated declaration" ,"/tt/A.java:6: JML postcondition is false" ,"/tt/A.java:3: Associated declaration" ,"MID" ,"/tt/A.java:4: JML postcondition is false" ,"/tt/A.java:3: Associated declaration" ,"MID" ,"/tt/A.java:4: JML postcondition is false" ,"/tt/A.java:3: Associated declaration" ,"MID" ,"/tt/A.java:4: JML postcondition is false" ,"/tt/A.java:3: Associated declaration" ,"/tt/A.java:12: JML postcondition is false" ,"/tt/A.java:3: Associated declaration" ,"MID" ,"/tt/A.java:4: JML postcondition is false" ,"/tt/A.java:3: Associated declaration" ,"END" ); } @Test public void testNoWarn1() { helpTCX("tt.A","package tt; public class A { \n" +"//@ public invariant i == 0; \n " +"public int i = 0; \n " +"void m(int j) { i = j; } //@ nowarn InvariantExit; \n " +"public static void main(String[] args) { \n" +"new A().m(1); \n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:6: JML invariant is false on leaving method tt.A.m(int), returning to tt.A.main(java.lang.String[])" ,"/tt/A.java:2: Associated declaration" ,"END" ); } @Test public void testNoWarn2() { helpTCX("tt.A","package tt; public class A { \n" +"//@ public invariant i == 0; \n " +"public int i = 0; \n " +"void m(int j) { i = j; } //@ nowarn ; \n " +"public static void main(String[] args) { \n" +"new A().m(1); \n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:6: JML invariant is false on leaving method tt.A.m(int), returning to tt.A.main(java.lang.String[])" ,"/tt/A.java:2: Associated declaration" ,"END" ); } @Test public void testNoWarn3() { helpTCX("tt.A","package tt; public class A { \n" +"//@ public invariant i == 0; \n " +"public int i = 0; \n " +"void m(int j) { i = j; } //@ nowarn Precondition ; \n " +"public static void main(String[] args) { \n" +"new A().m(1); \n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:4: JML invariant is false on leaving method tt.A.m(int)" ,"/tt/A.java:2: Associated declaration" ,"/tt/A.java:6: JML invariant is false on leaving method tt.A.m(int), returning to tt.A.main(java.lang.String[])" ,"/tt/A.java:2: Associated declaration" ,"END" ); } @Test public void testNoWarn4() { helpTCX("tt.A","package tt; public class A { \n" +"//@ invariant i == 0; \n " +"int i = 0; \n " +"void m(int j) { i = j; } //@ nowarn Precondition, InvariantExit ; \n " +"public static void main(String[] args) { \n" +"new A().m(1); //@ nowarn InvariantExit; \n" +"System.out.println(\"END\"); \n" +"}}" ,"END" ); } @Test public void testReceiver1() { helpTCX("tt.A","package tt; public class A { \n" +"public A(int k) { i = k; } \n " +"public int i; \n " +"/*@ requires i == j; ensures \\result; */ public boolean m(int j) { return true; }\n " +"public static void main(String[] args) { boolean z; \n" +"A a = new A(1);\n" +"A b = new A(2);\n" +"z = a.m(1); \n" +"z = b.m(2) && z; \n" +"z = a.m(2) && z; \n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:10: JML precondition is false" ,"/tt/A.java:4: Associated declaration" ,"/tt/A.java:4: JML precondition is false" ,"END" ); } @Test public void testReceiver2() { helpTCX("tt.A","package tt; public class A { \n" +"/*@ assignable i; */ public A(int k) { i = k; } \n " +"static public int i; \n " +"/*@ requires i == j; ensures \\result; */ public boolean m(int j) { return true; }\n " +"public static void main(String[] args) { boolean z; \n" +"A a = new A(1);\n" +"A b = new A(2);\n" +"a.m(1); \n" +"b.m(2); \n" +"a.m(2); \n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:8: JML precondition is false" ,"/tt/A.java:4: Associated declaration" ,"/tt/A.java:4: JML precondition is false" ,"END" ); } @Test public void testReceiver3() { helpTCX("tt.A","package tt; public class A { \n" +"/*@ assignable i; */ public A(int k) { i = k; } \n " +"static public int i; \n " +"/*@ requires i == j; ensures \\result; */ static public boolean m(int j) { return true; }\n " +"public static void main(String[] args) { boolean z; \n" +"A a = new A(1);\n" +"A b = new A(2);\n" +"z = A.m(1); \n" +"z = A.m(2); \n" +"z = A.m(2); \n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:8: JML precondition is false" ,"/tt/A.java:4: Associated declaration" ,"/tt/A.java:4: JML precondition is false" ,"END" ); } @Test public void testReceiver4() { helpTCX("tt.A","package tt; public class A { \n" +"//@ ensures i == k; \n " +"public A(int k) { i = k; } \n" +" public int i; \n" +"public static void main(String[] args) { boolean z; \n" +"A a = new A(1);\n" +"System.out.println(\"END\"); \n" +"}}" ,"END" ); } @Test public void testReceiver4bad() { helpTCX("tt.A","package tt; public class A { \n" +"//@ ensures i == 1; \n " +"public A(int k) { i = k; } \n" +" public int i; \n" +"public static void main(String[] args) { boolean z; \n" +"A a = new A(1);\n" +"A b = new A(2);\n" +"System.out.println(\"END\"); \n" +"}}" ,"/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" ,"END" ); } @Test public void testLet() { helpTCX("tt.A","package tt; public class A { \n" +"//@ ensures (\\let int k = 1; \\result == k + i) ; \n " +"public static int m(int i) { return i + 1; } \n" +"//@ ensures (\\let int k = 1; \\result == k - i) ; \n " +"public static int mm(int i) { return i + 1; } \n" +"public static void main(String[] args) { \n" +"m(1);\n" +"mm(1);\n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:5: JML postcondition is false" ,"/tt/A.java:4: Associated declaration" ,"/tt/A.java:8: JML postcondition is false" ,"/tt/A.java:4: Associated declaration" ,"END" ); } @Test public void testLet2() { helpTCX("tt.A","package tt; public class A { \n" +"//@ ensures (\\let int k = 1, int j = k; \\result == j + i) ; \n " +"public static int m(int i) { return i + 1; } \n" +"//@ ensures (\\let int k = 1, int j = k; \\result == j - i) ; \n " +"public static int mm(int i) { return i + 1; } \n" +"public static void main(String[] args) { \n" +"m(1);\n" +"mm(1);\n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:5: JML postcondition is false" ,"/tt/A.java:4: Associated declaration" ,"/tt/A.java:8: JML postcondition is false" ,"/tt/A.java:4: Associated declaration" ,"END" ); } @Test public void testBoxingOnDeclaration() { helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] args) { \n" +"{ Integer i = 6;\n" +"int k = i;\n" +"//@ assert k == i;\n}\n" +"{ Boolean i = true;\n" +"boolean k = i;\n" +"//@ assert k == i;\n}\n" +"{ Short i = 6;\n" +"short k = i;\n" +"//@ assert k == i;\n}\n" +"{ Long i = 6L;\n" +"long k = i;\n" +"//@ assert k == i;\n}\n" +"{ Byte i = 6;\n" +"byte k = i;\n" +"//@ assert k == i;\n}\n" +"{ Double i = 6.0;\n" +"double k = i;\n" +"//@ assert k == i;\n}\n" +"{ Float i = 6.0f;\n" +"float k = i;\n" +"//@ assert k == i;\n}\n" +"{ Character i = 6;\n" +"char k = i;\n" +"//@ assert k == i;\n}\n" +"{ Integer i = 6;\n" +"int k = i;\n" +"//@ assert k == i+1;\n}\n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:37: JML assertion is false" ,"END" ); } @Test public void testBoxingOnNullDeclaration() { helpTCX("tt.A","package tt; /*@ nullable_by_default*/ public class A { \n" +"public static void main(String[] args) { \n" +"try { Integer i = null;\n" +"int k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Boolean i = null;\n" +"boolean k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Short i = null;\n" +"short k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Long i = null;\n" +"long k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Byte i = null;\n" +"byte k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Double i = null;\n" +"double k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Float i = null;\n" +"float k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Character i = null;\n" +"char k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:4: JML Attempt to unbox a null object" ,"/tt/A.java:8: JML Attempt to unbox a null object" ,"/tt/A.java:12: JML Attempt to unbox a null object" ,"/tt/A.java:16: JML Attempt to unbox a null object" ,"/tt/A.java:20: JML Attempt to unbox a null object" ,"/tt/A.java:24: JML Attempt to unbox a null object" ,"/tt/A.java:28: JML Attempt to unbox a null object" ,"/tt/A.java:32: JML Attempt to unbox a null object" ,"END" ); } @Test public void testBoxingOnAssignment() { helpTCX("tt.A","package tt; public class A { \n" +"public static void main(String[] args) { \n" +"{ Integer i; int k; i = 6;\n" +" k = i;\n" +"//@ assert k == i;\n}\n" +"{ Boolean i; boolean k; i = true;\n" +" k = i;\n" +"//@ assert k == i;\n}\n" +"{ Short i; short k; i = 6;\n" +" k = i;\n" +"//@ assert k == i;\n}\n" +"{ Long i; long k; i = 6L;\n" +" k = i;\n" +"//@ assert k == i;\n}\n" +"{ Byte i; byte k; i = 6;\n" +" k = i;\n" +"//@ assert k == i;\n}\n" +"{ Double i; double k; i = 6.0;\n" +" k = i;\n" +"//@ assert k == i;\n}\n" +"{ Float i; float k; i = 6.0f;\n" +" k = i;\n" +"//@ assert k == i;\n}\n" +"{ Character i; char k; i = 6;\n" +" k = i;\n" +"//@ assert k == i;\n}\n" +"{ Integer i = 6;\n" +"int k = i;\n" +"//@ assert k == i+1;\n}\n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:37: JML assertion is false" ,"END" ); } @Test public void testBoxingOnAssignmentOp() { helpTCX("tt.A","package tt; /*@ nullable_by_default*/ public class A { \n" +"public static void main(String[] args) { \n" +"try { Integer i = null; int k = 6;\n" +" k += i;\n" +"\n} catch (Exception e) {}\n" +"try { Integer i = null; int k = 6;\n" +"i += k; \n" +"\n} catch (Exception e) {}\n" +"{ Integer i = 5; int k = 6;\n" +" k += i; i += k; \n" +"//@ assert k == 11;\n}\n" +"try { Boolean i = null; boolean k = true;\n" +" k &= i;\n" +"\n} catch (Exception e) {} \n" +"try { Boolean i = null; boolean k = true;\n" +" i &= k;\n" +"\n} catch (Exception e) {} \n" +"{ Boolean i = false; boolean k = true;\n" +" k &= i;\n" +" i &= k;\n" +"//@ assert !k;\n}\n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:4: JML Attempt to unbox a null object" ,"/tt/A.java:8: JML Attempt to unbox a null object" ,"/tt/A.java:16: JML Attempt to unbox a null object" ,"/tt/A.java:20: JML Attempt to unbox a null object" ,"END" ); } @Test public void testBoxingOnNullAsssignment() { helpTCX("tt.A","package tt; /*@ nullable_by_default*/ public class A { \n" +"public static void main(String[] args) { \n" +"try { Integer i = null;\n" +"int k; k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Boolean i = null;\n" +"boolean k; k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Short i = null;\n" +"short k; k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Long i = null;\n" +"long k; k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Byte i = null;\n" +"byte k; k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Double i = null;\n" +"double k; k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Float i = null;\n" +"float k; k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Character i = null;\n" +"char k; k = i;\n" +"//@ assert k == i;\n} catch (Exception e) {}\n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:4: JML Attempt to unbox a null object" ,"/tt/A.java:8: JML Attempt to unbox a null object" ,"/tt/A.java:12: JML Attempt to unbox a null object" ,"/tt/A.java:16: JML Attempt to unbox a null object" ,"/tt/A.java:20: JML Attempt to unbox a null object" ,"/tt/A.java:24: JML Attempt to unbox a null object" ,"/tt/A.java:28: JML Attempt to unbox a null object" ,"/tt/A.java:32: JML Attempt to unbox a null object" ,"END" ); } @Test public void testBoxing() { helpTCX("tt.A","package tt; /*@ nullable_by_default*/ public class A { \n" +"public static int unbox(int i) { return i;} \n" +"public static Integer box(Integer i) { return i;} \n" +"public static void main(String[] args) { \n" +"try { Boolean i = null;\n" +"boolean k = true && i;\n" // Null problem +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Boolean i = false;\n" +"boolean k = true && i;\n" +"//@ assert k == false;\n} catch (Exception e) {}\n" +"try { Boolean i = null;\n" +"boolean k = i && true;\n" // Null problem +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Boolean i = false;\n" +"boolean k = i && true;\n" +"//@ assert k == false;\n} catch (Exception e) {}\n" +"try { Integer i = null;\n" +"int k = 0 + i;\n" // Null problem - 22 +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Integer i = 6;\n" +"int k = 0 + i;\n" +"//@ assert k == 6;\n} catch (Exception e) {}\n" +"try { Integer i = null;\n" +"int k = i + 0;\n" // Null problem - 30 +"//@ assert k == i;\n} catch (Exception e) {}\n" +"try { Integer i = 6;\n" +"int k = i + 0;\n" +"//@ assert k == 6;\n} catch (Exception e) {}\n" +"try { Integer i = null;\n" +"int k = - i;\n" // Null problem -- 38 +"//@ assert k == -i;\n} catch (Exception e) {}\n" +"try { Integer i = 6;\n" +"int k = - i;\n" +"//@ assert k == -6;\n} catch (Exception e) {}\n" +"try { Integer i = null;\n" +"unbox(i);\n" // Null problem -- 46 +"} catch (Exception e) {}\n" +"try { Integer i = 6;\n" +"int k = unbox(i);\n" +"//@ assert k == 6;\n} catch (Exception e) {}\n" +"try { int i = 6;\n" +"Integer k = box(i); int ii = k;\n" +"//@ assert ii == 6;\n} catch (Exception e) {}\n" +"try { Boolean b = null;\n" +"int i = b ? 4 : 5;\n" // Null problem - 57 +"//@ assert i == 6;\n} catch (Exception e) {}\n" +"try { Boolean b = false;\n" +"int i = b ? 4 : 5;\n" +"//@ assert i == 5;\n} catch (Exception e) {}\n" +"try { Boolean b = null;\n" +"int i; if (b) i = 4; else i = 5;\n" // Null problem 65 +"//@ assert i == 6;\n} catch (Exception e) {}\n" +"try { Boolean b = false;\n" +"int i; if (b) i = 4; else i = 5;\n" +"//@ assert i == 5;\n} catch (Exception e) {}\n" +"System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:6: JML Attempt to unbox a null object" ,"/tt/A.java:14: JML Attempt to unbox a null object" ,"/tt/A.java:22: JML Attempt to unbox a null object" ,"/tt/A.java:30: JML Attempt to unbox a null object" ,"/tt/A.java:38: JML Attempt to unbox a null object" ,"/tt/A.java:46: JML Attempt to unbox a null object" ,"/tt/A.java:57: JML Attempt to unbox a null object" ,"/tt/A.java:65: JML Attempt to unbox a null object" ,"END" ); // FIXME: Also synchronized expression, switch expression, not on String, conditional, assignop, array index // type test, type case, return, loop initializers, array initializers, if condition } @Test public void testBoxingClass() { expectedRACExit = 1; helpTCX("tt.A","package tt; /*@ nullable_by_default*/ public class A { \n" +"public static int unbox(int i) { return i;} \n" +"public static Integer box(Integer i) { return i;} \n" +"public static Integer i = 6; \n" +"public static int j = i; \n" +"static { //@ assert j == 6; \n}\n" +"static { Integer k = 6; int m = k; //@ assert m == 6; \n}\n" +"static { try { Integer k = null; int m = k; } catch (Exception e) {} \n}\n" +"public static Integer ii = null; \n" +"public static int jj = ii; \n" +"public static void main(String[] args) { \n" +" System.out.println(\"END\"); \n" +"}}" ,"/tt/A.java:10: JML Attempt to unbox a null object" ,"/tt/A.java:13: JML Attempt to unbox a null object" ,"java.lang.ExceptionInInitializerError" ,"Caused by: java.lang.NullPointerException" ,"\tat tt.A.<clinit>(A.java:13)" ,"Exception in thread \"main\" " ); } @Test public void testBoxingString() { helpTCX("tt.A","package tt; /*@ nullable_by_default*/ public class A { \n" +"public static int unbox(int i) { return i;} \n" +"public static Integer box(Integer i) { return i;} \n" +"public static void main(String[] args) { \n" +"try { String s = null;\n" +"String ss = \"a\" + s; ss += s; \n" // No null problem // FIXME - crashes on the += +"\n} catch (Exception e) {}\n" +"System.out.println(\"END\"); \n" +"}}" ,"END" ); } @Test public void testStringSwitch() { helpTCX("tt.A","package tt; /*@ nullable_by_default*/ public class A { \n" +"public static void main(String[] args) { \n" +"String s = \"abc\"; int k;\n" +"switch (s) {\n" +" case \"asd\": k = 1; break;\n" +" case \"abc\": k = 2; break;\n" +" case \"def\": k = 3; break;\n" +" default: k = 4; break;\n" +"}\n" +"System.out.println(\"END \" + k); \n" +"}}" ,"END 2" ); } @Test public void testStringSwitchNull() { helpTCX("tt.A","package tt; /*@ nullable_by_default*/ public class A { \n" +"public static void main(String[] args) { \n" +"String s = null; int k = 0;\n" +"try { switch (s) {\n" +" case \"asd\": k = 1; break;\n" +" case \"abc\": k = 2; break;\n" +" case \"def\": k = 3; break;\n" +" default: k = 4; break;\n" +"} } catch (Exception e) {}\n" +"System.out.println(\"END \" + k); \n" +"}}" ,"/tt/A.java:4: JML An object may be illegally null" ,"END 0" ); } @Test public void testEnumSwitch() { helpTCX("tt.A","package tt; /*@ nullable_by_default*/ public class A { \n" +"enum E { A,B,C}; public static void main(String[] args) { \n" +"E e = E.B; int k = 0;\n" +"switch (e) {\n" +" case A: k = 1; break;\n" +" case B: k = 2; break;\n" +" case C: k = 3; break;\n" +" default: k = 4; break;\n" +"}\n" +"System.out.println(\"END \" + k); \n" +"}}" ,"END 2" ); } @Test public void testEnumSwitchNull() { helpTCX("tt.A","package tt; /*@ nullable_by_default*/ public class A { \n" +"enum E { A,B,C}; public static void main(String[] args) { \n" +"E e = null; int k = 0;\n" +"try { switch (e) {\n" +" case A: k = 1; break;\n" +" case B: k = 2; break;\n" +" case C: k = 3; break;\n" +" default: k = 4; break;\n" +"} } catch (Exception ee) {}\n" +"System.out.println(\"END \" + k); \n" +"}}" ,"/tt/A.java:4: JML An object may be illegally null" ,"END 0" ); } }