Skip to content

Commit e97353c

Browse files
committed
Value-set supported simplifier: add object_size, is_invalid_pointer
We can also use the value set to simplify `object_size` and `is_invalid_pointer` expressions.
1 parent 6b6c8d3 commit e97353c

File tree

3 files changed

+120
-5
lines changed

3 files changed

+120
-5
lines changed

src/goto-symex/simplify_expr_with_value_set.cpp

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}

src/goto-symex/simplify_expr_with_value_set.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ class simplify_expr_with_value_sett : public simplify_exprt
3131
[[nodiscard]] resultt<>
3232
simplify_inequality_pointer_object(const binary_relation_exprt &) override;
3333
[[nodiscard]] resultt<>
34+
simplify_is_invalid_pointer(const unary_exprt &) override;
35+
[[nodiscard]] resultt<>
36+
simplify_object_size(const object_size_exprt &) override;
37+
[[nodiscard]] resultt<>
3438
simplify_pointer_offset(const pointer_offset_exprt &) override;
3539

3640
protected:

src/util/simplify_expr_class.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,11 @@ class simplify_exprt
193193
[[nodiscard]] resultt<> simplify_pointer_object(const pointer_object_exprt &);
194194
[[nodiscard]] resultt<>
195195
simplify_unary_pointer_predicate_preorder(const unary_exprt &);
196-
[[nodiscard]] resultt<> simplify_object_size(const object_size_exprt &);
196+
[[nodiscard]] virtual resultt<>
197+
simplify_object_size(const object_size_exprt &);
197198
[[nodiscard]] resultt<> simplify_is_dynamic_object(const unary_exprt &);
198-
[[nodiscard]] resultt<> simplify_is_invalid_pointer(const unary_exprt &);
199+
[[nodiscard]] virtual resultt<>
200+
simplify_is_invalid_pointer(const unary_exprt &);
199201
[[nodiscard]] resultt<> simplify_object(const exprt &);
200202
[[nodiscard]] resultt<> simplify_unary_minus(const unary_minus_exprt &);
201203
[[nodiscard]] resultt<> simplify_unary_plus(const unary_plus_exprt &);

0 commit comments

Comments
 (0)