public abstract class CFAbstractStore<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>> extends Object implements Store<S>, org.plumelib.util.UniqueId
When adding a new field to track values for a code construct (similar to localVariableValues and thisValue), it is important to review all constructors and
 methods in this class for locations where the new field must be handled (such as the copy
 constructor and clearValue), as well as all constructors/methods in subclasses of {code
 CFAbstractStore}. Note that this includes not only overridden methods in the subclasses, but new
 methods in the subclasses as well. Also check if
 BaseTypeVisitor#getJavaExpressionContextFromNode(Node) needs to be updated. Failing to do so may
 result in silent failures that are time consuming to debug.
Store.FlowRule, Store.Kind| Modifier and Type | Field and Description | 
|---|---|
protected CFAbstractAnalysis<V,S,?> | 
analysis
The analysis class this store belongs to. 
 | 
protected Map<ArrayAccess,V> | 
arrayValues
Information collected about array elements, using the internal representation  
ArrayAccess. | 
protected Map<ClassName,V> | 
classValues
Information collected about classname.class values, using the internal representation
  
ClassName. | 
protected Map<FieldAccess,V> | 
fieldValues
Information collected about fields, using the internal representation  
FieldAccess. | 
protected Map<LocalVariable,V> | 
localVariableValues
Information collected about local variables (including method parameters). 
 | 
protected Map<MethodCall,V> | 
methodValues
Information collected about method calls, using the internal representation  
MethodCall. | 
protected boolean | 
sequentialSemantics
Should the analysis use sequential Java semantics (i.e., assume that only one thread is running
 at all times)? 
 | 
protected V | 
thisValue
Information collected about the current object. 
 | 
| Modifier | Constructor and Description | 
|---|---|
protected  | 
CFAbstractStore(CFAbstractAnalysis<V,S,?> analysis,
               boolean sequentialSemantics)
Creates a new CFAbstractStore. 
 | 
protected  | 
CFAbstractStore(CFAbstractStore<V,S> other)
Copy constructor. 
 | 
| Modifier and Type | Method and Description | 
|---|---|
boolean | 
canAlias(JavaExpression a,
        JavaExpression b)
Can the objects  
a and b be aliases? Returns a conservative answer (i.e.,
 returns true if not enough information is available to determine aliasing). | 
static boolean | 
canInsertJavaExpression(JavaExpression expr)
Returns true if  
expr can be stored in this store. | 
void | 
clearValue(JavaExpression expr)
Remove any knowledge about the expression  
expr (correctly deciding where to remove the
 information depending on the type of the expression expr). | 
protected void | 
computeNewValueAndInsert(JavaExpression expr,
                        V value,
                        BinaryOperator<V> merger,
                        boolean permitNondeterministic)
Inserts the result of applying  
merger to value and the previous value for
 expr. | 
S | 
copy()
Returns an exact copy of this store. 
 | 
boolean | 
equals(@Nullable Object o)  | 
V | 
getFieldValue(FieldAccess fieldAccess)
Returns the current abstract value of a field access, or  
null if no information is
 available. | 
Map<FieldAccess,V> | 
getFieldValues()
Returns information about fields. 
 | 
long | 
getUid()  | 
V | 
getValue(ArrayAccessNode n)
Returns the current abstract value of a field access, or  
null if no information is
 available. | 
V | 
getValue(FieldAccessNode n)
Returns the current abstract value of a field access, or  
null if no information is
 available. | 
V | 
getValue(JavaExpression expr)
Returns the current abstract value of a Java expression, or  
null if no information is
 available. | 
V | 
getValue(LocalVariableNode n)
Returns the current abstract value of a local variable, or  
null if no information is
 available. | 
V | 
getValue(MethodInvocationNode n)
Returns the current abstract value of a method call, or  
null if no information is
 available. | 
V | 
getValue(ThisNode n)
Returns the current abstract value of the current object, or  
null if no information is
 available. | 
int | 
hashCode()  | 
void | 
initializeMethodParameter(LocalVariableNode p,
                         V value)
