use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class LessThanTransfer method visitNumericalSubtraction.
/**
* Case 3.
*/
@Override
public TransferResult<CFValue, CFStore> visitNumericalSubtraction(NumericalSubtractionNode n, TransferInput<CFValue, CFStore> in) {
LessThanAnnotatedTypeFactory factory = (LessThanAnnotatedTypeFactory) analysis.getTypeFactory();
JavaExpression leftJe = JavaExpression.fromNode(n.getLeftOperand());
if (leftJe != null && leftJe.isUnassignableByOtherCode()) {
ValueAnnotatedTypeFactory valueFactory = factory.getValueAnnotatedTypeFactory();
Long right = ValueCheckerUtils.getMinValue(n.getRightOperand().getTree(), valueFactory);
if (right != null && 0 < right) {
// left - right < left iff 0 < right
List<String> expressions = getLessThanExpressions(n.getLeftOperand());
if (!isDoubleOrFloatLiteral(leftJe)) {
if (expressions == null) {
expressions = Collections.singletonList(leftJe.toString());
} else {
expressions = CollectionsPlume.append(expressions, leftJe.toString());
}
}
AnnotationMirror refine = factory.createLessThanQualifier(expressions);
CFValue value = analysis.createSingleAnnotationValue(refine, n.getType());
CFStore info = in.getRegularStore();
return new RegularTransferResult<>(finishValue(value, info), info);
}
}
return super.visitNumericalSubtraction(n, in);
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class SameLenTransfer method visitAssignment.
@Override
public TransferResult<CFValue, CFStore> visitAssignment(AssignmentNode node, TransferInput<CFValue, CFStore> in) {
TransferResult<CFValue, CFStore> result = super.visitAssignment(node, in);
// Handle b = new T[a.length]
if (node.getExpression() instanceof ArrayCreationNode) {
ArrayCreationNode acNode = (ArrayCreationNode) node.getExpression();
if (acNode.getDimensions().size() == 1) {
Node lengthNode = acNode.getDimension(0);
Node lengthNodeReceiver = getLengthReceiver(lengthNode);
if (lengthNodeReceiver != null) {
// "new T[a.length]" or "new T[s.length()]" is the right hand side of the assignment.
// lengthNode is known to be "lengthNodeReceiver.length" or "lengthNodeReceiver.length()"
// targetRec is the receiver for the left hand side of the assignment.
JavaExpression targetRec = JavaExpression.fromNode(node.getTarget());
JavaExpression otherRec = JavaExpression.fromNode(lengthNodeReceiver);
AnnotationMirror lengthNodeAnnotation = aTypeFactory.getAnnotatedType(lengthNodeReceiver.getTree()).getAnnotationInHierarchy(UNKNOWN);
AnnotationMirror combinedSameLen = aTypeFactory.createCombinedSameLen(Arrays.asList(targetRec, otherRec), Arrays.asList(UNKNOWN, lengthNodeAnnotation));
propagateCombinedSameLen(combinedSameLen, node, result.getRegularStore());
return result;
}
}
}
AnnotationMirror rightAnno = aTypeFactory.getAnnotatedType(node.getExpression().getTree()).getAnnotationInHierarchy(UNKNOWN);
// If the left side of the assignment is an array or a string, then have both the right and
// left side be SameLen of each other.
JavaExpression targetRec = JavaExpression.fromNode(node.getTarget());
JavaExpression exprRec = JavaExpression.fromNode(node.getExpression());
if (IndexUtil.isSequenceType(node.getTarget().getType()) || (rightAnno != null && aTypeFactory.areSameByClass(rightAnno, SameLen.class))) {
AnnotationMirror rightAnnoOrUnknown = rightAnno == null ? UNKNOWN : rightAnno;
AnnotationMirror combinedSameLen = aTypeFactory.createCombinedSameLen(Arrays.asList(targetRec, exprRec), Arrays.asList(UNKNOWN, rightAnnoOrUnknown));
propagateCombinedSameLen(combinedSameLen, node, result.getRegularStore());
}
return result;
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class UpperBoundVisitor method processSubsequenceForLHS.
/* Returns the new value of the left hand side after processing the arrays named in the lhs.
* Iff varLtlQual includes LTL(lhsSeq),
* lhsSeq has HSS, and expQual includes LTL(a, -from), then the LTL(lhsSeq) will be removed from varLtlQual
*/
private UBQualifier processSubsequenceForLHS(LessThanLengthOf varLtlQual, UBQualifier expQual) {
UBQualifier newLHS = varLtlQual;
for (String lhsSeq : varLtlQual.getSequences()) {
// check is lhsSeq is an actual LTL
if (varLtlQual.hasSequenceWithOffset(lhsSeq, 0)) {
JavaExpression lhsSeqExpr = parseJavaExpressionString(lhsSeq, atypeFactory, getCurrentPath());
Subsequence subSeq = Subsequence.getSubsequenceFromReceiver(lhsSeqExpr, atypeFactory);
if (subSeq != null) {
String from = subSeq.from;
String a = subSeq.array;
if (expQual.hasSequenceWithOffset(a, Subsequence.negateString(from))) {
// This cast is safe because LTLs cannot contain duplicates.
// Note that this updates newLHS on each iteration from its old value,
// so even if there are multiple HSS arrays the result will be correct.
newLHS = ((LessThanLengthOf) newLHS).removeOffset(lhsSeq, 0);
}
}
}
}
return newLHS;
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class UpperBoundVisitor method getExpressionAndOffsetFromJavaExpressionString.
/**
* Fetches a receiver and an offset from a String using the passed type factory. Returns null if
* there is a parse exception. This wraps GenericAnnotatedTypeFactory#parseJavaExpressionString.
*
* <p>This is useful for expressions like "n+1", for which {@link #parseJavaExpressionString}
* returns null because the whole expression is not a receiver.
*/
static Pair<JavaExpression, String> getExpressionAndOffsetFromJavaExpressionString(String s, UpperBoundAnnotatedTypeFactory atypeFactory, TreePath currentPath) {
Pair<String, String> p = AnnotatedTypeFactory.getExpressionAndOffset(s);
JavaExpression je = parseJavaExpressionString(p.first, atypeFactory, currentPath);
if (je == null) {
return null;
}
return Pair.of(je, p.second);
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class GenericAnnotatedTypeFactory method getAnnotationMirrorFromJavaExpressionString.
/**
* Returns the annotation mirror from dataflow for {@code expression}.
*
* <p>This will output a different annotation than {@link
* #getAnnotationFromJavaExpressionString(String, Tree, TreePath, Class)}, because if the
* specified annotation isn't found in the store, the type from the factory is used.
*
* @param expression a Java expression
* @param tree the tree at the location to parse the expression
* @param currentPath location at which expression is evaluated
* @throws JavaExpressionParseException thrown if the expression cannot be parsed
* @return an AnnotationMirror representing the type in the store at the given location from this
* type factory's type system, or null if one is not available
*/
public AnnotationMirror getAnnotationMirrorFromJavaExpressionString(String expression, Tree tree, TreePath currentPath) throws JavaExpressionParseException {
JavaExpression je = parseJavaExpressionString(expression, currentPath);
if (je == null || !CFAbstractStore.canInsertJavaExpression(je)) {
return null;
}
Store store = getStoreBefore(tree);
Value value = store.getValue(je);
return value != null ? value.getAnnotations().iterator().next() : null;
}
Aggregations