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).
|
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, visitValueLiteral
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
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
protected 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>>>