import org.checkerframework.checker.nullness.qual.*; public class FlowLoop { void simpleWhileLoop() { String s = "m"; while (s != null) { s.toString(); s = null; } //:: error: (dereference.of.nullable) s.toString(); // error } void whileConditionError() { String s = "m"; //:: error: (dereference.of.nullable) while (s.toString() == "m") { // error s.toString(); s = null; } s.toString(); } void simpleForLoop() { for (String s = "m"; s != null; s = null) { s.toString(); } } void forLoopConditionError() { for (String s = "m"; //:: error: (dereference.of.nullable) s.toString() != "m"; // error s = null) { s.toString(); } } class Link { Object val; @Nullable Link next; public Link(Object val, @Nullable Link next) { this.val = val; this.next = next; } } // Both dereferences of l should succeed void test(@Nullable Link in) { for (@Nullable Link l = in; l != null; l = l.next) { Object o; o = l.val; } } void multipleRuns() { String s = "m"; while (true) { //:: error: (dereference.of.nullable) s.toString(); // error s = null; } } void multipleRunsDo() { String s = "m"; do { //:: error: (dereference.of.nullable) s.toString(); // error s = null; } while (true); } void alwaysRunForLoop() { String s = "m"; for (s = null; s != null; s = "m") { s.toString(); // ok } //:: error: (dereference.of.nullable) s.toString(); // error } public void badIterator() { Class<?> opt_doc1 = null; //:: error: (dereference.of.nullable) opt_doc1.getInterfaces(); Class<?> opt_doc2 = null; //:: error: (dereference.of.nullable) for (Class<? extends @Nullable Object> fd : opt_doc2.getInterfaces()) { // empty loop body } } void testContinue(@Nullable Object o) { for (; ; ) { //:: error: (dereference.of.nullable) o.toString(); if (true) continue; } } void testBreak(@Nullable Object o) { while (true) { //:: error: (dereference.of.nullable) o.toString(); if (true) break; } } void testSimpleNull() { String r1 = null; while (r1 != null) ; //:: error: (dereference.of.nullable) r1.toString(); // error } void testMulticheckNull() { String r1 = null; while (r1 != null && r1.equals("m")) ; //:: error: (dereference.of.nullable) r1.toString(); // error } void testAssignInLoopSimple() { String r1 = ""; while (r1 != null) { r1 = null; } //:: error: (dereference.of.nullable) r1.toString(); // error } void testAssignInLoopMulti() { String r1 = ""; while (r1 != null && r1.isEmpty()) { r1 = null; } //:: error: (dereference.of.nullable) r1.toString(); // error } void testBreakWithCheck() { String s = null; while (true) { if (s == null) break; s.toString(); } } void test1() { while (true) { String s = null; if (s == null) { return; } s.toString(); } } }