use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class SameLenVisitor method commonAssignmentCheck.
/**
* Modifies the common assignment checks to ensure that SameLen annotations are always merged.
* The check is not relaxed in any way.
*/
@Override
protected void commonAssignmentCheck(AnnotatedTypeMirror varType, AnnotatedTypeMirror valueType, Tree valueTree, @CompilerMessageKey String errorKey) {
if (IndexUtil.isSequenceType(valueType.getUnderlyingType()) && TreeUtils.isExpressionTree(valueTree) && !(valueType.hasAnnotation(PolySameLen.class) && varType.hasAnnotation(PolySameLen.class))) {
AnnotationMirror am = valueType.getAnnotation(SameLen.class);
List<String> arraysInAnno = am == null ? new ArrayList<>() : IndexUtil.getValueOfAnnotationWithStringArgument(am);
Receiver rec = FlowExpressions.internalReprOf(atypeFactory, (ExpressionTree) valueTree);
if (rec != null && SameLenAnnotatedTypeFactory.shouldUseInAnnotation(rec)) {
List<String> names = new ArrayList<>();
names.add(rec.toString());
AnnotationMirror newSameLen = atypeFactory.getCombinedSameLen(arraysInAnno, names);
valueType.replaceAnnotation(newSameLen);
}
}
super.commonAssignmentCheck(varType, valueType, valueTree, errorKey);
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class OffsetEquation method createOffsetFromNode.
private static void createOffsetFromNode(Node node, AnnotationProvider factory, OffsetEquation eq, char op) {
Receiver r = FlowExpressions.internalReprOf(factory, node);
if (r instanceof Unknown || r == null) {
if (node instanceof NumericalAdditionNode) {
createOffsetFromNode(((NumericalAdditionNode) node).getLeftOperand(), factory, eq, op);
createOffsetFromNode(((NumericalAdditionNode) node).getRightOperand(), factory, eq, op);
} else if (node instanceof NumericalSubtractionNode) {
createOffsetFromNode(((NumericalSubtractionNode) node).getLeftOperand(), factory, eq, op);
char other = op == '+' ? '-' : '+';
createOffsetFromNode(((NumericalSubtractionNode) node).getRightOperand(), factory, eq, other);
} else {
eq.error = node.toString();
}
} else {
eq.addTerm(op, r.toString());
}
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class UpperBoundTransfer method visitFieldAccess.
/**
* If n is an array length field access, then the type of a.length is the glb
* of @LTEqLengthOf("a") and the value of a.length in the store. This is case 19.
*/
@Override
public TransferResult<CFValue, CFStore> visitFieldAccess(FieldAccessNode n, TransferInput<CFValue, CFStore> in) {
if (NodeUtils.isArrayLengthFieldAccess(n)) {
FieldAccess arrayLength = FlowExpressions.internalReprOfFieldAccess(atypeFactory, n);
Receiver arrayRec = arrayLength.getReceiver();
Tree arrayTree = n.getReceiver().getTree();
TransferResult<CFValue, CFStore> result = visitLengthAccess(n, in, arrayRec, arrayTree);
if (result != null) {
return result;
}
}
return super.visitFieldAccess(n, in);
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class UpperBoundTransfer method refineGT.
/**
* Case 8: if x < y, and y has a type that is related to the length of an array, then x has
* the same type, with an offset that is one less.
*/
@Override
protected void refineGT(Node larger, AnnotationMirror largerAnno, Node smaller, AnnotationMirror smallerAnno, CFStore store, TransferInput<CFValue, CFStore> in) {
// larger > smaller
UBQualifier largerQual = UBQualifier.createUBQualifier(largerAnno);
// larger + 1 >= smaller
UBQualifier largerQualPlus1 = largerQual.plusOffset(1);
UBQualifier rightQualifier = UBQualifier.createUBQualifier(smallerAnno);
UBQualifier refinedRight = rightQualifier.glb(largerQualPlus1);
if (largerQualPlus1.isLessThanLengthQualifier()) {
propagateToOperands((LessThanLengthOf) largerQualPlus1, smaller, in, store);
}
refineSubtrahendWithOffset(larger, smaller, true, in, store);
Receiver rightRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), smaller);
store.insertValue(rightRec, atypeFactory.convertUBQualifierToAnnotation(refinedRight));
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class LockAnnotatedTypeFactory method isExpressionEffectivelyFinal.
/**
* Returns whether or not the expression is effectively final.
*
* <p>This method returns true in the following cases when expr is:
*
* <p>1. a field access and the field is final and the field access expression is effectively
* final as specified by this method.
*
* <p>2. an effectively final local variable.
*
* <p>3. a deterministic method call whose arguments and receiver expression are effectively
* final as specified by this method.
*
* <p>4. a this reference or a class literal
*
* @param expr expression
* @return whether or not the expression is effectively final
*/
boolean isExpressionEffectivelyFinal(Receiver expr) {
if (expr instanceof FieldAccess) {
FieldAccess fieldAccess = (FieldAccess) expr;
Receiver recv = fieldAccess.getReceiver();
// Don't call fieldAccess
return fieldAccess.isFinal() && isExpressionEffectivelyFinal(recv);
} else if (expr instanceof LocalVariable) {
return ElementUtils.isEffectivelyFinal(((LocalVariable) expr).getElement());
} else if (expr instanceof MethodCall) {
MethodCall methodCall = (MethodCall) expr;
for (Receiver param : methodCall.getParameters()) {
if (!isExpressionEffectivelyFinal(param)) {
return false;
}
}
return PurityUtils.isDeterministic(this, methodCall.getElement()) && isExpressionEffectivelyFinal(methodCall.getReceiver());
} else if (expr instanceof ThisReference || expr instanceof ClassName) {
// final too.
return true;
} else {
// type of 'expr' is not supported in @GuardedBy(...) lock expressions
return false;
}
}
Aggregations