import org.checkerframework.dataflow.qual.Pure;
import org.checkerframework.framework.qual.EnsuresQualifier;
import org.checkerframework.framework.qual.EnsuresQualifierIf;
import org.checkerframework.framework.qual.EnsuresQualifiers;
import org.checkerframework.framework.qual.EnsuresQualifiersIf;
import org.checkerframework.framework.test.*;
import testlib.util.*;
class Postcondition {
String f1, f2, f3;
Postcondition p;
@Pure
String p1() {
return null;
}
/** *** normal postcondition ***** */
@EnsuresQualifier(expression = "f1", qualifier = Odd.class)
void oddF1() {
f1 = null;
}
@EnsuresQualifier(expression = "p.f1", qualifier = Odd.class)
void oddF1_1() {
p.f1 = null;
}
@EnsuresQualifier(expression = "#1.f1", qualifier = Odd.class)
void oddF1_2(final Postcondition param) {
param.f1 = null;
}
@EnsuresQualifier(expression = "p.p1()", qualifier = Odd.class)
void oddF1_3() {
if (p.p1() == null) {
return;
}
throw new RuntimeException();
}
@EnsuresQualifier(expression = "f1", qualifier = Value.class)
//:: error: (contracts.postcondition.not.satisfied)
void valueF1() {}
@EnsuresQualifier(expression = "---", qualifier = Value.class)
//:: error: (flowexpr.parse.error)
void error() {}
@EnsuresQualifier(expression = "#1.#2", qualifier = Value.class)
//:: error: (flowexpr.parse.error)
void error2(final String p1, final String p2) {}
@EnsuresQualifier(expression = "f1", qualifier = Value.class)
void exception() {
throw new RuntimeException();
}
@EnsuresQualifier(expression = "#1", qualifier = Value.class)
void param1(final @Value String f) {}
@EnsuresQualifier(
expression = {"#1", "#2"},
qualifier = Value.class
)
//:: error: (flowexpr.parameter.not.final)
void param2(@Value String f, @Value String g) {
f = g;
}
@EnsuresQualifier(expression = "#1", qualifier = Value.class)
//:: error: (flowexpr.parse.index.too.big)
void param3() {}
// basic postcondition test
void t1(@Odd String p1, String p2) {
valueF1();
//:: error: (assignment.type.incompatible)
@Odd String l1 = f1;
oddF1();
@Odd String l2 = f1;
//:: error: (flowexpr.parse.error)
error();
}
// test parameter syntax
void t2(@Odd String p1, String p2) {
//:: error: (flowexpr.parse.index.too.big)
param3();
}
// postcondition with more complex flow expression
void tn1(boolean b) {
//:: error: (assignment.type.incompatible)
@Odd String l1 = p.f1;
oddF1_1();
@Odd String l2 = p.f1;
}
// postcondition with more complex flow expression
void tn2(boolean b) {
Postcondition param = null;
//:: error: (assignment.type.incompatible)
@Odd String l1 = param.f1;
oddF1_2(param);
@Odd String l2 = param.f1;
}
// postcondition with more complex flow expression
void tn3(boolean b) {
//:: error: (assignment.type.incompatible)
@Odd String l1 = p.p1();
oddF1_3();
@Odd String l2 = p.p1();
}
/** *** many postcondition ***** */
@EnsuresQualifiers({
@EnsuresQualifier(expression = "f1", qualifier = Odd.class),
@EnsuresQualifier(expression = "f2", qualifier = Value.class)
})
void oddValueF1(@Value String p1) {
f1 = null;
f2 = p1;
}
@EnsuresQualifiers({
@EnsuresQualifier(expression = "f1", qualifier = Odd.class),
@EnsuresQualifier(expression = "f2", qualifier = Value.class)
})
//:: error: (contracts.postcondition.not.satisfied)
void oddValueF1_invalid(@Value String p1) {}
@EnsuresQualifiers({
@EnsuresQualifier(expression = "--", qualifier = Odd.class),
})
//:: error: (flowexpr.parse.error)
void error2() {}
// basic postcondition test
void tnm1(@Odd String p1, @Value String p2) {
//:: error: (assignment.type.incompatible)
@Odd String l1 = f1;
//:: error: (assignment.type.incompatible)
@Value String l2 = f2;
oddValueF1(p2);
@Odd String l3 = f1;
@Value String l4 = f2;
//:: error: (flowexpr.parse.error)
error2();
}
/** *** conditional postcondition ***** */
@EnsuresQualifierIf(result = true, expression = "f1", qualifier = Odd.class)
boolean condOddF1(boolean b) {
if (b) {
f1 = null;
return true;
}
return false;
}
@EnsuresQualifierIf(result = false, expression = "f1", qualifier = Odd.class)
boolean condOddF1False(boolean b) {
if (b) {
return true;
}
f1 = null;
return false;
}
@EnsuresQualifierIf(result = false, expression = "f1", qualifier = Odd.class)
boolean condOddF1Invalid(boolean b) {
if (b) {
f1 = null;
return true;
}
//:: error: (contracts.conditional.postcondition.not.satisfied)
return false;
}
@EnsuresQualifierIf(result = false, expression = "f1", qualifier = Odd.class)
//:: error: (contracts.conditional.postcondition.invalid.returntype)
void wrongReturnType() {}
@EnsuresQualifierIf(result = false, expression = "f1", qualifier = Odd.class)
//:: error: (contracts.conditional.postcondition.invalid.returntype)
String wrongReturnType2() {
f1 = null;
return "";
}
@EnsuresQualifierIf(result = true, expression = "#1", qualifier = Odd.class)
boolean isOdd(final String p1) {
return isOdd(p1, 0);
}
@EnsuresQualifierIf(result = true, expression = "#1", qualifier = Odd.class)
boolean isOdd(final String p1, int p2) {
return p1 == null;
}
@EnsuresQualifierIf(result = false, expression = "#1", qualifier = Odd.class)
boolean isNotOdd(final String p1) {
return !isOdd(p1);
}
// basic conditional postcondition test
void t3(@Odd String p1, String p2) {
condOddF1(true);
//:: error: (assignment.type.incompatible)
@Odd String l1 = f1;
if (condOddF1(false)) {
@Odd String l2 = f1;
}
//:: error: (assignment.type.incompatible)
@Odd String l3 = f1;
}
// basic conditional postcondition test (inverted)
void t4(@Odd String p1, String p2) {
condOddF1False(true);
//:: error: (assignment.type.incompatible)
@Odd String l1 = f1;
if (!condOddF1False(false)) {
@Odd String l2 = f1;
}
//:: error: (assignment.type.incompatible)
@Odd String l3 = f1;
}
// basic conditional postcondition test 2
void t5(boolean b) {
condOddF1(true);
if (b) {
//:: error: (assignment.type.incompatible)
@Odd String l2 = f1;
}
}
/** *** many conditional postcondition ***** */
@EnsuresQualifiersIf({
@EnsuresQualifierIf(result = true, expression = "f1", qualifier = Odd.class),
@EnsuresQualifierIf(result = false, expression = "f1", qualifier = Value.class)
})
boolean condsOddF1(boolean b, @Value String p1) {
if (b) {
f1 = null;
return true;
}
f1 = p1;
return false;
}
@EnsuresQualifiersIf({
@EnsuresQualifierIf(result = true, expression = "f1", qualifier = Odd.class),
@EnsuresQualifierIf(result = false, expression = "f1", qualifier = Value.class)
})
boolean condsOddF1_invalid(boolean b, @Value String p1) {
if (b) {
//:: error: (contracts.conditional.postcondition.not.satisfied)
return true;
}
//:: error: (contracts.conditional.postcondition.not.satisfied)
return false;
}
@EnsuresQualifiersIf({
@EnsuresQualifierIf(result = false, expression = "f1", qualifier = Odd.class)
})
//:: error: (contracts.conditional.postcondition.invalid.returntype)
String wrongReturnType3() {
return "";
}
void t6(@Odd String p1, @Value String p2) {
condsOddF1(true, p2);
//:: error: (assignment.type.incompatible)
@Odd String l1 = f1;
//:: error: (assignment.type.incompatible)
@Value String l2 = f1;
if (condsOddF1(false, p2)) {
@Odd String l3 = f1;
//:: error: (assignment.type.incompatible)
@Value String l4 = f1;
} else {
@Value String l5 = f1;
//:: error: (assignment.type.incompatible)
@Odd String l6 = f1;
}
}
}