CBMC
|
#include <abstract_environment.h>
Public Types | |
using | map_keyt = irep_idt |
Public Member Functions | |
abstract_environmentt ()=delete | |
abstract_environmentt (variable_sensitivity_object_factory_ptrt _object_factory) | |
virtual abstract_object_pointert | eval (const exprt &expr, const namespacet &ns) const |
These three are really the heart of the method. More... | |
virtual bool | assign (const exprt &expr, const abstract_object_pointert &value, const namespacet &ns) |
Assign a value to an expression. More... | |
virtual bool | assume (const exprt &expr, const namespacet &ns) |
Reduces the domain based on a condition. More... | |
exprt | do_assume (const exprt &e, const namespacet &ns) |
virtual abstract_object_pointert | write (const abstract_object_pointert &lhs, const abstract_object_pointert &rhs, std::stack< exprt > remaining_stack, const namespacet &ns, bool merge_write) |
Used within assign to do the actual dispatch. More... | |
void | erase (const symbol_exprt &expr) |
Delete a symbol from the map. More... | |
virtual abstract_object_pointert | abstract_object_factory (const typet &type, const namespacet &ns, bool top, bool bottom) const |
Look at the configuration for the sensitivity and create an appropriate abstract_object. More... | |
virtual abstract_object_pointert | abstract_object_factory (const typet &type, const exprt &e, const namespacet &ns) const |
For converting constants in the program. More... | |
const vsd_configt & | configuration () const |
Exposes the environment configuration. More... | |
virtual bool | merge (const abstract_environmentt &env, const goto_programt::const_targett &merge_location, widen_modet widen_mode) |
Computes the join between "this" and "b". More... | |
virtual void | havoc (const std::string &havoc_string) |
This should be used as a default case / everything else has failed The string is so that I can easily find and diagnose cases where this occurs. More... | |
void | make_top () |
Set the domain to top (i.e. everything) More... | |
void | make_bottom () |
Set the domain to top (i.e. no possible states / unreachable) More... | |
bool | is_bottom () const |
Gets whether the domain is bottom. More... | |
bool | is_top () const |
Gets whether the domain is top. More... | |
void | output (std::ostream &out, const class ai_baset &ai, const namespacet &ns) const |
Print out all the values in the abstract object map. More... | |
exprt | to_predicate () const |
Gives a boolean condition that is true for all values represented by the environment. More... | |
bool | verify () const |
Check the structural invariants are maintained. More... | |
abstract_object_statisticst | gather_statistics (const namespacet &ns) const |
Static Public Member Functions | |
static std::vector< abstract_environmentt::map_keyt > | modified_symbols (const abstract_environmentt &first, const abstract_environmentt &second) |
For our implementation of variable sensitivity domains, we need to be able to efficiently find symbols that have changed between different domains. More... | |
Protected Member Functions | |
virtual abstract_object_pointert | eval_expression (const exprt &e, const namespacet &ns) const |
abstract_object_pointert | resolve_symbol (const exprt &e, const namespacet &ns) const |
Protected Attributes | |
bool | bottom |
sharing_mapt< map_keyt, abstract_object_pointert > | map |
Private Member Functions | |
abstract_object_pointert | abstract_object_factory (const typet &type, bool top, bool bottom, const exprt &e, const abstract_environmentt &environment, const namespacet &ns) const |
Look at the configuration for the sensitivity and create an appropriate abstract_object. More... | |
Private Attributes | |
variable_sensitivity_object_factory_ptrt | object_factory |
Definition at line 40 of file abstract_environment.h.
Definition at line 43 of file abstract_environment.h.
|
delete |
|
inlineexplicit |
Definition at line 47 of file abstract_environment.h.
|
private |
Look at the configuration for the sensitivity and create an appropriate abstract_object.
type | the type of the object whose state should be tracked |
top | does the type of the object start as top in the two-value domain |
bottom | does the type of the object start as bottom in the two-value domain |
e | the starting value of the symbol if top and bottom are both false |
environment | the current environment (normally *this) |
ns | the current variable namespace |
Definition at line 331 of file abstract_environment.cpp.
|
virtual |
For converting constants in the program.
type | the type of the object whose state should be tracked |
e | the starting value of the symbol |
ns | the current variable namespace |
Look at the configuration for the sensitivity and create an appropriate abstract_object, assigning an appropriate value Maybe the two abstract_object_factory methods should be compacted to one call...
Definition at line 323 of file abstract_environment.cpp.
|
virtual |
Look at the configuration for the sensitivity and create an appropriate abstract_object.
type | the type of the object whose state should be tracked |
top | does the type of the object start as top |
bottom | does the type of the object start as bottom in the two-value domain |
ns | the current variable namespace |
Definition at line 312 of file abstract_environment.cpp.
|
virtual |
Assign a value to an expression.
expr | the expression to assign to |
value | the value to assign to the expression |
ns | the namespace |
Assign is in principe simple, it updates the map with the new abstract object. The challenge is how to handle write to compound objects, for example: a[i].x.y = 23; In this case we clearly want to update a, but we need to delegate to the object in a so that it updates the right part of it (depending on what kind of array abstraction it is). So, as we find the variable ('a' in this case) we build a stack of which part of it is accessed.
As abstractions may split the assignment into multiple writes (for example pointers that could point to several locations, arrays with non-constant indexes), each of which has to handle the rest of the compound write, thus the stack is passed (to write, which does the actual updating) as an explicit argument rather than just via recursion.
The same use case (but for the opposite reason; because you will only update one of the multiple objects) is also why a merge_write flag is needed.
Definition at line 147 of file abstract_environment.cpp.
|
virtual |
Reduces the domain based on a condition.
expr | the expression that is to be assumed |
ns | the current namespace |
Reduces the domain to (an over-approximation) of the cases when the the expression holds. Used to implement assume statements and conditional branches. It would be valid to simply return false here because it is an over-approximation. We try to do better than that. The better the implementation the more precise the results will be.
Definition at line 257 of file abstract_environment.cpp.
const vsd_configt & abstract_environmentt::configuration | ( | ) | const |
Exposes the environment configuration.
Definition at line 343 of file abstract_environment.cpp.
exprt abstract_environmentt::do_assume | ( | const exprt & | e, |
const namespacet & | ns | ||
) |
Definition at line 300 of file abstract_environment.cpp.
void abstract_environmentt::erase | ( | const symbol_exprt & | expr | ) |
Delete a symbol from the map.
This is necessary if the symbol falls out of scope and should no longer be tracked.
expr | A symbol to delete from the map |
Definition at line 476 of file abstract_environment.cpp.
|
virtual |
These three are really the heart of the method.
Evaluate the value of an expression relative to the current domain
expr | the expression to evaluate |
ns | the current namespace |
Definition at line 94 of file abstract_environment.cpp.
|
protectedvirtual |
Definition at line 461 of file abstract_environment.cpp.
abstract_object_statisticst abstract_environmentt::gather_statistics | ( | const namespacet & | ns | ) | const |
Definition at line 527 of file abstract_environment.cpp.
|
virtual |
This should be used as a default case / everything else has failed The string is so that I can easily find and diagnose cases where this occurs.
havoc_string | diagnostic string to track down havoc causing. |
Set the domain to top
Definition at line 379 of file abstract_environment.cpp.
bool abstract_environmentt::is_bottom | ( | ) | const |
Gets whether the domain is bottom.
Definition at line 398 of file abstract_environment.cpp.
bool abstract_environmentt::is_top | ( | ) | const |
Gets whether the domain is top.
Definition at line 403 of file abstract_environment.cpp.
void abstract_environmentt::make_bottom | ( | ) |
Set the domain to top (i.e. no possible states / unreachable)
Definition at line 392 of file abstract_environment.cpp.
void abstract_environmentt::make_top | ( | ) |
Set the domain to top (i.e. everything)
Definition at line 385 of file abstract_environment.cpp.
|
virtual |
Computes the join between "this" and "b".
env | the other environment |
merge_location | when the merge is happening |
widen_mode | indicates if this is a widening merge |
Definition at line 348 of file abstract_environment.cpp.
|
static |
For our implementation of variable sensitivity domains, we need to be able to efficiently find symbols that have changed between different domains.
To do this, we need to be able to quickly find which symbols have new written locations, which we do by finding the intersection between two different domains (environments).
Inputs are two abstract_environmentt's that need to be intersected for, so that we can find symbols that have changed between different domains.
Definition at line 482 of file abstract_environment.cpp.
void abstract_environmentt::output | ( | std::ostream & | out, |
const class ai_baset & | ai, | ||
const namespacet & | ns | ||
) | const |
Print out all the values in the abstract object map.
out | the stream to write to |
ai | the abstract interpreter that contains this domain |
ns | the current namespace |
Definition at line 408 of file abstract_environment.cpp.
|
protected |
Definition at line 135 of file abstract_environment.cpp.
exprt abstract_environmentt::to_predicate | ( | ) | const |
Gives a boolean condition that is true for all values represented by the environment.
Definition at line 425 of file abstract_environment.cpp.
bool abstract_environmentt::verify | ( | ) | const |
Check the structural invariants are maintained.
In this case this is checking there aren't any null pointer mapped values
Definition at line 449 of file abstract_environment.cpp.
|
virtual |
Used within assign to do the actual dispatch.
lhs | the abstract object for the left hand side of the write (i.e. the one to update). |
rhs | the value we are trying to write to the left hand side |
remaining_stack | what is left of the stack before the rhs can replace or be merged with the rhs |
ns | the namespace |
merge_write | Are we replacing the left hand side with the right hand side (e.g. we know for a fact that we are overwriting this object) or could the write in fact not take place and therefore we should merge to model the case where it did not. |
Write an abstract object onto another respecting a stack of member, index and dereference access. This ping-pongs between this method and the relevant write methods in abstract_struct, abstract_pointer and abstract_array until the stack is empty
Definition at line 237 of file abstract_environment.cpp.
|
protected |
Definition at line 253 of file abstract_environment.h.
|
protected |
Definition at line 262 of file abstract_environment.h.
|
private |
Definition at line 287 of file abstract_environment.h.