@@ -53,14 +53,60 @@ void get_assigns_lhs(
53
53
assignst &assigns,
54
54
std::function<bool (const exprt &)> predicate)
55
55
{
56
- if (
57
- (lhs.id () == ID_symbol || lhs.id () == ID_member || lhs.id () == ID_index) &&
58
- predicate (lhs))
56
+ assignst new_assigns;
57
+
58
+ if ((lhs.id () == ID_symbol || lhs.id () == ID_index))
59
+ {
60
+ // All variables `v` and their indexing expressions `v[idx]` are assigns.
61
+ new_assigns.insert (lhs);
62
+ }
63
+ else if (lhs.id () == ID_member)
59
64
{
60
- assigns.insert (lhs);
65
+ auto op = to_member_expr (lhs).struct_op ();
66
+ auto component_name = to_member_expr (lhs).get_component_name ();
67
+
68
+ // Insert expressions of form `v.member`.
69
+ if (op.id () == ID_symbol)
70
+ {
71
+ new_assigns.insert (lhs);
72
+ }
73
+
74
+ // For expressions of form `v->member`, insert all targets `u->member`,
75
+ // where `u` and `v` alias.
76
+ else if (op.id () == ID_dereference)
77
+ {
78
+ const pointer_arithmetict ptr (to_dereference_expr (op).pointer ());
79
+ for (const auto &mod : local_may_alias.get (t, ptr.pointer ))
80
+ {
81
+ const typecast_exprt typed_mod{mod, ptr.pointer .type ()};
82
+ if (mod.id () == ID_unknown)
83
+ {
84
+ continue ;
85
+ }
86
+ exprt to_insert;
87
+ if (ptr.offset .is_nil ())
88
+ {
89
+ // u->member
90
+ to_insert = member_exprt (
91
+ std::move (dereference_exprt{typed_mod}),
92
+ component_name,
93
+ lhs.type ());
94
+ }
95
+ else
96
+ {
97
+ // (u+offset)->member
98
+ to_insert = member_exprt (
99
+ std::move (dereference_exprt{plus_exprt{typed_mod, ptr.offset }}),
100
+ component_name,
101
+ lhs.type ());
102
+ }
103
+ new_assigns.insert (to_insert);
104
+ }
105
+ }
61
106
}
62
107
else if (lhs.id () == ID_dereference)
63
108
{
109
+ // All dereference `*v` and their alias `*u` are assigns.
64
110
const pointer_arithmetict ptr (to_dereference_expr (lhs).pointer ());
65
111
for (const auto &mod : local_may_alias.get (t, ptr.pointer ))
66
112
{
@@ -74,17 +120,24 @@ void get_assigns_lhs(
74
120
to_insert = dereference_exprt{typed_mod};
75
121
else
76
122
to_insert = dereference_exprt{plus_exprt{typed_mod, ptr.offset }};
77
- if (predicate (to_insert))
78
- assigns.insert (std::move (to_insert));
123
+ new_assigns.insert (std::move (to_insert));
79
124
}
80
125
}
81
126
else if (lhs.id () == ID_if)
82
127
{
83
128
const if_exprt &if_expr = to_if_expr (lhs);
84
129
85
- get_assigns_lhs (local_may_alias, t, if_expr.true_case (), assigns);
86
- get_assigns_lhs (local_may_alias, t, if_expr.false_case (), assigns);
130
+ get_assigns_lhs (
131
+ local_may_alias, t, if_expr.true_case (), assigns, predicate);
132
+ get_assigns_lhs (
133
+ local_may_alias, t, if_expr.false_case (), assigns, predicate);
87
134
}
135
+
136
+ std::copy_if (
137
+ new_assigns.begin (),
138
+ new_assigns.end (),
139
+ std::inserter (assigns, assigns.begin ()),
140
+ predicate);
88
141
}
89
142
90
143
void get_assigns (
0 commit comments