Set the abstract value of a method parameter (only adds the information to the store, does not
 remove any other knowledge). 
 | 
void | 
initializeThisValue(AnnotationMirror a,
                   TypeMirror underlyingType)
Set the value of the current object. 
 | 
void | 
insertOrRefine(JavaExpression expr,
              AnnotationMirror newAnno)
Add the annotation  
newAnno for the expression expr (correctly deciding where to
 store the information depending on the type of the expression expr). | 
protected void | 
insertOrRefine(JavaExpression expr,
              AnnotationMirror newAnno,
              boolean permitNondeterministic)
 | 
void | 
insertOrRefinePermitNondeterministic(JavaExpression expr,
                                    AnnotationMirror newAnno)
Like  
insertOrRefine(JavaExpression, AnnotationMirror), but permits nondeterministic
 expressions to be inserted. | 
void | 
insertThisValue(AnnotationMirror a,
               TypeMirror underlyingType)  | 
void | 
insertValue(JavaExpression expr,
           AnnotationMirror a)
Add the annotation  
a for the expression expr (correctly deciding where to store
 the information depending on the type of the expression expr). | 
void | 
insertValue(JavaExpression expr,
           V value)
Add the abstract value  
value for the expression expr (correctly deciding where
 to store the information depending on the type of the expression expr). | 
protected void | 
insertValue(JavaExpression expr,
           V value,
           boolean permitNondeterministic)
 | 
void | 
insertValuePermitNondeterministic(JavaExpression expr,
                                 AnnotationMirror a)
Like  
insertValue(JavaExpression, AnnotationMirror), but permits nondeterministic
 expressions to be stored. | 
void | 
insertValuePermitNondeterministic(JavaExpression expr,
                                 V value)
Like  
insertValue(JavaExpression, CFAbstractValue), but updates the store even if
 expr is nondeterministic. | 
protected String | 
internalVisualize(CFGVisualizer<V,S,?> viz)
Adds a representation of the internal information of this Store to visualizer  
viz. | 
protected boolean | 
isMonotonicUpdate(FieldAccess fieldAcc,
                 V value)
Return true if fieldAcc is an update of a monotonic qualifier to its target qualifier. 
 | 
protected boolean | 
isSideEffectFree(AnnotatedTypeFactory atypeFactory,
                ExecutableElement method)
Indicates whether the given method is side-effect-free as far as the current store is
 concerned. 
 | 
S | 
leastUpperBound(S other)
Compute the least upper bound of two stores. 
 | 
protected void | 
removeConflicting(ArrayAccess arrayAccess,
                 V val)
Remove any information in the store that might not be true any more after  
arrayAccess
 has been assigned a new value (with the abstract value val). | 
protected void | 
removeConflicting(FieldAccess fieldAccess,
                 V val)
Remove any information in this store that might not be true any more after  
fieldAccess
 has been assigned a new value (with the abstract value val). | 
protected void | 
removeConflicting(LocalVariable var)
Remove any information in this store that might not be true any more after  
localVar has
 been assigned a new value. | 
void | 
replaceValue(JavaExpression expr,
            V value)
Completely replaces the abstract value  
value for the expression expr (correctly
 deciding where to store the information depending on the type of the expression expr). | 
protected boolean | 
shouldInsert(JavaExpression expr,
            V value,
            boolean permitNondeterministic)
Returns true if the given (expression, value) pair can be inserted in the store, namely if the
 value is non-null and the expression does not contain unknown or a nondeterministic expression. 
 | 
protected boolean | 
supersetOf(CFAbstractStore<V,S> other)
Returns true iff this  
CFAbstractStore contains a superset of the map entries of the
 argument CFAbstractStore. | 
String | 
toString()  | 
protected void | 
updateForArrayAssignment(ArrayAccess arrayAccess,
                        V val)
Update the information in the store by considering an assignment with target  
n, where
 the target is an array access. | 
void | 
updateForAssignment(Node n,
                   V val)
Update the information in the store by considering an assignment with target  
n. | 
protected void | 
updateForFieldAccessAssignment(FieldAccess fieldAccess,
                              V val)
