public abstract class CFAbstractTransfer<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>,T extends CFAbstractTransfer<V,S,T>> extends AbstractNodeVisitor<TransferResult<V,S>,TransferInput<V,S>> implements TransferFunction<V,S>
AnnotatedTypeFactory to provide checker-specific logic how to
combine types (e.g., what is the type of a string concatenation, given the types of the two
operands) and as an abstraction function (e.g., determine the annotations on literals).
Design note: CFAbstractTransfer and its subclasses are supposed to act as transfer functions. But, since the AnnotatedTypeFactory already existed and performed checker-independent type propagation, CFAbstractTransfer delegates work to it instead of duplicating some logic in CFAbstractTransfer. The checker-specific subclasses of CFAbstractTransfer do implement transfer function logic themselves.
| Modifier and Type | Field and Description |
|---|---|
protected CFAbstractAnalysis<V,S,T> |
analysis
The analysis class this store belongs to.
|
protected boolean |
sequentialSemantics
Should the analysis use sequential Java semantics (i.e., assume that only one thread is
running at all times)?
|
| Constructor and Description |
|---|
CFAbstractTransfer(CFAbstractAnalysis<V,S,T> analysis) |
CFAbstractTransfer(CFAbstractAnalysis<V,S,T> analysis,
boolean forceConcurrentSemantics)
Constructor that allows forcing concurrent semantics to be on for this instance of
CFAbstractTransfer.
|
| Modifier and Type | Method and Description |
|---|---|
protected void |
addInformationFromPreconditions(S info,
AnnotatedTypeFactory factory,
UnderlyingAST.CFGMethod method,
MethodTree methodTree,
ExecutableElement methodElement)
Add the information from all the preconditions of the method
method with
corresponding tree methodTree to the store info. |
protected V |
finishValue(V value,
S store)
This method is called before returning the abstract value
value as the result of the
transfer function. |
protected V |
finishValue(V value,
S thenStore,
S elseStore)
This method is called before returning the abstract value
value as the result of the
transfer function. |
protected V |
getValueFromFactory(Tree tree,
Node node) |
protected V |
getValueWithSameAnnotations(TypeMirror type,
V annotatedValue) |
S |
initialStore(UnderlyingAST underlyingAST,
@Nullable List<LocalVariableNode> parameters)
The initial store maps method formal parameters to their currently most refined type.
|
protected boolean |
isNotFullyInitializedReceiver(MethodTree methodTree)
Returns true if the receiver of a method might not yet be fully initialized.
|
V |
moreSpecificValue(V value1,
V value2)
Returns the abstract value of
(value1, value2) that is more specific. |
protected void |
processCommonAssignment(TransferInput<V,S> in,
Node lhs,
Node rhs,
S info,
V rhsValue)
Determine abstract value of right-hand side and update the store accordingly to the
assignment.
|
protected void |
processConditionalPostconditions(MethodInvocationNode n,
ExecutableElement methodElement,
Tree tree,
S thenStore,
S elseStore)
Add information based on all conditional postconditions of method
n with tree tree and element method to the appropriate store. |
protected void |
processPostconditions(MethodInvocationNode n,
S store,
ExecutableElement methodElement,
Tree tree)
Add information based on all postconditions of method
n with tree tree and
element method to the store store. |
void |
setFixedInitialStore(S s)
Set a fixed initial Store.
|
protected List<Node> |
splitAssignments(Node node)
Takes a node, and either returns the node itself again (as a singleton list), or if the node
is an assignment node, returns the lhs and rhs (where splitAssignments is applied recursively
to the rhs -- that is, the rhs may not appear in the result, but rather its lhs and rhs may).
|
protected TransferResult<V,S> |
strengthenAnnotationOfEqualTo(TransferResult<V,S> res,
Node firstNode,
Node secondNode,
V firstValue,
V secondValue,
boolean notEqualTo)
Refine the annotation of
secondNode if the annotation secondValue is less
precise than firstvalue. |
boolean |
usesSequentialSemantics() |
TransferResult<V,S> |
visitArrayAccess(ArrayAccessNode n,
TransferInput<V,S> p) |
TransferResult<V,S> |
visitAssignment(AssignmentNode n,
TransferInput<V,S> in) |
TransferResult<V,S> |
visitCase(CaseNode n,
TransferInput<V,S> in)
A case produces no value, but it may imply some facts about the argument to the switch
statement.
|
TransferResult<V,S> |
visitClassName(ClassNameNode n,
TransferInput<V,S> in) |
TransferResult<V,S> |
visitConditionalNot(ConditionalNotNode n,
TransferInput<V,S> p)
Reverse the role of the 'thenStore' and 'elseStore'.
|
TransferResult<V,S> |
visitEqualTo(EqualToNode n,
TransferInput<V,S> p) |
TransferResult<V,S> |
visitFieldAccess(FieldAccessNode n,
TransferInput<V,S> p) |
TransferResult<V,S> |
visitLambdaResultExpression(LambdaResultExpressionNode n,
TransferInput<V,S> in) |
TransferResult<V,S> |
visitLocalVariable(LocalVariableNode n,
TransferInput<V,S> in)
Use the most specific type information available according to the store.
|
TransferResult<V,S> |
visitMethodInvocation(MethodInvocationNode n,
TransferInput<V,S> in) |
TransferResult<V,S> |
visitNarrowingConversion(NarrowingConversionNode n,
TransferInput<V,S> p) |
TransferResult<V,S> |
visitNode(Node n,
TransferInput<V,S> in)
The default visitor returns the input information unchanged, or in the case of conditional
input information, merged.
|
TransferResult<V,S> |
visitNotEqual(NotEqualNode n,
TransferInput<V,S> p) |
TransferResult<V,S> |
visitObjectCreation(ObjectCreationNode n,
TransferInput<V,S> p) |
TransferResult<V,S> |
visitReturn(ReturnNode n,
TransferInput<V,S> p) |
TransferResult<V,S> |
visitStringConcatenateAssignment(StringConcatenateAssignmentNode n,
TransferInput<V,S> in) |
TransferResult<V,S> |
visitStringConversion(StringConversionNode n,
TransferInput<V,S> p) |
TransferResult<V,S> |
visitTernaryExpression(TernaryExpressionNode n,
TransferInput<V,S> p)
The resulting abstract value is the merge of the 'then' and 'else' branch.
|
TransferResult<V,S> |
visitThisLiteral(ThisLiteralNode n,
TransferInput<V,S> in) |
TransferResult<V,S> |
visitVariableDeclaration(VariableDeclarationNode n,
TransferInput<V,S> p) |
TransferResult<V,S> |
visitWideningConversion(WideningConversionNode n,
TransferInput<V,S> p) |
visitArrayCreation, visitArrayType, visitAssertionError, visitBitwiseAnd, visitBitwiseComplement, visitBitwiseOr, visitBitwiseXor, visitBooleanLiteral, visitCharacterLiteral, visitClassDeclaration, visitConditionalAnd, visitConditionalOr, visitDoubleLiteral, visitExplicitThisLiteral, visitFloatingDivision, visitFloatingRemainder, visitFloatLiteral, visitGreaterThan, visitGreaterThanOrEqual, visitImplicitThisLiteral, visitInstanceOf, visitIntegerDivision, visitIntegerLiteral, visitIntegerRemainder, visitLeftShift, visitLessThan, visitLessThanOrEqual, visitLongLiteral, visitMarker, visitMemberReference, visitMethodAccess, visitNullChk, visitNullLiteral, visitNumericalAddition, visitNumericalMinus, visitNumericalMultiplication, visitNumericalPlus, visitNumericalSubtraction, visitPackageName, visitParameterizedType, visitPrimitiveType, visitShortLiteral, visitSignedRightShift, visitStringConcatenate, visitStringLiteral, visitSuper, visitSynchronized, visitThrow, visitTypeCast, visitUnsignedRightShift, visitValueLiteralclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitvisitArrayCreation, visitArrayType, visitAssertionError, visitBitwiseAnd, visitBitwiseComplement, visitBitwiseOr, visitBitwiseXor, visitBooleanLiteral, visitCharacterLiteral, visitClassDeclaration, visitConditionalAnd, visitConditionalOr, visitDoubleLiteral, visitExplicitThisLiteral, visitFloatingDivision, visitFloatingRemainder, visitFloatLiteral, visitGreaterThan, visitGreaterThanOrEqual, visitImplicitThisLiteral, visitInstanceOf, visitIntegerDivision, visitIntegerLiteral, visitIntegerRemainder, visitLeftShift, visitLessThan, visitLessThanOrEqual, visitLongLiteral, visitMarker, visitMemberReference, visitMethodAccess, visitNullChk, visitNullLiteral, visitNumericalAddition, visitNumericalMinus, visitNumericalMultiplication, visitNumericalPlus, visitNumericalSubtraction, visitPackageName, visitParameterizedType, visitPrimitiveType, visitShortLiteral, visitSignedRightShift, visitStringConcatenate, visitStringLiteral, visitSuper, visitSynchronized, visitThrow, visitTypeCast, visitUnsignedRightShiftprotected final CFAbstractAnalysis<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>,T extends CFAbstractTransfer<V,S,T>> analysis
protected final boolean sequentialSemantics
public CFAbstractTransfer(CFAbstractAnalysis<V,S,T> analysis)
public CFAbstractTransfer(CFAbstractAnalysis<V,S,T> analysis, boolean forceConcurrentSemantics)
forceConcurrentSemantics - whether concurrent semantics should be forced to be on. If
false, concurrent semantics are turned off by default, but the user can still turn them
on via -AconcurrentSemantics. If true, the user cannot turn off concurrent
semantics.public boolean usesSequentialSemantics()
protected V finishValue(V value, S store)
value as the result of the
transfer function. By default, the value is not changed but subclasses might decide to
implement some functionality. The store at this position is also passed.protected V finishValue(V value, S thenStore, S elseStore)
value as the result of the
transfer function. By default, the value is not changed but subclasses might decide to
implement some functionality. The store at this position is also passed (two stores, as the
result is a ConditionalTransferResult.protected V getValueFromFactory(Tree tree, Node node)
tree, as computed by the AnnotatedTypeFactory.protected V getValueWithSameAnnotations(TypeMirror type, V annotatedValue)
type and the annotations from annotatedValue.public void setFixedInitialStore(S s)
public S initialStore(UnderlyingAST underlyingAST, @Nullable List<LocalVariableNode> parameters)
initialStore in interface TransferFunction<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>parameters is only set if the underlying AST is a method.protected boolean isNotFullyInitializedReceiver(MethodTree methodTree)
protected void addInformationFromPreconditions(S info, AnnotatedTypeFactory factory, UnderlyingAST.CFGMethod method, MethodTree methodTree, ExecutableElement methodElement)
method with
corresponding tree methodTree to the store info.public TransferResult<V,S> visitNode(Node n, TransferInput<V,S> in)
visitNode in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitClassName(ClassNameNode n, TransferInput<V,S> in)
visitClassName in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitClassName in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitFieldAccess(FieldAccessNode n, TransferInput<V,S> p)
visitFieldAccess in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitFieldAccess in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitArrayAccess(ArrayAccessNode n, TransferInput<V,S> p)
visitArrayAccess in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitArrayAccess in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitLocalVariable(LocalVariableNode n, TransferInput<V,S> in)
visitLocalVariable in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitLocalVariable in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitThisLiteral(ThisLiteralNode n, TransferInput<V,S> in)
visitThisLiteral in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitTernaryExpression(TernaryExpressionNode n, TransferInput<V,S> p)
visitTernaryExpression in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitTernaryExpression in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitConditionalNot(ConditionalNotNode n, TransferInput<V,S> p)
visitConditionalNot in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitConditionalNot in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitEqualTo(EqualToNode n, TransferInput<V,S> p)
visitEqualTo in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitEqualTo in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitNotEqual(NotEqualNode n, TransferInput<V,S> p)
visitNotEqual in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitNotEqual in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>protected TransferResult<V,S> strengthenAnnotationOfEqualTo(TransferResult<V,S> res, Node firstNode, Node secondNode, V firstValue, V secondValue, boolean notEqualTo)
secondNode if the annotation secondValue is less
precise than firstvalue. This is possible, if secondNode is an expression
that is tracked by the store (e.g., a local variable or a field).
Note that when overriding this method, when a new type is inserted into the store, splitAssignments should be called, and the new type should be inserted into the store for each of the resulting nodes.
res - the previous resultnotEqualTo - if true, indicates that the logic is flipped (i.e., the information is
added to the elseStore instead of the thenStore) for a not-equal
comparison.null.protected List<Node> splitAssignments(Node node)
public TransferResult<V,S> visitAssignment(AssignmentNode n, TransferInput<V,S> in)
visitAssignment in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitAssignment in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitReturn(ReturnNode n, TransferInput<V,S> p)
visitReturn in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitReturn in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitLambdaResultExpression(LambdaResultExpressionNode n, TransferInput<V,S> in)
visitLambdaResultExpression in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitLambdaResultExpression in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitStringConcatenateAssignment(StringConcatenateAssignmentNode n, TransferInput<V,S> in)
visitStringConcatenateAssignment in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitStringConcatenateAssignment in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>protected void processCommonAssignment(TransferInput<V,S> in, Node lhs, Node rhs, S info, V rhsValue)
public TransferResult<V,S> visitObjectCreation(ObjectCreationNode n, TransferInput<V,S> p)
visitObjectCreation in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitObjectCreation in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitMethodInvocation(MethodInvocationNode n, TransferInput<V,S> in)
visitMethodInvocation in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitMethodInvocation in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>protected void processPostconditions(MethodInvocationNode n, S store, ExecutableElement methodElement, Tree tree)
n with tree tree and
element method to the store store.protected void processConditionalPostconditions(MethodInvocationNode n, ExecutableElement methodElement, Tree tree, S thenStore, S elseStore)
n with tree tree and element method to the appropriate store.public TransferResult<V,S> visitCase(CaseNode n, TransferInput<V,S> in)
visitCase in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitCase in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public V moreSpecificValue(V value1, V value2)
(value1, value2) that is more specific. If the two are
incomparable, then value1 is returned.public TransferResult<V,S> visitVariableDeclaration(VariableDeclarationNode n, TransferInput<V,S> p)
visitVariableDeclaration in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitVariableDeclaration in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitNarrowingConversion(NarrowingConversionNode n, TransferInput<V,S> p)
visitNarrowingConversion in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitNarrowingConversion in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitWideningConversion(WideningConversionNode n, TransferInput<V,S> p)
visitWideningConversion in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitWideningConversion in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>public TransferResult<V,S> visitStringConversion(StringConversionNode n, TransferInput<V,S> p)
visitStringConversion in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitStringConversion in class AbstractNodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>