use of org.checkerframework.dataflow.cfg.node.FloatingRemainderNode in project checker-framework by typetools.
the class CFGTranslationPhaseOne method visitCompoundAssignment.
@Override
public Node visitCompoundAssignment(CompoundAssignmentTree tree, Void p) {
// According the JLS 15.26.2, E1 op= E2 is equivalent to
// E1 = (T) ((E1) op (E2)), where T is the type of E1,
// except that E1 is evaluated only once.
//
Tree.Kind kind = tree.getKind();
switch(kind) {
case DIVIDE_ASSIGNMENT:
case MULTIPLY_ASSIGNMENT:
case REMAINDER_ASSIGNMENT:
{
// see JLS 15.17 and 15.26.2
Node targetLHS = scan(tree.getVariable(), p);
Node value = scan(tree.getExpression(), p);
TypeMirror exprType = TreeUtils.typeOf(tree);
TypeMirror leftType = TreeUtils.typeOf(tree.getVariable());
TypeMirror rightType = TreeUtils.typeOf(tree.getExpression());
TypeMirror promotedType = binaryPromotedType(leftType, rightType);
Node targetRHS = binaryNumericPromotion(targetLHS, promotedType);
value = binaryNumericPromotion(value, promotedType);
BinaryTree operTree = treeBuilder.buildBinary(promotedType, withoutAssignment(kind), tree.getVariable(), tree.getExpression());
handleArtificialTree(operTree);
Node operNode;
if (kind == Tree.Kind.MULTIPLY_ASSIGNMENT) {
operNode = new NumericalMultiplicationNode(operTree, targetRHS, value);
} else if (kind == Tree.Kind.DIVIDE_ASSIGNMENT) {
if (TypesUtils.isIntegralPrimitive(exprType)) {
operNode = new IntegerDivisionNode(operTree, targetRHS, value);
extendWithNodeWithException(operNode, arithmeticExceptionType);
} else {
operNode = new FloatingDivisionNode(operTree, targetRHS, value);
}
} else {
assert kind == Tree.Kind.REMAINDER_ASSIGNMENT;
if (TypesUtils.isIntegralPrimitive(exprType)) {
operNode = new IntegerRemainderNode(operTree, targetRHS, value);
extendWithNodeWithException(operNode, arithmeticExceptionType);
} else {
operNode = new FloatingRemainderNode(operTree, targetRHS, value);
}
}
extendWithNode(operNode);
TypeCastTree castTree = treeBuilder.buildTypeCast(leftType, operTree);
handleArtificialTree(castTree);
TypeCastNode castNode = new TypeCastNode(castTree, operNode, leftType, types);
castNode.setInSource(false);
extendWithNode(castNode);
AssignmentNode assignNode = new AssignmentNode(tree, targetLHS, castNode);
extendWithNode(assignNode);
return assignNode;
}
case MINUS_ASSIGNMENT:
case PLUS_ASSIGNMENT:
{
// see JLS 15.18 and 15.26.2
Node targetLHS = scan(tree.getVariable(), p);
Node value = scan(tree.getExpression(), p);
TypeMirror leftType = TreeUtils.typeOf(tree.getVariable());
TypeMirror rightType = TreeUtils.typeOf(tree.getExpression());
if (TypesUtils.isString(leftType) || TypesUtils.isString(rightType)) {
assert (kind == Tree.Kind.PLUS_ASSIGNMENT);
Node targetRHS = stringConversion(targetLHS);
value = stringConversion(value);
Node r = new StringConcatenateAssignmentNode(tree, targetRHS, value);
extendWithNode(r);
return r;
} else {
TypeMirror promotedType = binaryPromotedType(leftType, rightType);
Node targetRHS = binaryNumericPromotion(targetLHS, promotedType);
value = binaryNumericPromotion(value, promotedType);
BinaryTree operTree = treeBuilder.buildBinary(promotedType, withoutAssignment(kind), tree.getVariable(), tree.getExpression());
handleArtificialTree(operTree);
Node operNode;
if (kind == Tree.Kind.PLUS_ASSIGNMENT) {
operNode = new NumericalAdditionNode(operTree, targetRHS, value);
} else {
assert kind == Tree.Kind.MINUS_ASSIGNMENT;
operNode = new NumericalSubtractionNode(operTree, targetRHS, value);
}
extendWithNode(operNode);
TypeCastTree castTree = treeBuilder.buildTypeCast(leftType, operTree);
handleArtificialTree(castTree);
TypeCastNode castNode = new TypeCastNode(castTree, operNode, leftType, types);
castNode.setInSource(false);
extendWithNode(castNode);
// Map the compound assignment tree to an assignment node, which
// will have the correct type.
AssignmentNode assignNode = new AssignmentNode(tree, targetLHS, castNode);
extendWithNode(assignNode);
return assignNode;
}
}
case LEFT_SHIFT_ASSIGNMENT:
case RIGHT_SHIFT_ASSIGNMENT:
case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT:
{
// see JLS 15.19 and 15.26.2
Node targetLHS = scan(tree.getVariable(), p);
Node value = scan(tree.getExpression(), p);
TypeMirror leftType = TreeUtils.typeOf(tree.getVariable());
Node targetRHS = unaryNumericPromotion(targetLHS);
value = unaryNumericPromotion(value);
BinaryTree operTree = treeBuilder.buildBinary(leftType, withoutAssignment(kind), tree.getVariable(), tree.getExpression());
handleArtificialTree(operTree);
Node operNode;
if (kind == Tree.Kind.LEFT_SHIFT_ASSIGNMENT) {
operNode = new LeftShiftNode(operTree, targetRHS, value);
} else if (kind == Tree.Kind.RIGHT_SHIFT_ASSIGNMENT) {
operNode = new SignedRightShiftNode(operTree, targetRHS, value);
} else {
assert kind == Tree.Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT;
operNode = new UnsignedRightShiftNode(operTree, targetRHS, value);
}
extendWithNode(operNode);
TypeCastTree castTree = treeBuilder.buildTypeCast(leftType, operTree);
handleArtificialTree(castTree);
TypeCastNode castNode = new TypeCastNode(castTree, operNode, leftType, types);
castNode.setInSource(false);
extendWithNode(castNode);
AssignmentNode assignNode = new AssignmentNode(tree, targetLHS, castNode);
extendWithNode(assignNode);
return assignNode;
}
case AND_ASSIGNMENT:
case OR_ASSIGNMENT:
case XOR_ASSIGNMENT:
// see JLS 15.22
Node targetLHS = scan(tree.getVariable(), p);
Node value = scan(tree.getExpression(), p);
TypeMirror leftType = TreeUtils.typeOf(tree.getVariable());
TypeMirror rightType = TreeUtils.typeOf(tree.getExpression());
Node targetRHS = null;
if (isNumericOrBoxed(leftType) && isNumericOrBoxed(rightType)) {
TypeMirror promotedType = binaryPromotedType(leftType, rightType);
targetRHS = binaryNumericPromotion(targetLHS, promotedType);
value = binaryNumericPromotion(value, promotedType);
} else if (TypesUtils.isBooleanType(leftType) && TypesUtils.isBooleanType(rightType)) {
targetRHS = unbox(targetLHS);
value = unbox(value);
} else {
throw new BugInCF("Both arguments to logical operation must be numeric or boolean");
}
BinaryTree operTree = treeBuilder.buildBinary(leftType, withoutAssignment(kind), tree.getVariable(), tree.getExpression());
handleArtificialTree(operTree);
Node operNode;
if (kind == Tree.Kind.AND_ASSIGNMENT) {
operNode = new BitwiseAndNode(operTree, targetRHS, value);
} else if (kind == Tree.Kind.OR_ASSIGNMENT) {
operNode = new BitwiseOrNode(operTree, targetRHS, value);
} else {
assert kind == Tree.Kind.XOR_ASSIGNMENT;
operNode = new BitwiseXorNode(operTree, targetRHS, value);
}
extendWithNode(operNode);
TypeCastTree castTree = treeBuilder.buildTypeCast(leftType, operTree);
handleArtificialTree(castTree);
TypeCastNode castNode = new TypeCastNode(castTree, operNode, leftType, types);
castNode.setInSource(false);
extendWithNode(castNode);
AssignmentNode assignNode = new AssignmentNode(tree, targetLHS, castNode);
extendWithNode(assignNode);
return assignNode;
default:
throw new BugInCF("unexpected compound assignment type");
}
}
use of org.checkerframework.dataflow.cfg.node.FloatingRemainderNode 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;
}
Aggregations