Update the information in the store by considering a field assignment with target  
n,
 where the right hand side has the abstract value val. | 
protected void | 
updateForLocalVariableAssignment(LocalVariable receiver,
                                V val)
Set the abstract value of a local variable in the store. 
 | 
void | 
updateForMethodCall(MethodInvocationNode n,
                   AnnotatedTypeFactory atypeFactory,
                   V val)
Remove any information that might not be valid any more after a method call, and add
 information guaranteed by the method. 
 | 
String | 
visualize(CFGVisualizer<?,S,?> viz)
Delegate visualization responsibility to a visualizer. 
 | 
S | 
widenedUpperBound(S previous)
Compute an upper bound of two stores that is wider than the least upper bound of the two
 stores. 
 | 
protected final CFAbstractAnalysis<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>,?> analysis
protected final Map<LocalVariable,V extends CFAbstractValue<V>> localVariableValues
protected V extends CFAbstractValue<V> thisValue
protected Map<FieldAccess,V extends CFAbstractValue<V>> fieldValues
FieldAccess.protected Map<ArrayAccess,V extends CFAbstractValue<V>> arrayValues
ArrayAccess.protected Map<MethodCall,V extends CFAbstractValue<V>> methodValues
MethodCall.protected Map<ClassName,V extends CFAbstractValue<V>> classValues
ClassName.protected final boolean sequentialSemantics
protected CFAbstractStore(CFAbstractAnalysis<V,S,?> analysis, boolean sequentialSemantics)
analysis - the analysis class this store belongs tosequentialSemantics - should the analysis use sequential Java semantics?protected CFAbstractStore(CFAbstractStore<V,S> other)
public Map<FieldAccess,V> getFieldValues()
public long getUid()
getUid in interface org.plumelib.util.UniqueIdpublic void initializeMethodParameter(LocalVariableNode p, V value)
public void initializeThisValue(AnnotationMirror a, TypeMirror underlyingType)
protected boolean isSideEffectFree(AnnotatedTypeFactory atypeFactory, ExecutableElement method)
atypeFactory - the type factory used to retrieve annotations on the method elementmethod - the method elementpublic void updateForMethodCall(MethodInvocationNode n, AnnotatedTypeFactory atypeFactory, V val)
SideEffectFree or Pure), then no information needs to be removed.
   a.f needs to be removed, except
       if the method n cannot modify a.f (e.g., if a is a local variable
       or this, and f is final).
   val in the store.public void insertValue(JavaExpression expr, AnnotationMirror a)
a for the expression expr (correctly deciding where to store
 the information depending on the type of the expression expr).
 This method does not take care of removing other information that might be influenced by changes to certain parts of the state.
If there is already a value v present for expr, then the stronger of the new
 and old value are taken (according to the lattice). Note that this happens per hierarchy, and
 if the store already contains information about a hierarchy other than as hierarchy,
 that information is preserved.
 
If expr is nondeterministic, this method does not insert value into the
 store.
expr - an expressiona - an annotation for the expressionpublic void insertValuePermitNondeterministic(JavaExpression expr, AnnotationMirror a)
insertValue(JavaExpression, AnnotationMirror), but permits nondeterministic
 expressions to be stored.
 For an explanation of when to permit nondeterministic expressions, see insertValuePermitNondeterministic(JavaExpression, CFAbstractValue).
expr - an expressiona - an annotation for the expressionpublic final void insertOrRefine(JavaExpression expr, AnnotationMirror newAnno)
newAnno for the expression expr (correctly deciding where to
 store the information depending on the type of the expression expr).
 This method does not take care of removing other information that might be influenced by changes to certain parts of the state.
If there is already a value v present for expr, then the greatest lower
 bound of the new and old value is inserted into the store.
 
Note that this happens per hierarchy, and if the store already contains information about a
 hierarchy other than newAnno's hierarchy, that information is preserved.
 
If expr is nondeterministic, this method does not insert value into the
 store.
