use of org.checkerframework.common.value.util.Range in project checker-framework by typetools.
the class ValueTransfer method calculateRangeBinaryOp.
/**
* Calculate the result range after a binary operation between two numerical type nodes
*/
private Range calculateRangeBinaryOp(Node leftNode, Node rightNode, NumericalBinaryOps op, TransferInput<CFValue, CFStore> p) {
if (TypesUtils.isIntegral(leftNode.getType()) && TypesUtils.isIntegral(rightNode.getType())) {
Range leftRange = getIntRange(leftNode, p);
Range rightRange = getIntRange(rightNode, p);
Range resultRange;
switch(op) {
case ADDITION:
resultRange = leftRange.plus(rightRange);
break;
case SUBTRACTION:
resultRange = leftRange.minus(rightRange);
break;
case MULTIPLICATION:
resultRange = leftRange.times(rightRange);
break;
case DIVISION:
resultRange = leftRange.divide(rightRange);
break;
case REMAINDER:
resultRange = leftRange.remainder(rightRange);
break;
case SHIFT_LEFT:
resultRange = leftRange.shiftLeft(rightRange);
break;
case SIGNED_SHIFT_RIGHT:
resultRange = leftRange.signedShiftRight(rightRange);
break;
case UNSIGNED_SHIFT_RIGHT:
resultRange = leftRange.unsignedShiftRight(rightRange);
break;
case BITWISE_AND:
resultRange = leftRange.bitwiseAnd(rightRange);
break;
case BITWISE_OR:
resultRange = leftRange.bitwiseOr(rightRange);
break;
case BITWISE_XOR:
resultRange = leftRange.bitwiseXor(rightRange);
break;
default:
ErrorReporter.errorAbort("ValueTransfer: unsupported operation: " + op);
throw new RuntimeException("this can't happen");
}
// operations.
return leftNode.getType().getKind() == TypeKind.LONG || rightNode.getType().getKind() == TypeKind.LONG ? resultRange : resultRange.intRange();
} else {
return Range.EVERYTHING;
}
}
use of org.checkerframework.common.value.util.Range in project checker-framework by typetools.
the class ValueVisitor method visitTypeCast.
@Override
public Void visitTypeCast(TypeCastTree node, Void p) {
if (node.getExpression().getKind() == Kind.NULL_LITERAL) {
return null;
}
AnnotatedTypeMirror castType = atypeFactory.getAnnotatedType(node);
AnnotationMirror castAnno = castType.getAnnotationInHierarchy(atypeFactory.UNKNOWNVAL);
AnnotationMirror exprAnno = atypeFactory.getAnnotatedType(node.getExpression()).getAnnotationInHierarchy(atypeFactory.UNKNOWNVAL);
// to a @IntRange(from = Byte.MIN_VALUE, to = Byte.MAX_VALUE byte).
if (castAnno != null && exprAnno != null && atypeFactory.isIntRange(castAnno) && atypeFactory.isIntRange(exprAnno)) {
Range castRange = ValueAnnotatedTypeFactory.getRange(castAnno);
if (castType.getKind() == TypeKind.BYTE && castRange.isByteEverything()) {
return p;
}
if (castType.getKind() == TypeKind.SHORT && castRange.isShortEverything()) {
return p;
}
if (castType.getKind() == TypeKind.INT && castRange.isIntEverything()) {
return p;
}
if (castType.getKind() == TypeKind.LONG && castRange.isLongEverything()) {
return p;
}
if (Range.IGNORE_OVERFLOW) {
// Range.IGNORE_OVERFLOW is only set if this checker is ignoring overflow.
// In that case, do not warn if the range of the expression encompasses
// the whole type being casted to (i.e. the warning is actually about overflow).
Range exprRange = ValueAnnotatedTypeFactory.getRange(exprAnno);
switch(castType.getKind()) {
case BYTE:
exprRange = exprRange.byteRange();
break;
case SHORT:
exprRange = exprRange.shortRange();
break;
case INT:
exprRange = exprRange.intRange();
break;
default:
}
if (castRange.equals(exprRange)) {
return p;
}
}
}
return super.visitTypeCast(node, p);
}
Aggregations