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