expr - an expressionnewAnno - the expression's annotationpublic final void insertOrRefinePermitNondeterministic(JavaExpression expr, AnnotationMirror newAnno)
insertOrRefine(JavaExpression, AnnotationMirror), but permits nondeterministic
 expressions to be inserted.
 For an explanation of when to permit nondeterministic expressions, see insertValuePermitNondeterministic(JavaExpression, CFAbstractValue).
expr - an expressionnewAnno - the expression's annotationprotected void insertOrRefine(JavaExpression expr, AnnotationMirror newAnno, boolean permitNondeterministic)
insertOrRefine(JavaExpression, AnnotationMirror) and insertOrRefinePermitNondeterministic(org.checkerframework.dataflow.expression.JavaExpression, javax.lang.model.element.AnnotationMirror).expr - an expressionnewAnno - the expression's annotationpermitNondeterministic - whether nondeterministic expressions may be inserted into the
     storepublic static boolean canInsertJavaExpression(JavaExpression expr)
expr can be stored in this store.public final void insertValue(JavaExpression expr, V value)
value for the expression expr (correctly deciding where
 to store the information depending on the type of the expression expr).
 This method does not take care of removing other information that might be influenced by changes to certain parts of the state.
If there is already a value v present for expr, then the stronger of the new
 and old value are taken (according to the lattice). Note that this happens per hierarchy, and
 if the store already contains information about a hierarchy for which value does not
 contain information, then that information is preserved.
 
If expr is nondeterministic, this method does not insert value into the
 store.
expr - the expression to insert in the storevalue - the value of the expressionpublic final void insertValuePermitNondeterministic(JavaExpression expr, V value)
insertValue(JavaExpression, CFAbstractValue), but updates the store even if
 expr is nondeterministic.
 Usually, nondeterministic JavaExpressions should not be stored in a Store. For example, in
 the body of if (nondet() == 3) {...}, the store should not record that the value of
 nondet() is 3, because it might not be 3 the next time nondet() is executed.
 
However, contracts can mention a nondeterministic JavaExpression. For example, a contract
 might have a postcondition thatnondet() is odd. This means that the next call tonondet() will return odd. Such a postcondition may be evicted from the store by calling a
 side-effecting method.
expr - the expression to insert in the storevalue - the value of the expression@EnsuresNonNullIf(expression="#2", result=true) protected boolean shouldInsert(JavaExpression expr, V value, boolean permitNondeterministic)
This method returning true does not guarantee that the value will be inserted; the
 implementation of insertValue( JavaExpression, CFAbstractValue, boolean) might still
 not insert it.
expr - the expression to insert in the storevalue - the value of the expressionpermitNondeterministic - if false, returns false if expr is nondeterministic; if
     true, permits nondeterministic expressions to be placed in the storeprotected void insertValue(JavaExpression expr, V value, boolean permitNondeterministic)
insertValue(JavaExpression, CFAbstractValue) and insertValuePermitNondeterministic(org.checkerframework.dataflow.expression.JavaExpression, javax.lang.model.element.AnnotationMirror).
 Every overriding implementation should start with
 if (!shouldInsert) {
   return;
 }
 expr - the expression to insert in the storevalue - the value of the expressionpermitNondeterministic - if false, does nothing if expr is nondeterministic; if
     true, permits nondeterministic expressions to be placed in the storeprotected void computeNewValueAndInsert(JavaExpression expr, V value, BinaryOperator<V> merger, boolean permitNondeterministic)
merger to value and the previous value for
 expr.expr - the JavaExpressionvalue - the value of the JavaExpressionmerger - the function used to merge value and the previous value of exprpermitNondeterministic - if false, does nothing if expr is nondeterministic; if
     true, permits nondeterministic expressions to be placed in the storeprotected boolean isMonotonicUpdate(FieldAccess fieldAcc, V value)
sequentialSemantics is
 true.public void insertThisValue(AnnotationMirror a, TypeMirror underlyingType)
public void replaceValue(JavaExpression expr, V value)
value for the expression expr (correctly
 deciding where to store the information depending on the type of the expression expr).
 Any previous information is discarded.
 This method does not take care of removing other information that might be influenced by changes to certain parts of the state.
