Skip to content

Commit 7ff4fbd

Browse files
committed
Document symex_dereference
1 parent 4716606 commit 7ff4fbd

6 files changed

+81
-6
lines changed

src/goto-symex/symex_dereference.cpp

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,19 @@ Author: Daniel Kroening, [email protected]
2323

2424
#include "symex_dereference_state.h"
2525

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
2739
exprt goto_symext::address_arithmetic(
2840
const exprt &expr,
2941
statet &state,
@@ -178,6 +190,13 @@ exprt goto_symext::address_arithmetic(
178190
return result;
179191
}
180192

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
181200
void goto_symext::dereference_rec(exprt &expr, statet &state)
182201
{
183202
if(expr.id()==ID_dereference)
@@ -294,6 +313,43 @@ void goto_symext::dereference_rec(exprt &expr, statet &state)
294313
}
295314
}
296315

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.
297353
void goto_symext::dereference(exprt &expr, statet &state)
298354
{
299355
// The expression needs to be renamed to level 1

src/goto-symex/symex_dereference_state.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,21 @@ Author: Daniel Kroening, [email protected]
1313

1414
#include <util/symbol_table.h>
1515

16+
/// Get or create a failed symbol for the given pointer-typed expression. These
17+
/// are used as placeholders when dereferencing expressions that are illegal to
18+
/// dereference, such as null pointers. The \ref add_failed_symbols pass must
19+
/// have been run for this to do anything useful; it annotates a pointer-typed
20+
/// symbol `p` with an `ID_C_failed_symbol` comment, which we then clone on
21+
/// demand due to L1 renaming.
22+
///
23+
/// For example, if \p expr is `p` and it has an `ID_C_failed_symbol` `p$object`
24+
/// (the naming convention used by `add_failed_symbols`), and the latest L1
25+
/// renaming of `p` is `p!2@4`, then we will create `p$object!2@4` if it doesn't
26+
/// already exist.
27+
///
28+
/// \param expr: expression to get or create a failed symbol for
29+
/// \param [out] symbol: failed symbol result
30+
/// \return true if we populated \p symbol
1631
bool symex_dereference_statet::get_or_create_failed_symbol(
1732
const exprt &expr,
1833
const symbolt *&symbol)
@@ -68,6 +83,7 @@ bool symex_dereference_statet::get_or_create_failed_symbol(
6883
return false;
6984
}
7085

86+
/// Just forwards a value-set query to `state.value_set`
7187
void symex_dereference_statet::get_value_set(
7288
const exprt &expr,
7389
value_setst::valuest &value_set) const

src/goto-symex/symex_dereference_state.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ Author: Daniel Kroening, [email protected]
1616

1717
#include "goto_symex.h"
1818

19+
/// Callback object that \ref goto_symext::dereference_rec provides to
20+
/// \ref value_set_dereferencet to provide value sets (from goto-symex's
21+
/// working value set) and retrieve or create failed symbols on demand.
22+
/// For details of symex-dereference's operation see
23+
/// \ref goto_symext::dereference
1924
class symex_dereference_statet:
2025
public dereference_callbackt
2126
{

src/pointer-analysis/goto_program_dereference.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ void goto_program_dereferencet::dereference_failure(
100100
/// and use `dereference` on subexpressions of the form `*p`
101101
/// \param expr: expression in which to remove dereferences
102102
/// \param guard: boolean expression assumed to hold when dereferencing
103-
/// \param mode: unused
104103
void goto_program_dereferencet::dereference_rec(exprt &expr, guardt &guard)
105104
{
106105
if(!has_subexpr(expr, ID_dereference))

src/pointer-analysis/value_set_dereference.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,10 @@ bool value_set_dereferencet::dereference_type_compare(
258258
/// \param pointer_expr: pointer expression that may point to `what`
259259
/// \return a `valuet` object containing `guard`, `value` and `ignore` fields.
260260
/// The `ignore` field is true for a `null` object when `exclude_null_derefs`
261-
/// is true and integer addresses in java mode.
261+
/// is true (set by our creator when they know \p what cannot be null)
262+
//// and for integer addresses in java mode.
262263
/// The guard is an appropriate check to determine whether `pointer_expr`
263-
/// really points to `what`.
264+
/// really points to `what`; for example `pointer_expr == &what`.
264265
/// The value corresponds to the dereferenced pointer_expr assuming it is
265266
/// pointing to the object described by `what`.
266267
/// For example, we might return

src/pointer-analysis/value_set_dereference.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@ class value_set_dereferencet
5555
/// \param pointer: A pointer-typed expression, to
5656
/// be dereferenced.
5757
/// \param guard: A guard, which is assumed to hold when dereferencing.
58-
/// \param mode: Indicates whether the dereferencing is a load or store
59-
// (unused).
6058
virtual exprt dereference(const exprt &pointer, const guardt &guard);
6159

6260
private:

0 commit comments

Comments
 (0)