@@ -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
@@ -188,11 +189,23 @@ simplify_expr_with_value_sett::simplify_inequality_pointer_object(
188
189
objects.clear ();
189
190
break ;
190
191
}
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
+ }
194
202
}
195
203
}
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
+ }
196
209
return objects;
197
210
};
198
211
@@ -281,3 +294,99 @@ simplify_expr_with_value_sett::simplify_pointer_offset(
281
294
return changed (
282
295
simplify_rec (typecast_exprt::conditional_cast (*offset, expr.type ())));
283
296
}
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