Search in sources :

Example 1 with InternedDistinct

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());
}
Also used : InternedDistinct(org.checkerframework.checker.interning.qual.InternedDistinct) BinaryTree(com.sun.source.tree.BinaryTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) LiteralTree(com.sun.source.tree.LiteralTree) BinaryTree(com.sun.source.tree.BinaryTree) AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) TypeCastTree(com.sun.source.tree.TypeCastTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) PrimitiveTypeTree(com.sun.source.tree.PrimitiveTypeTree) ExpressionTree(com.sun.source.tree.ExpressionTree) LiteralTree(com.sun.source.tree.LiteralTree)

Example 2 with InternedDistinct

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;
}
Also used : Heuristics(org.checkerframework.framework.util.Heuristics) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) MemberSelectTree(com.sun.source.tree.MemberSelectTree) BinaryTree(com.sun.source.tree.BinaryTree) LiteralTree(com.sun.source.tree.LiteralTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) InternedDistinct(org.checkerframework.checker.interning.qual.InternedDistinct) ReturnTree(com.sun.source.tree.ReturnTree) LiteralTree(com.sun.source.tree.LiteralTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) NewClassTree(com.sun.source.tree.NewClassTree) IdentifierTree(com.sun.source.tree.IdentifierTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) IfTree(com.sun.source.tree.IfTree) ExpressionTree(com.sun.source.tree.ExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 3 with InternedDistinct

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);
    }
}
Also used : AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) InternedDistinct(org.checkerframework.checker.interning.qual.InternedDistinct) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ReturnTree(com.sun.source.tree.ReturnTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) NewArrayTree(com.sun.source.tree.NewArrayTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) ClassTree(com.sun.source.tree.ClassTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Aggregations

BinaryTree (com.sun.source.tree.BinaryTree)3 ExpressionTree (com.sun.source.tree.ExpressionTree)3 Tree (com.sun.source.tree.Tree)3 InternedDistinct (org.checkerframework.checker.interning.qual.InternedDistinct)3 ClassTree (com.sun.source.tree.ClassTree)2 CompoundAssignmentTree (com.sun.source.tree.CompoundAssignmentTree)2 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)2 LiteralTree (com.sun.source.tree.LiteralTree)2 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)2 MethodTree (com.sun.source.tree.MethodTree)2 NewClassTree (com.sun.source.tree.NewClassTree)2 ReturnTree (com.sun.source.tree.ReturnTree)2 TypeCastTree (com.sun.source.tree.TypeCastTree)2 AnnotatedTypeTree (com.sun.source.tree.AnnotatedTypeTree)1 AnnotationTree (com.sun.source.tree.AnnotationTree)1 AssignmentTree (com.sun.source.tree.AssignmentTree)1 BlockTree (com.sun.source.tree.BlockTree)1 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)1 IdentifierTree (com.sun.source.tree.IdentifierTree)1 IfTree (com.sun.source.tree.IfTree)1