public void clearValue(JavaExpression expr)
expr (correctly deciding where to remove the
 information depending on the type of the expression expr).public V getValue(JavaExpression expr)
null if no information is
 available.null if no information is
     availablepublic V getValue(FieldAccessNode n)
null if no information is
 available.n - the node whose abstract value to returnnull if no information is
     availablepublic V getFieldValue(FieldAccess fieldAccess)
null if no information is
 available.fieldAccess - the field access to look up in this storenull if no information is
     availablepublic V getValue(MethodInvocationNode n)
null if no information is
 available.n - a method callnull if no information is
     availablepublic V getValue(ArrayAccessNode n)
null if no information is
 available.n - the node whose abstract value to returnnull if no information is
     availablepublic void updateForAssignment(Node n, V val)
n.n - the left-hand side of an assignmentval - the right-hand value of an assignmentprotected void updateForFieldAccessAssignment(FieldAccess fieldAccess, V val)
n,
 where the right hand side has the abstract value val.val - the abstract value of the value assigned to n (or null if the
     abstract value is not known).protected void updateForArrayAssignment(ArrayAccess arrayAccess, V val)
n, where
 the target is an array access.
 See removeConflicting(ArrayAccess,CFAbstractValue), as it is called first by this
 method.
protected void updateForLocalVariableAssignment(LocalVariable receiver, V val)
val - the abstract value of the value assigned to n (or null if the
     abstract value is not known).protected void removeConflicting(FieldAccess fieldAccess, V val)
fieldAccess
 has been assigned a new value (with the abstract value val). This includes the
 following steps (assume that fieldAccess is of the form a.f for some
 a.
 fieldAccess, a. This update will raise the abstract value for such field
       accesses to at least val (or the old value, if that was less precise). However,
       this is only necessary if the field g is not final.
   fieldAccess might alias any expression in the receiver b.
   fieldAccess might alias any expression in the receiver a or index i.
 val - the abstract value of the value assigned to n (or null if the
     abstract value is not known).protected void removeConflicting(ArrayAccess arrayAccess, V val)
arrayAccess
 has been assigned a new value (with the abstract value val). This includes the
 following steps (assume that arrayAccess is of the form a[i] for some
 a.
 val - the abstract value of the value assigned to n (or null if the
     abstract value is not known).protected void removeConflicting(LocalVariable var)
localVar has
 been assigned a new value. This includes the following steps:
 localVar might alias any expression in the receiver b.
   localVar might alias the receiver a.
   localVar.
 public boolean canAlias(JavaExpression a, JavaExpression b)
a and b be aliases? Returns a conservative answer (i.e.,
 returns true if not enough information is available to determine aliasing).public V getValue(LocalVariableNode n)
null if no information is
 available.null if no information is
     availablepublic V getValue(ThisNode n)
null if no information is
 available.n - a reference to "this"null if no information is
     availablepublic S leastUpperBound(S other)
StoreImportant: This method must fulfill the following contract:
this.
   other.
   this, even if the signature is
       more permissive.
   leastUpperBound in interface Store<S extends CFAbstractStore<V,S>>public S widenedUpperBound(S previous)
StoreAnalysis. previous must be the previous store.
 A particular analysis might not require widening and should implement this method by calling leastUpperBound.
Important: This method must fulfill the following contract:
this.
   previous.
   this, even if the signature is
       more permissive.
   widenedUpperBound in interface Store<S extends CFAbstractStore<V,S>>previous - must be the previous storeprotected boolean supersetOf(CFAbstractStore<V,S> other)
CFAbstractStore contains a superset of the map entries of the
 argument CFAbstractStore. Note that we test the entry keys and values by Java equality,
 not by any subtype relationship. This method is used primarily to simplify the equals
 predicate.@SideEffectFree public String toString()
public String visualize(CFGVisualizer<?,S,?> viz)
Storeprotected String internalVisualize(CFGVisualizer<V,S,?> viz)
viz.viz - the visualizerStore