@@ -111,34 +111,68 @@ exprt field_sensitivityt::apply(
111
111
const member_exprt member{tmp.get_original_expr (), comp};
112
112
auto recursive_member =
113
113
get_subexpression_at_offset (member, be.offset (), be.type (), ns);
114
- if (
115
- recursive_member.has_value () &&
116
- (recursive_member->id () == ID_member ||
117
- recursive_member->id () == ID_index))
114
+ if (!recursive_member.has_value ())
115
+ continue ;
116
+
117
+ // We need to inspect the access path as the resulting expression may
118
+ // involve index expressions. When array field sensitivity is disabled
119
+ // or the size of the array that is indexed into is larger than
120
+ // max_field_sensitivity_array_size then only the expression up to (but
121
+ // excluding) said index expression can be turned into an ssa_exprt.
122
+ exprt full_exprt = *recursive_member;
123
+ exprt *for_ssa = &full_exprt;
124
+ exprt *parent = for_ssa;
125
+ while (parent->id () == ID_typecast)
126
+ parent = &to_typecast_expr (*parent).op ();
127
+ while (parent->id () == ID_member || parent->id () == ID_index)
118
128
{
119
- tmp.type () = be.type ();
120
- tmp.set_expression (*recursive_member);
129
+ if (parent->id () == ID_member)
130
+ {
131
+ parent = &to_member_expr (*parent).compound ();
132
+ }
133
+ else
134
+ {
135
+ parent = &to_index_expr (*parent).array ();
136
+ #ifdef ENABLE_ARRAY_FIELD_SENSITIVITY
137
+ if (
138
+ !to_array_type (parent->type ()).size ().is_constant () ||
139
+ numeric_cast_v<mp_integer>(
140
+ to_constant_expr (to_array_type (parent->type ()).size ())) >
141
+ max_field_sensitivity_array_size)
142
+ {
143
+ for_ssa = parent;
144
+ }
145
+ #else
146
+ for_ssa = parent;
147
+ #endif // ENABLE_ARRAY_FIELD_SENSITIVITY
148
+ }
149
+ }
150
+
151
+ if (for_ssa->id () == ID_index || for_ssa->id () == ID_member)
152
+ {
153
+ tmp.type () = for_ssa->type ();
154
+ tmp.set_expression (*for_ssa);
121
155
if (was_l2)
122
156
{
123
- return apply (
124
- ns, state, state.rename (std::move (tmp), ns).get (), write );
157
+ *for_ssa =
158
+ apply ( ns, state, state.rename (std::move (tmp), ns).get (), write );
125
159
}
126
160
else
127
- return apply (ns, state, std::move (tmp), write );
161
+ *for_ssa = apply (ns, state, std::move (tmp), write );
162
+
163
+ return full_exprt;
128
164
}
129
- else if (
130
- recursive_member.has_value () && recursive_member->id () == ID_typecast)
165
+ else if (for_ssa->id () == ID_typecast)
131
166
{
132
167
if (was_l2)
133
168
{
134
- return apply (
135
- ns,
136
- state,
137
- state.rename (std::move (*recursive_member), ns).get (),
138
- write );
169
+ *for_ssa =
170
+ apply (ns, state, state.rename (*for_ssa, ns).get (), write );
139
171
}
140
172
else
141
- return apply (ns, state, std::move (*recursive_member), write );
173
+ *for_ssa = apply (ns, state, std::move (*for_ssa), write );
174
+
175
+ return full_exprt;
142
176
}
143
177
}
144
178
}
0 commit comments