|
23 | 23 |
|
24 | 24 | #include "symex_dereference_state.h"
|
25 | 25 |
|
26 |
| -/// Evaluate an ID_address_of expression |
| 26 | +/// Transforms an lvalue expression by replacing any dereference operations it |
| 27 | +/// contains with explicit references to the objects they may point to (using |
| 28 | +/// \ref goto_symext::dereference_rec), and translates `byte_extract,` `member` |
| 29 | +/// and `index` operations into integer offsets from a root symbol (if any). |
| 30 | +/// These are ultimately expressed in the form |
| 31 | +/// `(target_type*)((char*)(&underlying_symbol) + offset)`. |
| 32 | +/// \param expr: expression to replace with normalised, dereference-free form |
| 33 | +/// \param state: working state. See \ref goto_symext::dereference for possible |
| 34 | +/// side-effects of a dereference operation. |
| 35 | +/// \param keep_array: if true and an underlying object is an array, return |
| 36 | +/// its address (`&array`); otherwise return the address of its first element |
| 37 | +/// (`&array[0]). |
| 38 | +/// \return the transformed lvalue expression |
27 | 39 | exprt goto_symext::address_arithmetic(
|
28 | 40 | const exprt &expr,
|
29 | 41 | statet &state,
|
@@ -178,6 +190,13 @@ exprt goto_symext::address_arithmetic(
|
178 | 190 | return result;
|
179 | 191 | }
|
180 | 192 |
|
| 193 | +/// If \p expr is a \ref dereference_exprt, replace it with explicit references |
| 194 | +/// to the objects it may point to. Otherwise recursively apply this function to |
| 195 | +/// \p expr's operands, with special cases for address-of (handled by \ref |
| 196 | +/// goto_symext::address_arithmetic) and certain common expression patterns |
| 197 | +/// such as `&struct.flexible_array[0]` (see inline comments in code). |
| 198 | +/// For full details of this method's pointer replacement and potential side- |
| 199 | +/// effects see \ref goto_symext::dereference |
181 | 200 | void goto_symext::dereference_rec(exprt &expr, statet &state)
|
182 | 201 | {
|
183 | 202 | if(expr.id()==ID_dereference)
|
@@ -294,6 +313,43 @@ void goto_symext::dereference_rec(exprt &expr, statet &state)
|
294 | 313 | }
|
295 | 314 | }
|
296 | 315 |
|
| 316 | +/// Replace all dereference operations within \p expr with explicit references |
| 317 | +/// to the objects they may refer to. For example, the expression `*p1 + *p2` |
| 318 | +/// might be rewritten to `obj1 + (p2 == &obj2 ? obj2 : obj3)` in the case where |
| 319 | +/// `p1` is known to point to `obj1` and `p2` points to either `obj2` or `obj3`. |
| 320 | +/// The expression, and any object references introduced, are renamed to L1 in |
| 321 | +/// the process (so in fact we would get `obj1!0@3 + (p2!0@1 == ....` rather |
| 322 | +/// than the exact example given above). |
| 323 | +/// |
| 324 | +/// It may have two kinds of side-effect: |
| 325 | +/// |
| 326 | +/// 1. When an expression may (or must) point to something which cannot legally |
| 327 | +/// be dereferenced, such as a null pointer or an integer cast to a pointer, |
| 328 | +/// a "failed object" is created instead, via one of two routes: |
| 329 | +/// |
| 330 | +/// a. if the `add_failed_symbols` pass has been run then a pointer-typed |
| 331 | +/// symbol `x` will have a corresponding failed symbol `x$object`. This |
| 332 | +/// is replicated according to L1 renaming on demand, so for example on |
| 333 | +/// the first failed dereference of `x!5@10` we will create |
| 334 | +/// `x$object!5@10` and add that to the symbol table. |
| 335 | +/// This addition is made by |
| 336 | +/// \ref symex_dereference_statet::get_or_create_failed_symbol |
| 337 | +/// |
| 338 | +/// b. if such a failed symbol can't be found then symex will create one of |
| 339 | +/// its own, called `symex::failed_symbol` with some suffix. This is done |
| 340 | +/// by \ref value_set_dereferencet::dereference |
| 341 | +/// |
| 342 | +/// In either case any newly-created symbol is added to \p state's symbol |
| 343 | +/// table and \p expr is altered to refer to it. Typically when \p expr has |
| 344 | +/// some legal targets as well this results in an expression like |
| 345 | +/// `ptr == &real_obj ? real_obj : ptr$object`. |
| 346 | +/// |
| 347 | +/// 2. Any object whose base-name ends with `auto_object` is automatically |
| 348 | +/// initialised when dereferenced for the first time, creating a tree of |
| 349 | +/// pointers leading to fresh objects each time such a pointer is |
| 350 | +/// dereferenced. If new objects are created by this mechanism then |
| 351 | +/// state will be altered (by `symex_assign`) to initialise them. |
| 352 | +/// See \ref auto_objects.cpp for details. |
297 | 353 | void goto_symext::dereference(exprt &expr, statet &state)
|
298 | 354 | {
|
299 | 355 | // The expression needs to be renamed to level 1
|
|
0 commit comments