@@ -53,14 +53,60 @@ void get_assigns_lhs(
5353 assignst &assigns,
5454 std::function<bool (const exprt &)> predicate)
5555{
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)
5964 {
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+ }
61106 }
62107 else if (lhs.id () == ID_dereference)
63108 {
109+ // All dereference `*v` and their alias `*u` are assigns.
64110 const pointer_arithmetict ptr (to_dereference_expr (lhs).pointer ());
65111 for (const auto &mod : local_may_alias.get (t, ptr.pointer ))
66112 {
@@ -74,17 +120,24 @@ void get_assigns_lhs(
74120 to_insert = dereference_exprt{typed_mod};
75121 else
76122 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));
79124 }
80125 }
81126 else if (lhs.id () == ID_if)
82127 {
83128 const if_exprt &if_expr = to_if_expr (lhs);
84129
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);
87134 }
135+
136+ std::copy_if (
137+ new_assigns.begin (),
138+ new_assigns.end (),
139+ std::inserter (assigns, assigns.begin ()),
140+ predicate);
88141}
89142
90143void get_assigns (
0 commit comments