use of org.checkerframework.framework.flow.CFAbstractStore in project checker-framework by typetools.
the class BaseTypeVisitor method checkConditionalPostcondition.
/**
* Check that the expression's type is annotated with {@code annotation} at every regular exit
* that returns {@code result}
*
* @param node tree of method with the postcondition
* @param annotation expression's type must have this annotation
* @param expression the expression that the postcondition concerns
* @param result result for which the postcondition is valid
*/
protected void checkConditionalPostcondition(MethodTree node, AnnotationMirror annotation, Receiver expression, boolean result) {
boolean booleanReturnType = TypesUtils.isBooleanType(TreeUtils.typeOf(node.getReturnType()));
if (!booleanReturnType) {
checker.report(Result.failure("contracts.conditional.postcondition.invalid.returntype"), node);
// annotation is invalid.
return;
}
for (Pair<ReturnNode, ?> pair : atypeFactory.getReturnStatementStores(node)) {
ReturnNode returnStmt = pair.first;
Node retValNode = returnStmt.getResult();
Boolean retVal = retValNode instanceof BooleanLiteralNode ? ((BooleanLiteralNode) retValNode).getValue() : null;
TransferResult<?, ?> transferResult = (TransferResult<?, ?>) pair.second;
if (transferResult == null) {
// Unreachable return statements have no stores, but there is no need to check them.
continue;
}
CFAbstractStore<?, ?> exitStore = (CFAbstractStore<?, ?>) (result ? transferResult.getThenStore() : transferResult.getElseStore());
CFAbstractValue<?> value = exitStore.getValue(expression);
// this means the result is a boolean literal
if (!(retVal == null || retVal == result)) {
continue;
}
AnnotationMirror inferredAnno = null;
if (value != null) {
QualifierHierarchy hierarchy = atypeFactory.getQualifierHierarchy();
Set<AnnotationMirror> annos = value.getAnnotations();
inferredAnno = hierarchy.findAnnotationInSameHierarchy(annos, annotation);
}
if (!checkContract(expression, annotation, inferredAnno, exitStore)) {
checker.report(Result.failure("contracts.conditional.postcondition.not.satisfied", expression.toString()), returnStmt.getTree());
}
}
}
use of org.checkerframework.framework.flow.CFAbstractStore in project checker-framework by typetools.
the class InitializationVisitor method checkContract.
@Override
protected boolean checkContract(Receiver expr, AnnotationMirror necessaryAnnotation, AnnotationMirror inferredAnnotation, CFAbstractStore<?, ?> store) {
// also use the information about initialized fields to check contracts
final AnnotationMirror invariantAnno = atypeFactory.getFieldInvariantAnnotation();
if (atypeFactory.getQualifierHierarchy().isSubtype(invariantAnno, necessaryAnnotation)) {
if (expr instanceof FieldAccess) {
FieldAccess fa = (FieldAccess) expr;
if (fa.getReceiver() instanceof ThisReference || fa.getReceiver() instanceof ClassName) {
@SuppressWarnings("unchecked") Store s = (Store) store;
if (s.isFieldInitialized(fa.getField())) {
AnnotatedTypeMirror fieldType = atypeFactory.getAnnotatedType(fa.getField());
// is this an invariant-field?
if (AnnotationUtils.containsSame(fieldType.getAnnotations(), invariantAnno)) {
return true;
}
}
} else {
Set<AnnotationMirror> recvAnnoSet;
@SuppressWarnings("unchecked") Value value = (Value) store.getValue(fa.getReceiver());
if (value != null) {
recvAnnoSet = value.getAnnotations();
} else if (fa.getReceiver() instanceof LocalVariable) {
Element elem = ((LocalVariable) fa.getReceiver()).getElement();
AnnotatedTypeMirror recvType = atypeFactory.getAnnotatedType(elem);
recvAnnoSet = recvType.getAnnotations();
} else {
// Is there anything better we could do?
return false;
}
boolean isRecvCommitted = false;
for (AnnotationMirror anno : recvAnnoSet) {
if (atypeFactory.isCommitted(anno)) {
isRecvCommitted = true;
}
}
AnnotatedTypeMirror fieldType = atypeFactory.getAnnotatedType(fa.getField());
// has the invariant type.
if (isRecvCommitted && AnnotationUtils.containsSame(fieldType.getAnnotations(), invariantAnno)) {
return true;
}
}
}
}
return super.checkContract(expr, necessaryAnnotation, inferredAnnotation, store);
}
Aggregations