@@ -53,38 +53,90 @@ 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 )
5959 {
60- assigns.insert (lhs);
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)
64+ {
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+ // For expressions of form `v->member`, insert all targets `u->member`,
74+ // where `u` and `v` alias.
75+ else if (op.id () == ID_dereference)
76+ {
77+ const pointer_arithmetict ptr (to_dereference_expr (op).pointer ());
78+ for (const auto &mod : local_may_alias.get (t, ptr.pointer ))
79+ {
80+ if (mod.id () == ID_unknown)
81+ {
82+ continue ;
83+ }
84+ const exprt typed_mod =
85+ typecast_exprt::conditional_cast (mod, ptr.pointer .type ());
86+ exprt to_insert;
87+ if (ptr.offset .is_nil ())
88+ {
89+ // u->member
90+ to_insert = member_exprt (
91+ dereference_exprt{typed_mod}, component_name, lhs.type ());
92+ }
93+ else
94+ {
95+ // (u+offset)->member
96+ to_insert = member_exprt (
97+ dereference_exprt{plus_exprt{typed_mod, ptr.offset }},
98+ component_name,
99+ lhs.type ());
100+ }
101+ new_assigns.insert (to_insert);
102+ }
103+ }
61104 }
62105 else if (lhs.id () == ID_dereference)
63106 {
107+ // All dereference `*v` and their alias `*u` are assigns.
64108 const pointer_arithmetict ptr (to_dereference_expr (lhs).pointer ());
65109 for (const auto &mod : local_may_alias.get (t, ptr.pointer ))
66110 {
67- const typecast_exprt typed_mod{mod, ptr.pointer .type ()};
68111 if (mod.id () == ID_unknown)
69112 {
70113 continue ;
71114 }
115+ const exprt typed_mod =
116+ typecast_exprt::conditional_cast (mod, ptr.pointer .type ());
72117 exprt to_insert;
73118 if (ptr.offset .is_nil ())
74119 to_insert = dereference_exprt{typed_mod};
75120 else
76121 to_insert = dereference_exprt{plus_exprt{typed_mod, ptr.offset }};
77- if (predicate (to_insert))
78- assigns.insert (std::move (to_insert));
122+ new_assigns.insert (std::move (to_insert));
79123 }
80124 }
81125 else if (lhs.id () == ID_if)
82126 {
83127 const if_exprt &if_expr = to_if_expr (lhs);
84128
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);
129+ get_assigns_lhs (
130+ local_may_alias, t, if_expr.true_case (), assigns, predicate);
131+ get_assigns_lhs (
132+ local_may_alias, t, if_expr.false_case (), assigns, predicate);
87133 }
134+
135+ std::copy_if (
136+ new_assigns.begin (),
137+ new_assigns.end (),
138+ std::inserter (assigns, assigns.begin ()),
139+ predicate);
88140}
89141
90142void get_assigns (
0 commit comments