use of org.checkerframework.checker.signedness.qual.Signed in project checker-framework by typetools.
the class SignednessVisitor method visitBinary.
/**
* Enforces the following rules on binary operations involving Unsigned and Signed types:
*
* <ul>
* <li>Do not allow any Unsigned types or PolySigned types in {@literal {/, %}} operations.
* <li>Do not allow signed right shift {@literal {>>}} on an Unsigned type or a PolySigned type.
* <li>Do not allow unsigned right shift {@literal {>>>}} on a Signed type or a PolySigned type.
* <li>Allow any left shift {@literal {<<}}.
* <li>Do not allow non-equality comparisons {@literal {<, <=, >, >=}} on Unsigned types or
* PolySigned types.
* <li>Do not allow the mixing of Signed and Unsigned types.
* </ul>
*/
@Override
public Void visitBinary(BinaryTree node, Void p) {
// Used in diagnostic messages.
ExpressionTree leftOp = node.getLeftOperand();
ExpressionTree rightOp = node.getRightOperand();
Pair<AnnotatedTypeMirror, AnnotatedTypeMirror> argTypes = atypeFactory.binaryTreeArgTypes(node);
AnnotatedTypeMirror leftOpType = argTypes.first;
AnnotatedTypeMirror rightOpType = argTypes.second;
Tree.Kind kind = node.getKind();
switch(kind) {
case DIVIDE:
case REMAINDER:
if (hasUnsignedAnnotation(leftOpType)) {
checker.reportError(leftOp, "operation.unsignedlhs", kind, leftOpType, rightOpType);
} else if (hasUnsignedAnnotation(rightOpType)) {
checker.reportError(rightOp, "operation.unsignedrhs", kind, leftOpType, rightOpType);
}
break;
case RIGHT_SHIFT:
if (hasUnsignedAnnotation(leftOpType) && !atypeFactory.isMaskedShiftEitherSignedness(node, getCurrentPath()) && !atypeFactory.isCastedShiftEitherSignedness(node, getCurrentPath())) {
checker.reportError(leftOp, "shift.signed", kind, leftOpType, rightOpType);
}
break;
case UNSIGNED_RIGHT_SHIFT:
if (hasSignedAnnotation(leftOpType) && !atypeFactory.isMaskedShiftEitherSignedness(node, getCurrentPath()) && !atypeFactory.isCastedShiftEitherSignedness(node, getCurrentPath())) {
checker.reportError(leftOp, "shift.unsigned", kind, leftOpType, rightOpType);
}
break;
case LEFT_SHIFT:
break;
case GREATER_THAN:
case GREATER_THAN_EQUAL:
case LESS_THAN:
case LESS_THAN_EQUAL:
if (hasUnsignedAnnotation(leftOpType)) {
checker.reportError(leftOp, "comparison.unsignedlhs", leftOpType, rightOpType);
} else if (hasUnsignedAnnotation(rightOpType)) {
checker.reportError(rightOp, "comparison.unsignedrhs", leftOpType, rightOpType);
}
break;
case EQUAL_TO:
case NOT_EQUAL_TO:
if (leftOpType.hasAnnotation(Unsigned.class) && rightOpType.hasAnnotation(Signed.class)) {
checker.reportError(node, "comparison.mixed.unsignedlhs", leftOpType, rightOpType);
} else if (leftOpType.hasAnnotation(Signed.class) && rightOpType.hasAnnotation(Unsigned.class)) {
checker.reportError(node, "comparison.mixed.unsignedrhs", leftOpType, rightOpType);
}
break;
case PLUS:
if (TreeUtils.isStringConcatenation(node)) {
AnnotationMirror leftAnno = leftOpType.getEffectiveAnnotations().iterator().next();
AnnotationMirror rightAnno = rightOpType.getEffectiveAnnotations().iterator().next();
if (leftOpType.getKind() != TypeKind.CHAR && !TypesUtils.isDeclaredOfName(leftOpType.getUnderlyingType(), "java.lang.Character") && !atypeFactory.getQualifierHierarchy().isSubtype(leftAnno, atypeFactory.SIGNED)) {
checker.reportError(leftOp, "unsigned.concat");
} else if (rightOpType.getKind() != TypeKind.CHAR && !TypesUtils.isDeclaredOfName(rightOpType.getUnderlyingType(), "java.lang.Character") && !atypeFactory.getQualifierHierarchy().isSubtype(rightAnno, atypeFactory.SIGNED)) {
checker.reportError(rightOp, "unsigned.concat");
}
break;
}
// fall through
default:
if (leftOpType.hasAnnotation(Unsigned.class) && rightOpType.hasAnnotation(Signed.class)) {
checker.reportError(node, "operation.mixed.unsignedlhs", kind, leftOpType, rightOpType);
} else if (leftOpType.hasAnnotation(Signed.class) && rightOpType.hasAnnotation(Unsigned.class)) {
checker.reportError(node, "operation.mixed.unsignedrhs", kind, leftOpType, rightOpType);
}
break;
}
return super.visitBinary(node, p);
}
use of org.checkerframework.checker.signedness.qual.Signed in project checker-framework by typetools.
the class SignednessVisitor method visitCompoundAssignment.
/**
* Enforces the following rules on compound assignments involving Unsigned and Signed types:
*
* <ul>
* <li>Do not allow any Unsigned types or PolySigned types in {@literal {/=, %=}} assignments.
* <li>Do not allow signed right shift {@literal {>>=}} to assign to an Unsigned type or a
* PolySigned type.
* <li>Do not allow unsigned right shift {@literal {>>>=}} to assign to a Signed type or a
* PolySigned type.
* <li>Allow any left shift {@literal {<<=}} assignment.
* <li>Do not allow mixing of Signed and Unsigned types.
* </ul>
*/
@Override
public Void visitCompoundAssignment(CompoundAssignmentTree node, Void p) {
ExpressionTree var = node.getVariable();
ExpressionTree expr = node.getExpression();
Pair<AnnotatedTypeMirror, AnnotatedTypeMirror> argTypes = atypeFactory.compoundAssignmentTreeArgTypes(node);
AnnotatedTypeMirror varType = argTypes.first;
AnnotatedTypeMirror exprType = argTypes.second;
Tree.Kind kind = node.getKind();
switch(kind) {
case DIVIDE_ASSIGNMENT:
case REMAINDER_ASSIGNMENT:
if (hasUnsignedAnnotation(varType)) {
checker.reportError(var, "compound.assignment.unsigned.variable", kindWithoutAssignment(kind), varType, exprType);
} else if (hasUnsignedAnnotation(exprType)) {
checker.reportError(expr, "compound.assignment.unsigned.expression", kindWithoutAssignment(kind), varType, exprType);
}
break;
case RIGHT_SHIFT_ASSIGNMENT:
if (hasUnsignedAnnotation(varType)) {
checker.reportError(var, "compound.assignment.shift.signed", kindWithoutAssignment(kind), varType, exprType);
}
break;
case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT:
if (hasSignedAnnotation(varType)) {
checker.reportError(var, "compound.assignment.shift.unsigned", kindWithoutAssignment(kind), varType, exprType);
}
break;
case LEFT_SHIFT_ASSIGNMENT:
break;
case PLUS_ASSIGNMENT:
if (TreeUtils.isStringCompoundConcatenation(node)) {
if (exprType.getKind() != TypeKind.CHAR && !TypesUtils.isDeclaredOfName(exprType.getUnderlyingType(), "java.lang.Character")) {
AnnotationMirror anno = exprType.getEffectiveAnnotations().iterator().next();
if (!atypeFactory.getQualifierHierarchy().isSubtype(anno, atypeFactory.SIGNED)) {
checker.reportError(node.getExpression(), "unsigned.concat");
}
}
break;
}
// fall through
default:
if (varType.hasAnnotation(Unsigned.class) && exprType.hasAnnotation(Signed.class)) {
checker.reportError(expr, "compound.assignment.mixed.unsigned.variable", kindWithoutAssignment(kind), varType, exprType);
} else if (varType.hasAnnotation(Signed.class) && exprType.hasAnnotation(Unsigned.class)) {
checker.reportError(expr, "compound.assignment.mixed.unsigned.expression", kindWithoutAssignment(kind), varType, exprType);
}
break;
}
return super.visitCompoundAssignment(node, p);
}
Aggregations