@@ -429,7 +429,8 @@ bool taint_algorithm_computing_summary_of_functiont::
429429 const exprt &expr,
430430 const instruction_iteratort &it,
431431 local_value_set_analysist &lvsa,
432- lvalue_numbers_sett &result)
432+ lvalue_numbers_sett &result,
433+ const bool generate_fresh_evs)
433434{
434435 TMPROF_BLOCK ();
435436
@@ -444,7 +445,7 @@ bool taint_algorithm_computing_summary_of_functiont::
444445 *numbering,
445446 raw_result,
446447 singular);
447- if (raw_result.empty ())
448+ if (generate_fresh_evs && raw_result.empty ())
448449 {
449450 external_value_set_exprt new_lhs (
450451 query_expr.type (),
@@ -472,7 +473,7 @@ bool taint_algorithm_computing_summary_of_functiont::
472473 {
473474 if (
474475 !collect_lvsa_access_paths_extended (
475- member_expr->compound (), it, lvsa, result))
476+ member_expr->compound (), it, lvsa, result, generate_fresh_evs ))
476477 {
477478 singular = false ;
478479 }
@@ -775,32 +776,21 @@ void taint_algorithm_computing_summary_of_functiont::initialise_domain(
775776 if (it->type ==ASSIGN)
776777 {
777778 const code_assignt &asgn = to_code_assign (it->code );
778- collect_lvsa_access_paths_extended (asgn.lhs (), it, lvsa, environment);
779- collect_lvsa_access_paths_extended (asgn.lhs (), it, lvsa, written);
780- if (asgn.rhs ().id ()==ID_side_effect)
779+ collect_lvsa_access_paths_extended (
780+ asgn.lhs (), it, lvsa, environment, false );
781+ collect_lvsa_access_paths_extended (
782+ asgn.lhs (), it, lvsa, written, false );
783+ if (asgn.rhs ().id () != ID_side_effect)
781784 {
782- const side_effect_exprt see=to_side_effect_expr (asgn.rhs ());
783- if (see.get_statement ()==ID_nondet)
784- {
785- const auto replace_it=
786- program->get_NONDET_retvals_replacements ().find (it);
787- if (replace_it != program->get_NONDET_retvals_replacements ().cend ())
788- {
789- collect_lvsa_access_paths_extended (
790- replace_it->second , it, lvsa, environment);
791- }
792- else
793- {
794- // This must be a NONDET assignment not relating to a stub function,
795- // for example initialising an input parameter in __CPROVER_start.
796- }
797- }
785+ collect_lvsa_access_paths_extended (
786+ asgn.rhs (), it, lvsa, environment, false );
798787 }
799- else
800- collect_lvsa_access_paths_extended (asgn.rhs (), it, lvsa, environment);
801788 }
802789 else if (it->type == ASSERT)
803- collect_lvsa_access_paths_extended (it->guard , it, lvsa, environment);
790+ {
791+ collect_lvsa_access_paths_extended (
792+ it->guard , it, lvsa, environment, false );
793+ }
804794 else if (it->type ==FUNCTION_CALL)
805795 {
806796 const code_function_callt &fn_call = to_code_function_call (it->code );
@@ -809,8 +799,6 @@ void taint_algorithm_computing_summary_of_functiont::initialise_domain(
809799 // Can't handle call by pointer, etc
810800 continue ;
811801 irep_idt callee_id = to_symbol_expr (callee_expr).get_identifier ();
812- const auto &fn_type=
813- program->get_functions ().function_map .at (callee_id).type ;
814802
815803 if (!database.contains (callee_id) || transition_rules->has_rule (callee_id))
816804 {
@@ -824,50 +812,15 @@ void taint_algorithm_computing_summary_of_functiont::initialise_domain(
824812 // In the future we could be more precise about exactly which arguments
825813 // are used in the rule.
826814 for (const auto &arg : fn_call.arguments ())
827- collect_lvsa_access_paths_extended (arg, it, lvsa, environment);
815+ {
816+ collect_lvsa_access_paths_extended (
817+ arg, it, lvsa, environment, false );
818+ }
828819 if (!database.contains (callee_id))
829820 continue ;
830821 }
831822
832823 const std::shared_ptr<taint_summaryt> summary = database.at (callee_id);
833- for (const std::pair<taint_lvalue_numbert, taint_variablet>& input
834- : summary->input )
835- {
836- if (symbol_utilst (program->get_namespace ())
837- .is_parameter (numbering->at (input.first )))
838- {
839- // Collect access paths for the corresponding actual argument:
840- parameter_matches_id match (
841- to_symbol_expr (numbering->at (input.first ))
842- .get_identifier ());
843- auto findit=std::find_if (
844- fn_type.parameters ().begin (),
845- fn_type.parameters ().end (),
846- match);
847- assert (findit!=fn_type.parameters ().end () &&
848- " Parameter symbol doesn't match?" );
849- const auto paramidx=
850- std::distance (fn_type.parameters ().begin (), findit);
851- collect_lvsa_access_paths_extended (
852- fn_call.arguments ()[paramidx], it, lvsa, environment);
853- }
854- else if (!symbol_utilst (program->get_namespace ()).is_parameter (
855- numbering->at (input.first )) &&
856- !symbol_utilst (program->get_namespace ())
857- .is_return_value_auxiliary (numbering->at (input.first )))
858- {
859- environment.insert (input.first );
860- }
861- if (numbering->at (input.first ).id ()==ID_external_value_set)
862- {
863- const auto & evse=to_external_value_set (
864- numbering->at (input.first ));
865- if (evse.access_path_entries ().size ()==1 )
866- numbering_map
867- ->get_object_numbers_by_field ()[as_string (function_id)]
868- .insert ({ evse.access_path_entries ().back ().label (), {} });
869- }
870- }
871824 for (const std::pair<taint_lvalue_numbert, taint_sett> &lvalue_taint:
872825 summary->output )
873826 written.insert (lvalue_taint.first );
@@ -1599,6 +1552,16 @@ void taint_algorithm_computing_summary_of_functiont::
15991552 }
16001553 summary.input = std::move (pruned_input);
16011554
1555+ #ifndef NDEBUG // Ignore the check below in a non-debug build.
1556+ {
1557+ taint_variable_sett input_vars;
1558+ for (const auto &input_var : summary.input )
1559+ input_vars.insert (input_var.second );
1560+ for (const auto &end_var : end_values_taint.get_vars ())
1561+ INVARIANT (input_vars.count (end_var), " Out var must be present in input." );
1562+ }
1563+ #endif
1564+
16021565 const goto_functiont &func_ref =
16031566 program->get_functions ().function_map .at (fn_id);
16041567 const code_typet &fn_type = to_code_type (func_ref.type );
0 commit comments