@@ -53,38 +53,90 @@ 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
59
{
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
+ }
61
104
}
62
105
else if (lhs.id () == ID_dereference)
63
106
{
107
+ // All dereference `*v` and their alias `*u` are assigns.
64
108
const pointer_arithmetict ptr (to_dereference_expr (lhs).pointer ());
65
109
for (const auto &mod : local_may_alias.get (t, ptr.pointer ))
66
110
{
67
- const typecast_exprt typed_mod{mod, ptr.pointer .type ()};
68
111
if (mod.id () == ID_unknown)
69
112
{
70
113
continue ;
71
114
}
115
+ const exprt typed_mod =
116
+ typecast_exprt::conditional_cast (mod, ptr.pointer .type ());
72
117
exprt to_insert;
73
118
if (ptr.offset .is_nil ())
74
119
to_insert = dereference_exprt{typed_mod};
75
120
else
76
121
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));
79
123
}
80
124
}
81
125
else if (lhs.id () == ID_if)
82
126
{
83
127
const if_exprt &if_expr = to_if_expr (lhs);
84
128
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);
87
133
}
134
+
135
+ std::copy_if (
136
+ new_assigns.begin (),
137
+ new_assigns.end (),
138
+ std::inserter (assigns, assigns.begin ()),
139
+ predicate);
88
140
}
89
141
90
142
void get_assigns (
0 commit comments