@@ -12,6 +12,7 @@ Author: Diffblue Ltd.
1212#include < analyses/variable-sensitivity/variable_sensitivity_domain.h>
1313#include < ansi-c/expr2c.h>
1414
15+ #include < analyses/variable-sensitivity/variable_sensitivity_object_factory.h>
1516#include < sstream>
1617#include < string>
1718#include < util/arith_tools.h>
@@ -57,6 +58,7 @@ class ContainsAllOf
5758 {
5859 oss << " , " ;
5960 }
61+ first = false ;
6062 oss << expr2c (value, ns);
6163 }
6264 oss << " }" ;
@@ -359,3 +361,119 @@ TEST_CASE(
359361
360362 REQUIRE (value_set.to_constant () == value);
361363}
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