@@ -155,6 +155,78 @@ simplify_exprt::resultt<> simplify_expr_with_value_sett::simplify_inequality(
155
155
return unchanged (expr);
156
156
}
157
157
158
+ simplify_exprt::resultt<>
159
+ simplify_expr_with_value_sett::simplify_inequality_pointer_object (
160
+ const binary_relation_exprt &expr)
161
+ {
162
+ PRECONDITION (expr.id () == ID_equal || expr.id () == ID_notequal);
163
+ PRECONDITION (expr.is_boolean ());
164
+
165
+ auto collect_objects = [this ](const exprt &pointer)
166
+ {
167
+ std::set<exprt> objects;
168
+ if (auto address_of = expr_try_dynamic_cast<address_of_exprt>(pointer))
169
+ {
170
+ objects.insert (
171
+ object_descriptor_exprt::root_object (address_of->object ()));
172
+ }
173
+ else if (auto ssa_expr = expr_try_dynamic_cast<ssa_exprt>(pointer))
174
+ {
175
+ ssa_exprt l1_expr{*ssa_expr};
176
+ l1_expr.remove_level_2 ();
177
+ const std::vector<exprt> value_set_elements =
178
+ value_set.get_value_set (l1_expr, ns);
179
+
180
+ for (const auto &value_set_element : value_set_elements)
181
+ {
182
+ if (
183
+ value_set_element.id () == ID_unknown ||
184
+ value_set_element.id () == ID_invalid ||
185
+ is_failed_symbol (
186
+ to_object_descriptor_expr (value_set_element).root_object ()))
187
+ {
188
+ objects.clear ();
189
+ break ;
190
+ }
191
+
192
+ objects.insert (
193
+ to_object_descriptor_expr (value_set_element).root_object ());
194
+ }
195
+ }
196
+ return objects;
197
+ };
198
+
199
+ auto lhs_objects =
200
+ collect_objects (to_pointer_object_expr (expr.lhs ()).pointer ());
201
+ auto rhs_objects =
202
+ collect_objects (to_pointer_object_expr (expr.rhs ()).pointer ());
203
+
204
+ if (lhs_objects.size () == 1 && lhs_objects == rhs_objects)
205
+ {
206
+ // there is exactly one pointed-to object on both left-hand and right-hand
207
+ // side, and that object is the same
208
+ return expr.id () == ID_equal ? changed (static_cast <exprt>(true_exprt{}))
209
+ : changed (static_cast <exprt>(false_exprt{}));
210
+ }
211
+
212
+ std::list<exprt> intersection;
213
+ std::set_intersection (
214
+ lhs_objects.begin (),
215
+ lhs_objects.end (),
216
+ rhs_objects.begin (),
217
+ rhs_objects.end (),
218
+ std::back_inserter (intersection));
219
+ if (!lhs_objects.empty () && !rhs_objects.empty () && intersection.empty ())
220
+ {
221
+ // all pointed-to objects on the left-hand side are different from any of
222
+ // the pointed-to objects on the right-hand side
223
+ return expr.id () == ID_equal ? changed (static_cast <exprt>(false_exprt{}))
224
+ : changed (static_cast <exprt>(true_exprt{}));
225
+ }
226
+
227
+ return simplify_exprt::simplify_inequality_pointer_object (expr);
228
+ }
229
+
158
230
simplify_exprt::resultt<>
159
231
simplify_expr_with_value_sett::simplify_pointer_offset (
160
232
const pointer_offset_exprt &expr)
0 commit comments