@@ -12,6 +12,7 @@ Author: Diffblue Ltd.
12
12
#include < analyses/variable-sensitivity/variable_sensitivity_domain.h>
13
13
#include < ansi-c/expr2c.h>
14
14
15
+ #include < analyses/variable-sensitivity/variable_sensitivity_object_factory.h>
15
16
#include < sstream>
16
17
#include < string>
17
18
#include < util/arith_tools.h>
@@ -57,6 +58,7 @@ class ContainsAllOf
57
58
{
58
59
oss << " , " ;
59
60
}
61
+ first = false ;
60
62
oss << expr2c (value, ns);
61
63
}
62
64
oss << " }" ;
@@ -359,3 +361,119 @@ TEST_CASE(
359
361
360
362
REQUIRE (value_set.to_constant () == value);
361
363
}
364
+
365
+ static abstract_environmentt get_value_set_abstract_environment ()
366
+ {
367
+ vsd_configt config;
368
+ config.advanced_sensitivities .new_value_set = true ;
369
+ config.context_tracking .data_dependency_context = false ;
370
+ config.context_tracking .last_write_context = false ;
371
+ variable_sensitivity_object_factoryt::instance ().set_options (config);
372
+ auto environment = abstract_environmentt{};
373
+ environment.make_top ();
374
+ return environment;
375
+ }
376
+
377
+ TEST_CASE (" Eval on an constant gives us that constant" , VALUE_SET_TEST_TAGS)
378
+ {
379
+ const auto environment = get_value_set_abstract_environment ();
380
+ namespacet ns{symbol_tablet{}};
381
+ const auto zero = from_integer (0 , signedbv_typet{32 });
382
+ const auto eval_result = environment.eval (zero, ns);
383
+ REQUIRE (eval_result != nullptr );
384
+ REQUIRE (!eval_result->is_top ());
385
+ REQUIRE (!eval_result->is_bottom ());
386
+ const auto eval_result_as_value_set =
387
+ std::dynamic_pointer_cast<const value_set_abstract_valuet>(
388
+ eval_result->unwrap_context ());
389
+ REQUIRE (eval_result_as_value_set != nullptr );
390
+ REQUIRE (eval_result_as_value_set->get_values ().size () == 1 );
391
+ REQUIRE_THAT (eval_result_as_value_set->get_values (), ContainsAllOf{zero});
392
+ }
393
+
394
+ TEST_CASE (
395
+ " Eval on a plus expression with constant operands gives us the result of "
396
+ " that plus" ,
397
+ VALUE_SET_TEST_TAGS)
398
+ {
399
+ const auto environment = get_value_set_abstract_environment ();
400
+ namespacet ns{symbol_tablet{}};
401
+ const auto s32_type = signedbv_typet{32 };
402
+ const auto three = from_integer (3 , s32_type);
403
+ const auto five = from_integer (5 , s32_type);
404
+ const auto three_plus_five = plus_exprt{three, five};
405
+
406
+ auto eval_result = environment.eval (three_plus_five, ns);
407
+ REQUIRE (eval_result != nullptr );
408
+ REQUIRE (!eval_result->is_top ());
409
+ REQUIRE (!eval_result->is_bottom ());
410
+
411
+ const auto eval_result_as_value_set =
412
+ std::dynamic_pointer_cast<const value_set_abstract_valuet>(
413
+ eval_result->unwrap_context ());
414
+ REQUIRE (eval_result_as_value_set != nullptr );
415
+ const auto eight = from_integer (8 , s32_type);
416
+ REQUIRE (eval_result_as_value_set->get_values ().size () == 1 );
417
+ REQUIRE_THAT (eval_result_as_value_set->get_values (), ContainsAllOf{eight});
418
+ }
419
+
420
+ TEST_CASE (
421
+ " Eval on a multiply expression on symbols gives us the results of that "
422
+ " multiplication" ,
423
+ VALUE_SET_TEST_TAGS)
424
+ {
425
+ auto environment = get_value_set_abstract_environment ();
426
+ symbol_tablet symbol_table;
427
+
428
+ const auto s32_type = signedbv_typet{32 };
429
+
430
+ symbolt a_symbol{};
431
+ a_symbol.name = a_symbol.pretty_name = a_symbol.base_name = " a" ;
432
+ a_symbol.is_lvalue = true ;
433
+ a_symbol.type = s32_type;
434
+ symbol_table.add (a_symbol);
435
+
436
+ symbolt b_symbol{};
437
+ b_symbol.name = b_symbol.pretty_name = b_symbol.base_name = " b" ;
438
+ b_symbol.is_lvalue = true ;
439
+ b_symbol.type = s32_type;
440
+ symbol_table.add (b_symbol);
441
+ symbol_table.add (b_symbol);
442
+
443
+ const namespacet ns{symbol_table};
444
+
445
+ const auto three = from_integer (3 , s32_type);
446
+ const auto four = from_integer (4 , s32_type);
447
+ const auto five = from_integer (5 , s32_type);
448
+ const auto six = from_integer (6 , s32_type);
449
+
450
+ const auto three_or_five = std::make_shared<const value_set_abstract_valuet>(
451
+ s32_type, value_set_abstract_valuet::valuest{three, five});
452
+ environment.assign (a_symbol.symbol_expr (), three_or_five, ns);
453
+
454
+ const auto four_or_six = std::make_shared<const value_set_abstract_valuet>(
455
+ s32_type, value_set_abstract_valuet::valuest{four, six});
456
+ environment.assign (b_symbol.symbol_expr (), four_or_six, ns);
457
+
458
+ const auto a_times_b =
459
+ mult_exprt{a_symbol.symbol_expr (), b_symbol.symbol_expr ()};
460
+
461
+ const auto eval_result = environment.eval (a_times_b, ns);
462
+ REQUIRE (eval_result != nullptr );
463
+ REQUIRE (!eval_result->is_top ());
464
+ REQUIRE (!eval_result->is_bottom ());
465
+
466
+ const auto eval_result_as_value_set =
467
+ std::dynamic_pointer_cast<const value_set_abstract_valuet>(
468
+ eval_result->unwrap_context ());
469
+ REQUIRE (eval_result_as_value_set != nullptr );
470
+ REQUIRE (eval_result_as_value_set->get_values ().size () == 4 );
471
+
472
+ const auto twelve = from_integer (12 , s32_type);
473
+ const auto eighteen = from_integer (18 , s32_type);
474
+ const auto twenty = from_integer (20 , s32_type);
475
+ const auto twentyfour = from_integer (30 , s32_type);
476
+ REQUIRE_THAT (
477
+ eval_result_as_value_set->get_values (),
478
+ ContainsAllOf (twelve, eighteen, twenty, twentyfour));
479
+ }
0 commit comments