@@ -111,34 +111,68 @@ exprt field_sensitivityt::apply(
111111 const member_exprt member{tmp.get_original_expr (), comp};
112112 auto recursive_member =
113113 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)
118128 {
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);
121155 if (was_l2)
122156 {
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);
125159 }
126160 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;
128164 }
129- else if (
130- recursive_member.has_value () && recursive_member->id () == ID_typecast)
165+ else if (for_ssa->id () == ID_typecast)
131166 {
132167 if (was_l2)
133168 {
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);
139171 }
140172 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;
142176 }
143177 }
144178 }
0 commit comments