use of org.checkerframework.dataflow.cfg.node.BinaryOperationNode in project checker-framework by typetools.
the class LowerBoundTransfer method getAnnotationForPlus.
/**
* getAnnotationForPlus handles the following cases (cases 10-12 above):
*
* <pre>
* 8. lit -2 + pos → gte-1
* lit -1 + * → call demote
* lit 0 + * → *
* lit 1 + * → call promote
* 9. lit ≥ 2 + {gte-1, nn, or pos} → pos
* let all other lits, including sets, fall through:
* 10. pos + pos → pos
* 11. nn + * → *
* 12. pos + gte-1 → nn
* * + * → lbu
* </pre>
*/
private AnnotationMirror getAnnotationForPlus(BinaryOperationNode binaryOpNode, TransferInput<CFValue, CFStore> p) {
Node leftExprNode = binaryOpNode.getLeftOperand();
Node rightExprNode = binaryOpNode.getRightOperand();
AnnotationMirror leftAnno = getLowerBoundAnnotation(leftExprNode, p);
// Check if the right side's value is known at compile time.
Long valRight = ValueCheckerUtils.getExactValue(rightExprNode.getTree(), aTypeFactory.getValueAnnotatedTypeFactory());
if (valRight != null) {
return getAnnotationForLiteralPlus(valRight.intValue(), leftAnno);
}
AnnotationMirror rightAnno = getLowerBoundAnnotation(rightExprNode, p);
// Check if the left side's value is known at compile time.
Long valLeft = ValueCheckerUtils.getExactValue(leftExprNode.getTree(), aTypeFactory.getValueAnnotatedTypeFactory());
if (valLeft != null) {
return getAnnotationForLiteralPlus(valLeft.intValue(), rightAnno);
}
/* This section is handling the generic cases:
* pos + pos -> pos
* nn + * -> *
* pos + gte-1 -> nn
*/
if (aTypeFactory.areSameByClass(leftAnno, Positive.class) && aTypeFactory.areSameByClass(rightAnno, Positive.class)) {
return POS;
}
if (aTypeFactory.areSameByClass(leftAnno, NonNegative.class)) {
return rightAnno;
}
if (aTypeFactory.areSameByClass(rightAnno, NonNegative.class)) {
return leftAnno;
}
if ((isPositive(leftAnno) && isGTEN1(rightAnno)) || (isGTEN1(leftAnno) && isPositive(rightAnno))) {
return NN;
}
return UNKNOWN;
}
use of org.checkerframework.dataflow.cfg.node.BinaryOperationNode in project checker-framework by typetools.
the class JavaExpression method fromNode.
/**
* We ignore operations such as widening and narrowing when computing the internal representation.
*
* @param receiverNode a node to convert to a JavaExpression
* @return the internal representation of the given node. Might contain {@link Unknown}.
*/
public static JavaExpression fromNode(Node receiverNode) {
JavaExpression result = null;
if (receiverNode instanceof FieldAccessNode) {
result = fromNodeFieldAccess((FieldAccessNode) receiverNode);
} else if (receiverNode instanceof ExplicitThisNode) {
result = new ThisReference(receiverNode.getType());
} else if (receiverNode instanceof ThisNode) {
result = new ThisReference(receiverNode.getType());
} else if (receiverNode instanceof SuperNode) {
result = new ThisReference(receiverNode.getType());
} else if (receiverNode instanceof LocalVariableNode) {
LocalVariableNode lv = (LocalVariableNode) receiverNode;
result = new LocalVariable(lv);
} else if (receiverNode instanceof ArrayAccessNode) {
ArrayAccessNode a = (ArrayAccessNode) receiverNode;
result = fromArrayAccess(a);
} else if (receiverNode instanceof StringConversionNode) {
// ignore string conversion
return fromNode(((StringConversionNode) receiverNode).getOperand());
} else if (receiverNode instanceof WideningConversionNode) {
// ignore widening
return fromNode(((WideningConversionNode) receiverNode).getOperand());
} else if (receiverNode instanceof NarrowingConversionNode) {
// ignore narrowing
return fromNode(((NarrowingConversionNode) receiverNode).getOperand());
} else if (receiverNode instanceof UnaryOperationNode) {
UnaryOperationNode uopn = (UnaryOperationNode) receiverNode;
return new UnaryOperation(uopn, fromNode(uopn.getOperand()));
} else if (receiverNode instanceof BinaryOperationNode) {
BinaryOperationNode bopn = (BinaryOperationNode) receiverNode;
return new BinaryOperation(bopn, fromNode(bopn.getLeftOperand()), fromNode(bopn.getRightOperand()));
} else if (receiverNode instanceof ClassNameNode) {
ClassNameNode cn = (ClassNameNode) receiverNode;
result = new ClassName(cn.getType());
} else if (receiverNode instanceof ValueLiteralNode) {
ValueLiteralNode vn = (ValueLiteralNode) receiverNode;
result = new ValueLiteral(vn.getType(), vn);
} else if (receiverNode instanceof ArrayCreationNode) {
ArrayCreationNode an = (ArrayCreationNode) receiverNode;
List<@Nullable JavaExpression> dimensions = CollectionsPlume.mapList(JavaExpression::fromNode, an.getDimensions());
List<JavaExpression> initializers = CollectionsPlume.mapList(JavaExpression::fromNode, an.getInitializers());
result = new ArrayCreation(an.getType(), dimensions, initializers);
} else if (receiverNode instanceof MethodInvocationNode) {
MethodInvocationNode mn = (MethodInvocationNode) receiverNode;
MethodInvocationTree t = mn.getTree();
if (t == null) {
throw new BugInCF("Unexpected null tree for node: " + mn);
}
assert TreeUtils.isUseOfElement(t) : "@AssumeAssertion(nullness): tree kind";
ExecutableElement invokedMethod = TreeUtils.elementFromUse(t);
// Note that the method might be nondeterministic.
List<JavaExpression> parameters = CollectionsPlume.mapList(JavaExpression::fromNode, mn.getArguments());
JavaExpression methodReceiver;
if (ElementUtils.isStatic(invokedMethod)) {
methodReceiver = new ClassName(mn.getTarget().getReceiver().getType());
} else {
methodReceiver = fromNode(mn.getTarget().getReceiver());
}
result = new MethodCall(mn.getType(), invokedMethod, methodReceiver, parameters);
}
if (result == null) {
result = new Unknown(receiverNode);
}
return result;
}
use of org.checkerframework.dataflow.cfg.node.BinaryOperationNode in project checker-framework by typetools.
the class LiveVarStore method addUseInExpression.
/**
* Add the information of live variables in an expression to the live variable set.
*
* @param expression a node
*/
public void addUseInExpression(Node expression) {
// TODO Do we need a AbstractNodeScanner to do the following job?
if (expression instanceof LocalVariableNode || expression instanceof FieldAccessNode) {
LiveVarValue liveVarValue = new LiveVarValue(expression);
putLiveVar(liveVarValue);
} else if (expression instanceof UnaryOperationNode) {
UnaryOperationNode unaryNode = (UnaryOperationNode) expression;
addUseInExpression(unaryNode.getOperand());
} else if (expression instanceof TernaryExpressionNode) {
TernaryExpressionNode ternaryNode = (TernaryExpressionNode) expression;
addUseInExpression(ternaryNode.getConditionOperand());
addUseInExpression(ternaryNode.getThenOperand());
addUseInExpression(ternaryNode.getElseOperand());
} else if (expression instanceof TypeCastNode) {
TypeCastNode typeCastNode = (TypeCastNode) expression;
addUseInExpression(typeCastNode.getOperand());
} else if (expression instanceof InstanceOfNode) {
InstanceOfNode instanceOfNode = (InstanceOfNode) expression;
addUseInExpression(instanceOfNode.getOperand());
} else if (expression instanceof BinaryOperationNode) {
BinaryOperationNode binaryNode = (BinaryOperationNode) expression;
addUseInExpression(binaryNode.getLeftOperand());
addUseInExpression(binaryNode.getRightOperand());
}
}
Aggregations