use of org.checkerframework.dataflow.cfg.node.NotEqualNode in project checker-framework by typetools.
the class CFGTranslationPhaseOne method visitBinary.
@Override
public Node visitBinary(BinaryTree tree, Void p) {
// Note that for binary operations it is important to perform any required promotion on the left
// operand before generating any Nodes for the right operand, because labels must be inserted
// AFTER ALL preceding Nodes and BEFORE ALL following Nodes.
Node r = null;
Tree leftTree = tree.getLeftOperand();
Tree rightTree = tree.getRightOperand();
Tree.Kind kind = tree.getKind();
switch(kind) {
case DIVIDE:
case MULTIPLY:
case REMAINDER:
{
// see JLS 15.17
TypeMirror exprType = TreeUtils.typeOf(tree);
TypeMirror leftType = TreeUtils.typeOf(leftTree);
TypeMirror rightType = TreeUtils.typeOf(rightTree);
TypeMirror promotedType = binaryPromotedType(leftType, rightType);
Node left = binaryNumericPromotion(scan(leftTree, p), promotedType);
Node right = binaryNumericPromotion(scan(rightTree, p), promotedType);
if (kind == Tree.Kind.MULTIPLY) {
r = new NumericalMultiplicationNode(tree, left, right);
} else if (kind == Tree.Kind.DIVIDE) {
if (TypesUtils.isIntegralPrimitive(exprType)) {
r = new IntegerDivisionNode(tree, left, right);
extendWithNodeWithException(r, arithmeticExceptionType);
} else {
r = new FloatingDivisionNode(tree, left, right);
}
} else {
assert kind == Tree.Kind.REMAINDER;
if (TypesUtils.isIntegralPrimitive(exprType)) {
r = new IntegerRemainderNode(tree, left, right);
extendWithNodeWithException(r, arithmeticExceptionType);
} else {
r = new FloatingRemainderNode(tree, left, right);
}
}
break;
}
case MINUS:
case PLUS:
{
// see JLS 15.18
// TypeMirror exprType = InternalUtils.typeOf(tree);
TypeMirror leftType = TreeUtils.typeOf(leftTree);
TypeMirror rightType = TreeUtils.typeOf(rightTree);
if (TypesUtils.isString(leftType) || TypesUtils.isString(rightType)) {
assert (kind == Tree.Kind.PLUS);
Node left = stringConversion(scan(leftTree, p));
Node right = stringConversion(scan(rightTree, p));
r = new StringConcatenateNode(tree, left, right);
} else {
TypeMirror promotedType = binaryPromotedType(leftType, rightType);
Node left = binaryNumericPromotion(scan(leftTree, p), promotedType);
Node right = binaryNumericPromotion(scan(rightTree, p), promotedType);
// set conversion.
if (kind == Tree.Kind.PLUS) {
r = new NumericalAdditionNode(tree, left, right);
} else {
assert kind == Tree.Kind.MINUS;
r = new NumericalSubtractionNode(tree, left, right);
}
}
break;
}
case LEFT_SHIFT:
case RIGHT_SHIFT:
case UNSIGNED_RIGHT_SHIFT:
{
// see JLS 15.19
Node left = unaryNumericPromotion(scan(leftTree, p));
Node right = unaryNumericPromotion(scan(rightTree, p));
if (kind == Tree.Kind.LEFT_SHIFT) {
r = new LeftShiftNode(tree, left, right);
} else if (kind == Tree.Kind.RIGHT_SHIFT) {
r = new SignedRightShiftNode(tree, left, right);
} else {
assert kind == Tree.Kind.UNSIGNED_RIGHT_SHIFT;
r = new UnsignedRightShiftNode(tree, left, right);
}
break;
}
case GREATER_THAN:
case GREATER_THAN_EQUAL:
case LESS_THAN:
case LESS_THAN_EQUAL:
{
// see JLS 15.20.1
TypeMirror leftType = TreeUtils.typeOf(leftTree);
if (TypesUtils.isBoxedPrimitive(leftType)) {
leftType = types.unboxedType(leftType);
}
TypeMirror rightType = TreeUtils.typeOf(rightTree);
if (TypesUtils.isBoxedPrimitive(rightType)) {
rightType = types.unboxedType(rightType);
}
TypeMirror promotedType = binaryPromotedType(leftType, rightType);
Node left = binaryNumericPromotion(scan(leftTree, p), promotedType);
Node right = binaryNumericPromotion(scan(rightTree, p), promotedType);
Node node;
if (kind == Tree.Kind.GREATER_THAN) {
node = new GreaterThanNode(tree, left, right);
} else if (kind == Tree.Kind.GREATER_THAN_EQUAL) {
node = new GreaterThanOrEqualNode(tree, left, right);
} else if (kind == Tree.Kind.LESS_THAN) {
node = new LessThanNode(tree, left, right);
} else {
assert kind == Tree.Kind.LESS_THAN_EQUAL;
node = new LessThanOrEqualNode(tree, left, right);
}
extendWithNode(node);
return node;
}
case EQUAL_TO:
case NOT_EQUAL_TO:
{
// see JLS 15.21
TreeInfo leftInfo = getTreeInfo(leftTree);
TreeInfo rightInfo = getTreeInfo(rightTree);
Node left = scan(leftTree, p);
Node right = scan(rightTree, p);
if (leftInfo.isNumeric() && rightInfo.isNumeric() && !(leftInfo.isBoxed() && rightInfo.isBoxed())) {
// JLS 15.21.1 numerical equality
TypeMirror promotedType = binaryPromotedType(leftInfo.unboxedType(), rightInfo.unboxedType());
left = binaryNumericPromotion(left, promotedType);
right = binaryNumericPromotion(right, promotedType);
} else if (leftInfo.isBoolean() && rightInfo.isBoolean() && !(leftInfo.isBoxed() && rightInfo.isBoxed())) {
// JSL 15.21.2 boolean equality
left = unboxAsNeeded(left, leftInfo.isBoxed());
right = unboxAsNeeded(right, rightInfo.isBoxed());
}
Node node;
if (kind == Tree.Kind.EQUAL_TO) {
node = new EqualToNode(tree, left, right);
} else {
assert kind == Tree.Kind.NOT_EQUAL_TO;
node = new NotEqualNode(tree, left, right);
}
extendWithNode(node);
return node;
}
case AND:
case OR:
case XOR:
{
// see JLS 15.22
TypeMirror leftType = TreeUtils.typeOf(leftTree);
TypeMirror rightType = TreeUtils.typeOf(rightTree);
boolean isBooleanOp = TypesUtils.isBooleanType(leftType) && TypesUtils.isBooleanType(rightType);
Node left;
Node right;
if (isBooleanOp) {
left = unbox(scan(leftTree, p));
right = unbox(scan(rightTree, p));
} else if (isNumericOrBoxed(leftType) && isNumericOrBoxed(rightType)) {
TypeMirror promotedType = binaryPromotedType(leftType, rightType);
left = binaryNumericPromotion(scan(leftTree, p), promotedType);
right = binaryNumericPromotion(scan(rightTree, p), promotedType);
} else {
left = unbox(scan(leftTree, p));
right = unbox(scan(rightTree, p));
}
Node node;
if (kind == Tree.Kind.AND) {
node = new BitwiseAndNode(tree, left, right);
} else if (kind == Tree.Kind.OR) {
node = new BitwiseOrNode(tree, left, right);
} else {
assert kind == Tree.Kind.XOR;
node = new BitwiseXorNode(tree, left, right);
}
extendWithNode(node);
return node;
}
case CONDITIONAL_AND:
case CONDITIONAL_OR:
{
// see JLS 15.23 and 15.24
// all necessary labels
Label rightStartL = new Label();
Label shortCircuitL = new Label();
// left-hand side
Node left = scan(leftTree, p);
ConditionalJump cjump;
if (kind == Tree.Kind.CONDITIONAL_AND) {
cjump = new ConditionalJump(rightStartL, shortCircuitL);
cjump.setFalseFlowRule(FlowRule.ELSE_TO_ELSE);
} else {
cjump = new ConditionalJump(shortCircuitL, rightStartL);
cjump.setTrueFlowRule(FlowRule.THEN_TO_THEN);
}
extendWithExtendedNode(cjump);
// right-hand side
addLabelForNextNode(rightStartL);
Node right = scan(rightTree, p);
// conditional expression itself
addLabelForNextNode(shortCircuitL);
Node node;
if (kind == Tree.Kind.CONDITIONAL_AND) {
node = new ConditionalAndNode(tree, left, right);
} else {
node = new ConditionalOrNode(tree, left, right);
}
extendWithNode(node);
return node;
}
default:
throw new BugInCF("unexpected binary tree: " + kind);
}
assert r != null : "unexpected binary tree";
extendWithNode(r);
return r;
}
use of org.checkerframework.dataflow.cfg.node.NotEqualNode in project checker-framework by typetools.
the class ValueTransfer method visitNotEqual.
@Override
public TransferResult<CFValue, CFStore> visitNotEqual(NotEqualNode n, TransferInput<CFValue, CFStore> p) {
TransferResult<CFValue, CFStore> res = super.visitNotEqual(n, p);
Node leftN = n.getLeftOperand();
Node rightN = n.getRightOperand();
CFValue leftV = p.getValueOfSubNode(leftN);
CFValue rightV = p.getValueOfSubNode(rightN);
// if annotations differ, use the one that is more precise for both
// sides (and add it to the store if possible)
res = strengthenAnnotationOfEqualTo(res, leftN, rightN, leftV, rightV, true);
res = strengthenAnnotationOfEqualTo(res, rightN, leftN, rightV, leftV, true);
Boolean leftBoolean = getBooleanValue(leftV);
if (leftBoolean != null) {
CFValue notLeftV = createBooleanCFValue(!leftBoolean);
res = strengthenAnnotationOfEqualTo(res, leftN, rightN, notLeftV, rightV, false);
res = strengthenAnnotationOfEqualTo(res, rightN, leftN, rightV, notLeftV, false);
}
Boolean rightBoolean = getBooleanValue(rightV);
if (rightBoolean != null) {
CFValue notRightV = createBooleanCFValue(!rightBoolean);
res = strengthenAnnotationOfEqualTo(res, leftN, rightN, leftV, notRightV, false);
res = strengthenAnnotationOfEqualTo(res, rightN, leftN, notRightV, leftV, false);
}
return res;
}
use of org.checkerframework.dataflow.cfg.node.NotEqualNode in project checker-framework by typetools.
the class CFAbstractTransfer method visitNotEqual.
@Override
public TransferResult<V, S> visitNotEqual(NotEqualNode n, TransferInput<V, S> p) {
TransferResult<V, S> res = super.visitNotEqual(n, p);
Node leftN = n.getLeftOperand();
Node rightN = n.getRightOperand();
V leftV = p.getValueOfSubNode(leftN);
V rightV = p.getValueOfSubNode(rightN);
if (res.containsTwoStores() && (NodeUtils.isConstantBoolean(leftN, true) || NodeUtils.isConstantBoolean(rightN, true))) {
S thenStore = res.getElseStore();
S elseStore = res.getThenStore();
res = new ConditionalTransferResult<>(res.getResultValue(), thenStore, elseStore);
}
// if annotations differ, use the one that is more precise for both
// sides (and add it to the store if possible)
res = strengthenAnnotationOfEqualTo(res, leftN, rightN, leftV, rightV, true);
res = strengthenAnnotationOfEqualTo(res, rightN, leftN, rightV, leftV, true);
return res;
}
Aggregations