@@ -10,6 +10,7 @@ Author: Michael Tautschnig
10
10
11
11
#include < util/expr_util.h>
12
12
#include < util/pointer_expr.h>
13
+ #include < util/pointer_offset_size.h>
13
14
#include < util/simplify_expr.h>
14
15
#include < util/ssa_expr.h>
15
16
@@ -193,6 +194,12 @@ simplify_expr_with_value_sett::simplify_inequality_pointer_object(
193
194
to_object_descriptor_expr (value_set_element).root_object ());
194
195
}
195
196
}
197
+ else if (
198
+ pointer.is_constant () && to_constant_expr (pointer).is_null_pointer ())
199
+ {
200
+ objects.insert (
201
+ exprt{ID_null_object, to_pointer_type (pointer.type ()).base_type ()});
202
+ }
196
203
return objects;
197
204
};
198
205
@@ -281,3 +288,99 @@ simplify_expr_with_value_sett::simplify_pointer_offset(
281
288
return changed (
282
289
simplify_rec (typecast_exprt::conditional_cast (*offset, expr.type ())));
283
290
}
291
+
292
+ simplify_exprt::resultt<> simplify_expr_with_value_sett::simplify_object_size (
293
+ const object_size_exprt &expr)
294
+ {
295
+ const exprt &ptr = expr.pointer ();
296
+
297
+ if (ptr.type ().id () != ID_pointer)
298
+ return unchanged (expr);
299
+
300
+ const ssa_exprt *ssa_symbol_expr = expr_try_dynamic_cast<ssa_exprt>(ptr);
301
+
302
+ if (!ssa_symbol_expr)
303
+ return simplify_exprt::simplify_object_size (expr);
304
+
305
+ ssa_exprt l1_expr{*ssa_symbol_expr};
306
+ l1_expr.remove_level_2 ();
307
+ const std::vector<exprt> value_set_elements =
308
+ value_set.get_value_set (l1_expr, ns);
309
+
310
+ std::optional<exprt> object_size;
311
+
312
+ for (const auto &value_set_element : value_set_elements)
313
+ {
314
+ if (
315
+ value_set_element.id () == ID_unknown ||
316
+ value_set_element.id () == ID_invalid ||
317
+ is_failed_symbol (
318
+ to_object_descriptor_expr (value_set_element).root_object ()) ||
319
+ to_object_descriptor_expr (value_set_element).offset ().id () == ID_unknown)
320
+ {
321
+ object_size.reset ();
322
+ break ;
323
+ }
324
+
325
+ auto this_object_size_opt = size_of_expr (
326
+ to_object_descriptor_expr (value_set_element).root_object ().type (), ns);
327
+ if (
328
+ !this_object_size_opt.has_value () ||
329
+ (object_size.has_value () && *this_object_size_opt != *object_size))
330
+ {
331
+ object_size.reset ();
332
+ break ;
333
+ }
334
+ else if (!object_size.has_value ())
335
+ {
336
+ object_size = this_object_size_opt;
337
+ }
338
+ }
339
+
340
+ if (!object_size.has_value ())
341
+ return simplify_exprt::simplify_object_size (expr);
342
+
343
+ return changed (
344
+ simplify_rec (typecast_exprt::conditional_cast (*object_size, expr.type ())));
345
+ }
346
+
347
+ simplify_exprt::resultt<>
348
+ simplify_expr_with_value_sett::simplify_is_invalid_pointer (
349
+ const unary_exprt &expr)
350
+ {
351
+ const exprt &ptr = expr.op ();
352
+
353
+ if (ptr.type ().id () != ID_pointer)
354
+ return unchanged (expr);
355
+
356
+ const ssa_exprt *ssa_symbol_expr = expr_try_dynamic_cast<ssa_exprt>(ptr);
357
+
358
+ if (!ssa_symbol_expr)
359
+ return simplify_exprt::simplify_is_invalid_pointer (expr);
360
+
361
+ ssa_exprt l1_expr{*ssa_symbol_expr};
362
+ l1_expr.remove_level_2 ();
363
+ const std::vector<exprt> value_set_elements =
364
+ value_set.get_value_set (l1_expr, ns);
365
+
366
+ bool all_valid = !value_set_elements.empty ();
367
+
368
+ for (const auto &value_set_element : value_set_elements)
369
+ {
370
+ if (
371
+ value_set_element.id () == ID_unknown ||
372
+ value_set_element.id () == ID_invalid ||
373
+ is_failed_symbol (
374
+ to_object_descriptor_expr (value_set_element).root_object ()) ||
375
+ to_object_descriptor_expr (value_set_element).offset ().id () == ID_unknown)
376
+ {
377
+ all_valid = false ;
378
+ break ;
379
+ }
380
+ }
381
+
382
+ if (all_valid)
383
+ return changed (static_cast <exprt>(false_exprt{}));
384
+ else
385
+ return simplify_exprt::simplify_is_invalid_pointer (expr);
386
+ }
0 commit comments