2727# include < iostream>
2828#endif
2929
30- // / Function: abstract_environmentt::eval
31- // / Evaluate the value of an expression relative to the current domain
32- // /
33- // / \param expr: the expression to evaluate
34- // / \param ns: the current namespace
35- // /
36- // / \return The abstract_object representing the value of the expression
3730abstract_object_pointert
3831abstract_environmentt::eval (const exprt &expr, const namespacet &ns) const
3932{
@@ -121,35 +114,6 @@ abstract_environmentt::eval(const exprt &expr, const namespacet &ns) const
121114 }
122115}
123116
124- // / Function: abstract_environmentt::assign
125- // /
126- // / \param expr: the expression to assign to
127- // / \param value: the value to assign to the expression
128- // / \param ns: the namespace
129- // /
130- // / \return A boolean, true if the assignment has changed the domain.
131- // /
132- // / Assign a value to an expression
133- // /
134- // / Assign is in principe simple, it updates the map with the new
135- // / abstract object. The challenge is how to handle write to compound
136- // / objects, for example:
137- // / a[i].x.y = 23;
138- // / In this case we clearly want to update a, but we need to delegate to
139- // / the object in a so that it updates the right part of it (depending on
140- // / what kind of array abstraction it is). So, as we find the variable
141- // / ('a' in this case) we build a stack of which part of it is accessed.
142- // /
143- // / As abstractions may split the assignment into multiple writes (for
144- // / example pointers that could point to several locations, arrays with
145- // / non-constant indexes), each of which has to handle the rest of the
146- // / compound write, thus the stack is passed (to write, which does the
147- // / actual updating) as an explicit argument rather than just via
148- // / recursion.
149- // /
150- // / The same use case (but for the opposite reason; because you will only
151- // / update one of the multiple objects) is also why a merge_write flag is
152- // / needed.
153117bool abstract_environmentt::assign (
154118 const exprt &expr,
155119 const abstract_object_pointert value,
@@ -257,26 +221,6 @@ bool abstract_environmentt::assign(
257221 return true ;
258222}
259223
260- // / Function: abstract_object_pointert abstract_environmentt::write
261- // /
262- // / \param lhs: the abstract object for the left hand side of the write
263- // / (i.e. the one to update).
264- // / \param rhs: the value we are trying to write to the left hand side
265- // / \param remaining_stack: what is left of the stack before the rhs can replace
266- // / or be merged with the rhs
267- // / \param ns: the namespace
268- // / \param merge_write: Are we replacing the left hand side with the
269- // / right hand side (e.g. we know for a fact that
270- // / we are overwriting this object) or could the
271- // / write in fact not take place and therefore we
272- // / should merge to model the case where it did not.
273- // /
274- // / \return A modified version of the rhs after the write has taken place
275- // /
276- // / Write an abstract object onto another respecting a stack of
277- // / member, index and dereference access. This ping-pongs between
278- // / this method and the relevant write methods in abstract_struct,
279- // / abstract_pointer and abstract_array until the stack is empty
280224abstract_object_pointert abstract_environmentt::write (
281225 abstract_object_pointert lhs,
282226 abstract_object_pointert rhs,
@@ -318,20 +262,6 @@ abstract_object_pointert abstract_environmentt::write(
318262 }
319263}
320264
321- // / Function: abstract_environmentt::assume
322- // /
323- // / \param expr: the expression that is to be assumed
324- // / \param ns: the current namespace
325- // /
326- // / \return True if the assume changed the domain.
327- // /
328- // / Reduces the domain to (an over-approximation) of the cases
329- // / when the the expression holds. Used to implement assume
330- // / statements and conditional branches.
331- // / It would be valid to simply return false here because it
332- // / is an over-approximation. We try to do better than that.
333- // / The better the implementation the more precise the results
334- // / will be.
335265bool abstract_environmentt::assume (const exprt &expr, const namespacet &ns)
336266{
337267 // We should only attempt to assume Boolean things
@@ -380,17 +310,6 @@ bool abstract_environmentt::assume(const exprt &expr, const namespacet &ns)
380310 return false ;
381311}
382312
383- // / Function: abstract_environmentt::abstract_object_factory
384- // /
385- // / \param type: the type of the object whose state should be tracked
386- // / \param top: does the type of the object start as top
387- // / \param bottom: does the type of the object start as bottom in
388- // / the two-value domain
389- // /
390- // / \return The abstract object that has been created
391- // /
392- // / Look at the configuration for the sensitivity and create an
393- // / appropriate abstract_object
394313abstract_object_pointert abstract_environmentt::abstract_object_factory (
395314 const typet &type,
396315 const namespacet &ns,
@@ -402,15 +321,6 @@ abstract_object_pointert abstract_environmentt::abstract_object_factory(
402321 type, top, bottom, empty_constant_expr, *this , ns);
403322}
404323
405- // / Function: abstract_environmentt::abstract_object_factory
406- // /
407- // / \param type: the type of the object whose state should be tracked
408- // / \param expr: the starting value of the symbol
409- // /
410- // / \return The abstract object that has been created
411- // /
412- // / Look at the configuration for the sensitivity and create an
413- // / appropriate abstract_object, assigning an appropriate value
414324abstract_object_pointert abstract_environmentt::abstract_object_factory (
415325 const typet &type,
416326 const exprt &e,
@@ -419,19 +329,6 @@ abstract_object_pointert abstract_environmentt::abstract_object_factory(
419329 return abstract_object_factory (type, false , false , e, *this , ns);
420330}
421331
422- // / Function: abstract_environmentt::abstract_object_factory
423- // /
424- // / \param type: the type of the object whose state should be tracked
425- // / \param top: does the type of the object start as top in the two-value domain
426- // / \param bottom: does the type of the object start as bottom in
427- // / the two-value domain
428- // / \param expr: the starting value of the symbol if top and bottom
429- // / are both false
430- // /
431- // / \return The abstract object that has been created
432- // /
433- // / Look at the configuration for the sensitivity and create an
434- // / appropriate abstract_object
435332abstract_object_pointert abstract_environmentt::abstract_object_factory (
436333 const typet &type,
437334 bool top,
@@ -444,13 +341,6 @@ abstract_object_pointert abstract_environmentt::abstract_object_factory(
444341 type, top, bottom, e, environment, ns);
445342}
446343
447- // / Function: abstract_environmentt::merge
448- // /
449- // / \param env: the other environment
450- // /
451- // / \return A Boolean, true when the merge has changed something
452- // /
453- // / Computes the join between "this" and "b"
454344bool abstract_environmentt::merge (const abstract_environmentt &env)
455345{
456346 // Use the sharing_map's "iterative over all differences" functionality
@@ -489,61 +379,35 @@ bool abstract_environmentt::merge(const abstract_environmentt &env)
489379 }
490380}
491381
492- // / Function: abstract_environmentt::havoc
493- // /
494- // / \param havoc_string: diagnostic string to track down havoc causing.
495- // /
496- // / \return None
497- // /
498- // / Set the domain to top
499382void abstract_environmentt::havoc (const std::string &havoc_string)
500383{
501384 // TODO(tkiley): error reporting
502385 make_top ();
503386}
504387
505- // / Function: abstract_environmentt::make_top
506- // /
507- // / Set the domain to top
508388void abstract_environmentt::make_top ()
509389{
510390 // since we assume anything is not in the map is top this is sufficient
511391 map.clear ();
512392 bottom = false ;
513393}
514394
515- // / Function: abstract_environmentt::make_bottom
516- // /
517- // / Set the domain to top
518395void abstract_environmentt::make_bottom ()
519396{
520397 map.clear ();
521398 bottom = true ;
522399}
523400
524- // / abstract_environmentt::is_bottom
525- // /
526- // / Gets whether the domain is bottom
527401bool abstract_environmentt::is_bottom () const
528402{
529403 return map.empty () && bottom;
530404}
531405
532- // / Function: abstract_environmentt::is_top
533- // /
534- // / Gets whether the domain is top
535406bool abstract_environmentt::is_top () const
536407{
537408 return map.empty () && !bottom;
538409}
539410
540- // / Function: abstract_environmentt::output
541- // /
542- // / \param out: the stream to write to
543- // / \param ai: the abstract interpreter that contains this domain
544- // / \param ns: the current namespace
545- // /
546- // / Print out all the values in the abstract object map
547411void abstract_environmentt::output (
548412 std::ostream &out,
549413 const ai_baset &ai,
@@ -562,9 +426,6 @@ void abstract_environmentt::output(
562426 out << " }\n " ;
563427}
564428
565- // / Function: abstract_environmentt::verify
566- // /
567- // / Check there aren't any null pointer mapped values
568429bool abstract_environmentt::verify () const
569430{
570431 decltype (map)::viewt view;
@@ -601,33 +462,11 @@ abstract_object_pointert abstract_environmentt::eval_expression(
601462 return eval_obj->expression_transform (e, operands, *this , ns);
602463}
603464
604- // / Function: abstract_environmentt::erase
605- // /
606- // / \param expr: A symbol to delete from the map
607- // /
608- // /
609- // / Delete a symbol from the map. This is necessary if the
610- // / symbol falls out of scope and should no longer be tracked.
611465void abstract_environmentt::erase (const symbol_exprt &expr)
612466{
613467 map.erase_if_exists (expr.get_identifier ());
614468}
615469
616- // / Function: abstract_environmentt::environment_diff
617- // /
618- // / Inputs: Two abstract_environmentt's that need to be intersected for,
619- // / so that we can find symbols that have changed between
620- // / different domains.
621- // /
622- // / Outputs: An std::vector containing the symbols that are present in
623- // / both environments.
624- // /
625- // / Purpose: For our implementation of variable sensitivity domains, we
626- // / need to be able to efficiently find symbols that have changed
627- // / between different domains. To do this, we need to be able
628- // / to quickly find which symbols have new written locations,
629- // / which we do by finding the intersection between two different
630- // / domains (environments).
631470std::vector<abstract_environmentt::map_keyt>
632471abstract_environmentt::modified_symbols (
633472 const abstract_environmentt &first,
0 commit comments