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) |
| 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. |
<W extends GenericAnnotatedTypeFactory<?,?,?,?>,U extends BaseTypeChecker> |
getTypeFactoryOfSubchecker(Class<U> checkerClass) |
protected V |
getValueFromFactory(Tree tree,
Node node) |
protected V |
getValueWithSameAnnotations(TypeMirror type,
V annotatedValue) |
S |
initialStore(UnderlyingAST underlyingAST,
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).
|
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. |
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)
Revert 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> |
visitInstanceOf(InstanceOfNode n,
TransferInput<V,S> p)
Refine the operand of an instanceof check with more specific annotations
if possible.
|
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> |
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, visitConditionalAnd, visitConditionalOr, visitDoubleLiteral, visitExplicitThisLiteral, visitFloatingDivision, visitFloatingRemainder, visitFloatLiteral, visitGreaterThan, visitGreaterThanOrEqual, visitImplicitThisLiteral, visitIntegerDivision, visitIntegerLiteral, visitIntegerRemainder, visitLeftShift, visitLessThan, visitLessThanOrEqual, visitLongLiteral, visitMarker, visitMemberReference, visitMethodAccess, visitNullChk, visitNullLiteral, visitNumericalAddition, visitNumericalMinus, visitNumericalMultiplication, visitNumericalPlus, visitNumericalSubtraction, visitObjectCreation, visitPackageName, visitParameterizedType, visitPrimitiveType, visitReturn, 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, visitConditionalAnd, visitConditionalOr, visitDoubleLiteral, visitExplicitThisLiteral, visitFloatingDivision, visitFloatingRemainder, visitFloatLiteral, visitGreaterThan, visitGreaterThanOrEqual, visitImplicitThisLiteral, visitIntegerDivision, visitIntegerLiteral, visitIntegerRemainder, visitLeftShift, visitLessThan, visitLessThanOrEqual, visitLongLiteral, visitMarker, visitMemberReference, visitMethodAccess, visitNullChk, visitNullLiteral, visitNumericalAddition, visitNumericalMinus, visitNumericalMultiplication, visitNumericalPlus, visitNumericalSubtraction, visitObjectCreation, visitPackageName, visitParameterizedType, visitPrimitiveType, visitReturn, visitShortLiteral, visitSignedRightShift, visitStringConcatenate, visitStringLiteral, visitSuper, visitSynchronized, visitThrow, visitTypeCast, visitUnsignedRightShiftprotected 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)
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, 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).res - The previous result.notEqualTo - 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> 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> 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 TransferResult<V,S> visitInstanceOf(InstanceOfNode n, TransferInput<V,S> p)
visitInstanceOf in interface NodeVisitor<TransferResult<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>,TransferInput<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>>>visitInstanceOf 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>>>public <W extends GenericAnnotatedTypeFactory<?,?,?,?>,U extends BaseTypeChecker> W getTypeFactoryOfSubchecker(Class<U> checkerClass)