@@ -311,4 +311,91 @@ SCENARIO(
311
311
}
312
312
}
313
313
}
314
+
315
+ GIVEN (" A base value-set" )
316
+ {
317
+ value_sett base_value_set;
318
+
319
+ // Create int i; int *ptr;
320
+
321
+ signedbv_typet int32_type (32 );
322
+
323
+ symbolt i;
324
+ i.name = " i" ;
325
+ i.base_name = " i" ;
326
+ i.pretty_name = " i" ;
327
+ i.type = int32_type;
328
+ i.is_static_lifetime = true ;
329
+ symbol_table.add (i);
330
+
331
+ symbolt ptr;
332
+ ptr.name = " ptr" ;
333
+ ptr.base_name = " ptr" ;
334
+ ptr.pretty_name = " ptr" ;
335
+ ptr.type = pointer_typet (int32_type, 64 );
336
+ ptr.is_static_lifetime = true ;
337
+ symbol_table.add (ptr);
338
+
339
+ // Assign ptr = &i (in the base value-set):
340
+
341
+ code_assignt assign_ptr (
342
+ ptr.symbol_expr (), address_of_exprt (i.symbol_expr ()));
343
+ base_value_set.apply_code (assign_ptr, ns);
344
+
345
+ value_set.set_base_value_set (&base_value_set);
346
+
347
+ WHEN (" Querying ptr via the base value-set" )
348
+ {
349
+ value_setst::valuest result;
350
+ base_value_set.get_value_set (ptr.symbol_expr (), result, ns);
351
+
352
+ THEN (" The answer should be { &i }" )
353
+ {
354
+ REQUIRE (result.size () == 1 );
355
+ REQUIRE (object_descriptor_matches (*result.begin (), i.symbol_expr ()));
356
+ }
357
+
358
+ WHEN (" Querying ptr via the child value-set" )
359
+ {
360
+ value_setst::valuest child_result;
361
+ value_set.get_value_set (ptr.symbol_expr (), child_result, ns);
362
+
363
+ THEN (" The answer should also be { &i }" )
364
+ {
365
+ REQUIRE (result == child_result);
366
+ }
367
+ }
368
+
369
+ WHEN (" ptr is weakly updated in the child value-set" )
370
+ {
371
+ null_pointer_exprt null_pointer (to_pointer_type (ptr.type ));
372
+
373
+ // Final 'true' parameter makes this a weak write:
374
+ value_set.assign (ptr.symbol_expr (), null_pointer, ns, false , true );
375
+
376
+ WHEN (" ptr is queried again" )
377
+ {
378
+ value_setst::valuest requery_result;
379
+ value_set.get_value_set (ptr.symbol_expr (), requery_result, ns);
380
+
381
+ THEN (" The answer should be { null, &i }" )
382
+ {
383
+ REQUIRE (requery_result.size () == 2 );
384
+
385
+ bool found_i = false , found_null = false ;
386
+ for (const exprt &result : requery_result)
387
+ {
388
+ if (object_descriptor_matches (result, i.symbol_expr ()))
389
+ found_i = true ;
390
+ else if (object_descriptor_matches (result, null_pointer))
391
+ found_null = true ;
392
+ }
393
+
394
+ REQUIRE (found_i);
395
+ REQUIRE (found_null);
396
+ }
397
+ }
398
+ }
399
+ }
400
+ }
314
401
}
0 commit comments