use of org.checkerframework.dataflow.expression.FieldAccess in project checker-framework by typetools.
the class UpperBoundTransfer method refineNeqSequenceLength.
/**
* If lengthAccess node is an sequence length field or method access (optionally with a constant
* offset subtracted) and the other node is less than or equal to that sequence length (minus the
* offset), then refine the other node's type to less than the sequence length (minus the offset).
* This is case 12.
*/
private void refineNeqSequenceLength(Node lengthAccess, Node otherNode, AnnotationMirror otherNodeAnno, CFStore store) {
// If lengthAccess is "receiver.length - c" where c is an integer constant,
// then lengthOffset is "c".
int lengthOffset = 0;
if (lengthAccess instanceof NumericalSubtractionNode) {
NumericalSubtractionNode subtraction = (NumericalSubtractionNode) lengthAccess;
Node offsetNode = subtraction.getRightOperand();
Long offsetValue = ValueCheckerUtils.getExactValue(offsetNode.getTree(), atypeFactory.getValueAnnotatedTypeFactory());
if (offsetValue != null && offsetValue > Integer.MIN_VALUE && offsetValue <= Integer.MAX_VALUE) {
lengthOffset = offsetValue.intValue();
lengthAccess = subtraction.getLeftOperand();
} else {
// Subtraction of non-constant expressions is not supported
return;
}
}
JavaExpression receiver = null;
if (NodeUtils.isArrayLengthFieldAccess(lengthAccess)) {
FieldAccess fa = (FieldAccess) JavaExpression.fromNodeFieldAccess((FieldAccessNode) lengthAccess);
receiver = fa.getReceiver();
} else if (atypeFactory.getMethodIdentifier().isLengthOfMethodInvocation(lengthAccess)) {
JavaExpression ma = JavaExpression.fromNode(lengthAccess);
if (ma instanceof MethodCall) {
receiver = ((MethodCall) ma).getReceiver();
}
}
if (receiver != null && !receiver.containsUnknown()) {
UBQualifier otherQualifier = UBQualifier.createUBQualifier(otherNodeAnno, (UpperBoundChecker) atypeFactory.getChecker());
String sequence = receiver.toString();
// Check if otherNode + c - 1 < receiver.length
if (otherQualifier.hasSequenceWithOffset(sequence, lengthOffset - 1)) {
// Add otherNode + c < receiver.length
UBQualifier newQualifier = UBQualifier.createUBQualifier(sequence, Integer.toString(lengthOffset));
otherQualifier = otherQualifier.glb(newQualifier);
for (Node internal : splitAssignments(otherNode)) {
JavaExpression leftJe = JavaExpression.fromNode(internal);
store.insertValue(leftJe, atypeFactory.convertUBQualifierToAnnotation(otherQualifier));
}
}
}
}
use of org.checkerframework.dataflow.expression.FieldAccess in project checker-framework by typetools.
the class InitializationVisitor method checkContract.
@Override
protected boolean checkContract(JavaExpression expr, AnnotationMirror necessaryAnnotation, AnnotationMirror inferredAnnotation, CFAbstractStore<?, ?> store) {
// also use the information about initialized fields to check contracts
final AnnotationMirror invariantAnno = atypeFactory.getFieldInvariantAnnotation();
if (!atypeFactory.getQualifierHierarchy().isSubtype(invariantAnno, necessaryAnnotation) || !(expr instanceof FieldAccess)) {
return super.checkContract(expr, necessaryAnnotation, inferredAnnotation, store);
}
if (expr.containsUnknown()) {
return false;
}
FieldAccess fa = (FieldAccess) expr;
if (fa.getReceiver() instanceof ThisReference || fa.getReceiver() instanceof ClassName) {
@SuppressWarnings("unchecked") Store s = (Store) store;
if (s.isFieldInitialized(fa.getField())) {
AnnotatedTypeMirror fieldType = atypeFactory.getAnnotatedType(fa.getField());
// is this an invariant-field?
if (AnnotationUtils.containsSame(fieldType.getAnnotations(), invariantAnno)) {
return true;
}
}
} else {
@SuppressWarnings("unchecked") Value value = (Value) store.getValue(fa.getReceiver());
Set<AnnotationMirror> receiverAnnoSet;
if (value != null) {
receiverAnnoSet = value.getAnnotations();
} else if (fa.getReceiver() instanceof LocalVariable) {
Element elem = ((LocalVariable) fa.getReceiver()).getElement();
AnnotatedTypeMirror receiverType = atypeFactory.getAnnotatedType(elem);
receiverAnnoSet = receiverType.getAnnotations();
} else {
// Is there anything better we could do?
return false;
}
boolean isReceiverInitialized = false;
for (AnnotationMirror anno : receiverAnnoSet) {
if (atypeFactory.isInitialized(anno)) {
isReceiverInitialized = true;
}
}
AnnotatedTypeMirror fieldType = atypeFactory.getAnnotatedType(fa.getField());
// has the invariant type.
if (isReceiverInitialized && AnnotationUtils.containsSame(fieldType.getAnnotations(), invariantAnno)) {
return true;
}
}
return super.checkContract(expr, necessaryAnnotation, inferredAnnotation, store);
}
use of org.checkerframework.dataflow.expression.FieldAccess in project checker-framework by typetools.
the class InitializationTransfer method visitAssignment.
@Override
public TransferResult<V, S> visitAssignment(AssignmentNode n, TransferInput<V, S> in) {
TransferResult<V, S> result = super.visitAssignment(n, in);
assert result instanceof RegularTransferResult;
JavaExpression lhs = JavaExpression.fromNode(n.getTarget());
// If this is an assignment to a field of 'this', then mark the field as initialized.
if (!lhs.containsUnknown()) {
if (lhs instanceof FieldAccess) {
FieldAccess fa = (FieldAccess) lhs;
result.getRegularStore().addInitializedField(fa);
}
}
return result;
}
use of org.checkerframework.dataflow.expression.FieldAccess in project checker-framework by typetools.
the class InitializationStore method insertValue.
/**
* {@inheritDoc}
*
* <p>If the receiver is a field, and has an invariant annotation, then it can be considered
* initialized.
*/
@Override
public void insertValue(JavaExpression je, V value, boolean permitNondeterministic) {
if (!shouldInsert(je, value, permitNondeterministic)) {
return;
}
InitializationAnnotatedTypeFactory<?, ?, ?, ?> atypeFactory = (InitializationAnnotatedTypeFactory<?, ?, ?, ?>) analysis.getTypeFactory();
QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();
AnnotationMirror invariantAnno = atypeFactory.getFieldInvariantAnnotation();
// Remember fields that have the 'invariant' annotation in the store.
if (je instanceof FieldAccess) {
FieldAccess fieldAccess = (FieldAccess) je;
if (!fieldValues.containsKey(je)) {
Set<AnnotationMirror> declaredAnnos = atypeFactory.getAnnotatedType(fieldAccess.getField()).getAnnotations();
if (AnnotationUtils.containsSame(declaredAnnos, invariantAnno)) {
if (!invariantFields.containsKey(fieldAccess)) {
invariantFields.put(fieldAccess, analysis.createSingleAnnotationValue(invariantAnno, je.getType()));
}
}
}
}
super.insertValue(je, value, permitNondeterministic);
for (AnnotationMirror a : value.getAnnotations()) {
if (qualifierHierarchy.isSubtype(a, invariantAnno)) {
if (je instanceof FieldAccess) {
FieldAccess fa = (FieldAccess) je;
if (fa.getReceiver() instanceof ThisReference || fa.getReceiver() instanceof ClassName) {
addInitializedField(fa.getField());
}
}
}
}
}
use of org.checkerframework.dataflow.expression.FieldAccess in project checker-framework by typetools.
the class InitializationStore method supersetOf.
@Override
protected boolean supersetOf(CFAbstractStore<V, S> o) {
if (!(o instanceof InitializationStore)) {
return false;
}
@SuppressWarnings("unchecked") S other = (S) o;
for (Element field : other.initializedFields) {
if (!initializedFields.contains(field)) {
return false;
}
}
for (FieldAccess invariantField : other.invariantFields.keySet()) {
if (!invariantFields.containsKey(invariantField)) {
return false;
}
}
Map<FieldAccess, V> removedFieldValues = new HashMap<>(invariantFields.size());
Map<FieldAccess, V> removedOtherFieldValues = new HashMap<>(other.invariantFields.size());
try {
// Remove invariant annotated fields to avoid performance issue reported in #1438.
for (FieldAccess invariantField : invariantFields.keySet()) {
V v = fieldValues.remove(invariantField);
removedFieldValues.put(invariantField, v);
}
for (FieldAccess invariantField : other.invariantFields.keySet()) {
V v = other.fieldValues.remove(invariantField);
removedOtherFieldValues.put(invariantField, v);
}
return super.supersetOf(other);
} finally {
// Restore removed values.
fieldValues.putAll(removedFieldValues);
other.fieldValues.putAll(removedOtherFieldValues);
}
}
Aggregations