13
13
14
14
#include < boost/range/algorithm.hpp>
15
15
16
+ // For documentation of members of `local_value_sett`, see the corresponding
17
+ // header file, `local_value_set.h`.
18
+
16
19
void local_value_sett::make_union_adjusting_evs_types (
17
20
object_mapt &dest,
18
21
const object_mapt &src,
@@ -73,14 +76,35 @@ void local_value_sett::get_value_set(
73
76
baset::get_value_set (tmp, dest, ns, true );
74
77
}
75
78
79
+ // / Value-set analysis accrues a `suffix` as it walks down an expression tree--
80
+ // / for example, it transforms a `get_value_set_rec(x.y.z)` into
81
+ // / `get_value_set_rec(x, suffix = "y.z")`. This function recovers the type
82
+ // / information lost in so doing by examining the type of the root expression
83
+ // / and each subsequent member.
84
+ // / The suffix may also contain the string "[]", which indicates a pointer
85
+ // / dereference or array indexing operation.
86
+ // / \param original_type: Type of root object (in the above example, `x.type()`)
87
+ // / \param suffix: Suffix, a sequence of member and array operators
88
+ // / \param ns: global namespace
89
+ // / \param [out] parent_type: Type of the object referred to excluding the
90
+ // / suffix's last period-delimited element. For example, if suffix is
91
+ // / `x.y[].z[][]`, then this gives the result for `x.y[]`. If there is only
92
+ // / one element in `suffix` (e.g. `.a[]`) then `parent_type` is simply
93
+ // / `original_type`. If suffix is empty then `parent_type` is not assigned.
94
+ // / \param [out] suffix_without_supertypes: is assigned `suffix` with any
95
+ // / leading `[email protected] ` accessors removed. For example, if
96
+ // / `suffix` is `[email protected] [email protected] ` then `suffix_without_supertypes`
97
+ // / will be assigned `.z`.
98
+ // / \return Type of expression `root.suffix`, where `root` has type
99
+ // / `original_type`
76
100
static const typet &type_from_suffix (
77
101
const typet &original_type,
78
102
const std::string &suffix,
79
103
const namespacet &ns,
80
104
typet &parent_type,
81
- std::string &suffix_without_subtypes )
105
+ std::string &suffix_without_supertypes )
82
106
{
83
- suffix_without_subtypes =suffix;
107
+ suffix_without_supertypes =suffix;
84
108
const typet* ret=&original_type;
85
109
size_t next_member=1 ; // Skip initial '.'
86
110
if (suffix.size ()!=0 )
@@ -93,7 +117,8 @@ static const typet &type_from_suffix(
93
117
// of pending members or similar.
94
118
if (suffix[next_member]==' @' )
95
119
{
96
- // This path is (believed to be, supposed to be) Java-specific.
120
+ // This accesses either special fields @class_identifier or @lock,
121
+ // or a superclass field, which has a name like @package.Classname.
97
122
if (has_infix (suffix, " @lock" , next_member) ||
98
123
has_infix (suffix, " @class_identifier" , next_member))
99
124
return static_cast <const typet&>(get_nil_irep ());
@@ -104,10 +129,12 @@ static const typet &type_from_suffix(
104
129
assert (has_infix (suffix, subclass_name, next_member));
105
130
ret=&subclass_comp.type ();
106
131
next_member+=(subclass_name.size ()+1 );
107
- suffix_without_subtypes =suffix.substr (next_member-1 );
132
+ suffix_without_supertypes =suffix.substr (next_member-1 );
108
133
}
109
134
else
110
135
{
136
+ // This accesses a struct member and then dereferences it one or more
137
+ // times (for example, .x[][] gets field x and then derefs it twice)
111
138
size_t member_after=suffix.find (' .' , next_member);
112
139
if (member_after==std::string::npos)
113
140
member_after=suffix.size ();
@@ -135,7 +162,6 @@ static const typet &type_from_suffix(
135
162
return *ret;
136
163
}
137
164
138
- // Override value_sett to provide behaviour for external value sets
139
165
void local_value_sett::get_value_set_rec (
140
166
const exprt &expr,
141
167
object_mapt &dest,
@@ -197,6 +223,10 @@ void local_value_sett::get_value_set_rec(
197
223
" []" :
198
224
suffix_without_subtype;
199
225
const auto &extinit=to_external_value_set (expr);
226
+
227
+ // If we're reading from `EVS(A.b)` then initialize an entry for that
228
+ // EVS containing an initializer (e.g.
229
+ // `external_objects.A.b <- { EVS(A.b) }`.
200
230
access_path_entry_exprt newentry (
201
231
access_path_suffix,
202
232
function,
@@ -228,9 +258,6 @@ void local_value_sett::get_value_set_rec(
228
258
}
229
259
}
230
260
231
- // / Applying side effects needed in Recency Analysis.
232
- // / \param rhs: Right-hand-side of an assignment code expression.
233
- // / \param ns: Namespace.
234
261
void local_value_sett::apply_side_effects (
235
262
const exprt &rhs,
236
263
const namespacet &ns)
0 commit comments