use of org.checkerframework.checker.interning.qual.InternedDistinct in project checker-framework by typetools.
the class SignednessAnnotatedTypeFactory method isMaskedShiftEitherSignedness.
/**
* Determines if a right shift operation, {@code >>} or {@code >>>}, is masked with a masking
* operation of the form {@code shiftExpr & maskLit} or {@code shiftExpr | maskLit} such that the
* mask renders the shift signedness ({@code >>} vs {@code >>>}) irrelevent by destroying the bits
* duplicated into the shift result. For example, the following pairs of right shifts on {@code
* byte b} both produce the same results under any input, because of their masks:
*
* <p>{@code (b >> 4) & 0x0F == (b >>> 4) & 0x0F;}
*
* <p>{@code (b >> 4) | 0xF0 == (b >>> 4) | 0xF0;}
*
* @param shiftExpr a right shift expression: {@code expr1 >> expr2} or {@code expr1 >>> expr2}
* @param path the path to {@code shiftExpr}
* @return true iff the right shift is masked such that a signed or unsigned right shift has the
* same effect
*/
/*package-private*/
boolean isMaskedShiftEitherSignedness(BinaryTree shiftExpr, TreePath path) {
Pair<Tree, Tree> enclosingPair = TreePathUtil.enclosingNonParen(path);
// enclosing immediately contains shiftExpr or a parenthesized version of shiftExpr
Tree enclosing = enclosingPair.first;
// enclosingChild is a child of enclosing: shiftExpr or a parenthesized version of it.
// comparing AST nodes
@SuppressWarnings("interning:assignment") @InternedDistinct Tree enclosingChild = enclosingPair.second;
if (!isMask(enclosing)) {
return false;
}
BinaryTree maskExpr = (BinaryTree) enclosing;
ExpressionTree shiftAmountExpr = shiftExpr.getRightOperand();
// Determine which child of maskExpr leads to shiftExpr. The other one is the mask.
ExpressionTree mask = maskExpr.getRightOperand() == enclosingChild ? maskExpr.getLeftOperand() : maskExpr.getRightOperand();
// Strip away the parentheses from the mask if any exist
mask = TreeUtils.withoutParens(mask);
if (!isLiteral(shiftAmountExpr) || !isLiteral(mask)) {
return false;
}
LiteralTree shiftLit = (LiteralTree) shiftAmountExpr;
LiteralTree maskLit = (LiteralTree) mask;
return maskIgnoresMSB(maskExpr.getKind(), shiftLit, maskLit, TreeUtils.typeOf(shiftExpr).getKind());
}
use of org.checkerframework.checker.interning.qual.InternedDistinct in project checker-framework by typetools.
the class InterningVisitor method suppressEarlyCompareTo.
/**
* Pattern matches to prevent false positives of the form {@code (a == b || a.compareTo(b) == 0)}.
* Returns true iff the given node fits this pattern.
*
* @return true iff the node fits the pattern (a == b || a.compareTo(b) == 0)
*/
private boolean suppressEarlyCompareTo(final BinaryTree node) {
// Only handle == binary trees
if (node.getKind() != Tree.Kind.EQUAL_TO) {
return false;
}
Tree left = TreeUtils.withoutParens(node.getLeftOperand());
Tree right = TreeUtils.withoutParens(node.getRightOperand());
// Only valid if we're comparing identifiers.
if (!(left.getKind() == Tree.Kind.IDENTIFIER && right.getKind() == Tree.Kind.IDENTIFIER)) {
return false;
}
final Element lhs = TreeUtils.elementFromUse((IdentifierTree) left);
final Element rhs = TreeUtils.elementFromUse((IdentifierTree) right);
// looking for ((a == b || a.compareTo(b) == 0)
Heuristics.Matcher matcherEqOrCompareTo = new Heuristics.Matcher() {
@Override
public Boolean visitBinary(BinaryTree tree, Void p) {
if (tree.getKind() == Tree.Kind.EQUAL_TO) {
// a.compareTo(b) == 0
// looking for a.compareTo(b) or
ExpressionTree leftTree = tree.getLeftOperand();
// b.compareTo(a)
// looking for 0
ExpressionTree rightTree = tree.getRightOperand();
if (rightTree.getKind() != Tree.Kind.INT_LITERAL) {
return false;
}
LiteralTree rightLiteral = (LiteralTree) rightTree;
if (!rightLiteral.getValue().equals(0)) {
return false;
}
return visit(leftTree, p);
} else {
// a == b || a.compareTo(b) == 0
@// AST node comparisons
SuppressWarnings(// AST node comparisons
"interning:assignment") @InternedDistinct ExpressionTree // looking for a==b
leftTree = tree.getLeftOperand();
// looking for a.compareTo(b) == 0
ExpressionTree rightTree = tree.getRightOperand();
// or b.compareTo(a) == 0
if (leftTree != node) {
return false;
}
if (rightTree.getKind() != Tree.Kind.EQUAL_TO) {
return false;
}
return visit(rightTree, p);
}
}
@Override
public Boolean visitMethodInvocation(MethodInvocationTree tree, Void p) {
if (!TreeUtils.isMethodInvocation(tree, comparableCompareTo, checker.getProcessingEnvironment())) {
return false;
}
List<? extends ExpressionTree> args = tree.getArguments();
if (args.size() != 1) {
return false;
}
ExpressionTree arg = args.get(0);
if (arg.getKind() != Tree.Kind.IDENTIFIER) {
return false;
}
Element argElt = TreeUtils.elementFromUse(arg);
ExpressionTree exp = tree.getMethodSelect();
if (exp.getKind() != Tree.Kind.MEMBER_SELECT) {
return false;
}
MemberSelectTree member = (MemberSelectTree) exp;
if (member.getExpression().getKind() != Tree.Kind.IDENTIFIER) {
return false;
}
Element refElt = TreeUtils.elementFromUse(member.getExpression());
if (!((refElt.equals(lhs) && argElt.equals(rhs)) || (refElt.equals(rhs) && argElt.equals(lhs)))) {
return false;
}
return true;
}
};
boolean okay = new Heuristics.Within(new Heuristics.OfKind(Tree.Kind.CONDITIONAL_OR, matcherEqOrCompareTo)).match(getCurrentPath());
return okay;
}
use of org.checkerframework.checker.interning.qual.InternedDistinct in project checker-framework by typetools.
the class AnnotatedTypeFactory method getCurrentMethodReceiver.
/**
* Returns the receiver type of the method enclosing {@code tree}.
*
* <p>The method uses the parameter only if the most enclosing method cannot be found directly.
*
* @param tree the tree used to find the enclosing method.
* @return receiver type of the most enclosing method being visited
* @deprecated Use {@link #getSelfType(Tree)} instead.
*/
@Deprecated
@Nullable
protected final AnnotatedDeclaredType getCurrentMethodReceiver(Tree tree) {
TreePath path = getPath(tree);
if (path == null) {
return null;
}
// used for == test
@SuppressWarnings("interning:assignment") @InternedDistinct MethodTree enclosingMethod = TreePathUtil.enclosingMethod(path);
ClassTree enclosingClass = TreePathUtil.enclosingClass(path);
boolean found = false;
for (Tree member : enclosingClass.getMembers()) {
if (member.getKind() == Tree.Kind.METHOD) {
if (member == enclosingMethod) {
found = true;
}
}
}
if (found && enclosingMethod != null) {
AnnotatedExecutableType method = getAnnotatedType(enclosingMethod);
return method.getReceiverType();
} else {
// We are within an anonymous class or field initializer
return this.getAnnotatedType(enclosingClass);
}
}
Aggregations