@@ -10,6 +10,7 @@ Author: Michael Tautschnig
1010
1111#include < util/expr_util.h>
1212#include < util/pointer_expr.h>
13+ #include < util/pointer_offset_size.h>
1314#include < util/simplify_expr.h>
1415#include < util/ssa_expr.h>
1516
@@ -188,11 +189,23 @@ simplify_expr_with_value_sett::simplify_inequality_pointer_object(
188189 objects.clear ();
189190 break ;
190191 }
191-
192- objects.insert (
193- to_object_descriptor_expr (value_set_element).root_object ());
192+ else if (value_set_element.id () == ID_null_object)
193+ {
194+ // make sure all NULL objects being considered look the same
195+ objects.insert (exprt{ID_null_object, empty_typet{}});
196+ }
197+ else
198+ {
199+ objects.insert (
200+ to_object_descriptor_expr (value_set_element).root_object ());
201+ }
194202 }
195203 }
204+ else if (
205+ pointer.is_constant () && to_constant_expr (pointer).is_null_pointer ())
206+ {
207+ objects.insert (exprt{ID_null_object, empty_typet{}});
208+ }
196209 return objects;
197210 };
198211
@@ -281,3 +294,99 @@ simplify_expr_with_value_sett::simplify_pointer_offset(
281294 return changed (
282295 simplify_rec (typecast_exprt::conditional_cast (*offset, expr.type ())));
283296}
297+
298+ simplify_exprt::resultt<> simplify_expr_with_value_sett::simplify_object_size (
299+ const object_size_exprt &expr)
300+ {
301+ const exprt &ptr = expr.pointer ();
302+
303+ if (ptr.type ().id () != ID_pointer)
304+ return unchanged (expr);
305+
306+ const ssa_exprt *ssa_symbol_expr = expr_try_dynamic_cast<ssa_exprt>(ptr);
307+
308+ if (!ssa_symbol_expr)
309+ return simplify_exprt::simplify_object_size (expr);
310+
311+ ssa_exprt l1_expr{*ssa_symbol_expr};
312+ l1_expr.remove_level_2 ();
313+ const std::vector<exprt> value_set_elements =
314+ value_set.get_value_set (l1_expr, ns);
315+
316+ std::optional<exprt> object_size;
317+
318+ for (const auto &value_set_element : value_set_elements)
319+ {
320+ if (
321+ value_set_element.id () == ID_unknown ||
322+ value_set_element.id () == ID_invalid ||
323+ is_failed_symbol (
324+ to_object_descriptor_expr (value_set_element).root_object ()) ||
325+ to_object_descriptor_expr (value_set_element).offset ().id () == ID_unknown)
326+ {
327+ object_size.reset ();
328+ break ;
329+ }
330+
331+ auto this_object_size_opt = size_of_expr (
332+ to_object_descriptor_expr (value_set_element).root_object ().type (), ns);
333+ if (
334+ !this_object_size_opt.has_value () ||
335+ (object_size.has_value () && *this_object_size_opt != *object_size))
336+ {
337+ object_size.reset ();
338+ break ;
339+ }
340+ else if (!object_size.has_value ())
341+ {
342+ object_size = this_object_size_opt;
343+ }
344+ }
345+
346+ if (!object_size.has_value ())
347+ return simplify_exprt::simplify_object_size (expr);
348+
349+ return changed (
350+ simplify_rec (typecast_exprt::conditional_cast (*object_size, expr.type ())));
351+ }
352+
353+ simplify_exprt::resultt<>
354+ simplify_expr_with_value_sett::simplify_is_invalid_pointer (
355+ const unary_exprt &expr)
356+ {
357+ const exprt &ptr = expr.op ();
358+
359+ if (ptr.type ().id () != ID_pointer)
360+ return unchanged (expr);
361+
362+ const ssa_exprt *ssa_symbol_expr = expr_try_dynamic_cast<ssa_exprt>(ptr);
363+
364+ if (!ssa_symbol_expr)
365+ return simplify_exprt::simplify_is_invalid_pointer (expr);
366+
367+ ssa_exprt l1_expr{*ssa_symbol_expr};
368+ l1_expr.remove_level_2 ();
369+ const std::vector<exprt> value_set_elements =
370+ value_set.get_value_set (l1_expr, ns);
371+
372+ bool all_valid = !value_set_elements.empty ();
373+
374+ for (const auto &value_set_element : value_set_elements)
375+ {
376+ if (
377+ value_set_element.id () == ID_unknown ||
378+ value_set_element.id () == ID_invalid ||
379+ is_failed_symbol (
380+ to_object_descriptor_expr (value_set_element).root_object ()) ||
381+ to_object_descriptor_expr (value_set_element).offset ().id () == ID_unknown)
382+ {
383+ all_valid = false ;
384+ break ;
385+ }
386+ }
387+
388+ if (all_valid)
389+ return changed (static_cast <exprt>(false_exprt{}));
390+ else
391+ return simplify_exprt::simplify_is_invalid_pointer (expr);
392+ }
0 commit comments