inline bool merge( const is_threaded_domaint &src, locationt from, locationt to) { bool old_reachable=reachable; if(src.reachable) reachable=true; bool old_h_s=has_spawn; if(src.has_spawn && (from->is_end_function() || from->function==to->function)) has_spawn=true; bool old_i_t=is_threaded; if(has_spawn || (src.is_threaded && !from->is_end_function())) is_threaded=true; return old_reachable!=reachable || old_i_t!=is_threaded || old_h_s!=has_spawn; }
expr2tc abstract_domain_baset::get_return_lhs(locationt to) const { // get predecessor of "to" to--; if(to->is_end_function()) return expr2tc(); // must be the function call assert(to->is_function_call()); const code_function_call2t &code = to_code_function_call2t(to->code); return code.ret; }
exprt static_analysis_baset::get_return_lhs(locationt to) { // get predecessor of "to" to--; if(to->is_end_function()) return static_cast<const exprt &>(get_nil_irep()); // must be the function call assert(to->is_function_call()); const code_function_callt &code= to_code_function_call(to->code); return code.lhs(); }
exprt flow_insensitive_abstract_domain_baset::get_return_lhs(locationt to) const { // get predecessor of "to" to--; if(to->is_end_function()) return static_cast<const exprt &>(get_nil_irep()); // must be the function call assert(to->is_function_call()); const code_function_callt &code= to_code_function_call(to_code(to->code)); return code.lhs(); }
void rd_range_domaint::transform( locationt from, locationt to, ai_baset &ai, const namespacet &ns) { reaching_definitions_analysist *rd= dynamic_cast<reaching_definitions_analysist*>(&ai); assert(rd!=0); assert(bv_container); // kill values if(from->is_dead()) transform_dead(ns, from); // kill thread-local values else if(from->is_start_thread()) transform_start_thread(ns, *rd); // do argument-to-parameter assignments else if(from->is_function_call()) transform_function_call(ns, from, to, *rd); // cleanup parameters else if(from->is_end_function()) transform_end_function(ns, from, to, *rd); // lhs assignements else if(from->is_assign()) transform_assign(ns, from, from, *rd); // initial (non-deterministic) value else if(from->is_decl()) transform_assign(ns, from, from, *rd); #if 0 // handle return values if(to->is_function_call()) { const code_function_callt &code=to_code_function_call(to->code); if(code.lhs().is_not_nil()) { rw_range_set_value_sett rw_set(ns, rd->get_value_sets()); goto_rw(to, rw_set); const bool is_must_alias=rw_set.get_w_set().size()==1; forall_rw_range_set_w_objects(it, rw_set) { const irep_idt &identifier=it->first; // ignore symex::invalid_object const symbolt *symbol_ptr; if(ns.lookup(identifier, symbol_ptr)) continue; assert(symbol_ptr!=0); const range_domaint &ranges=rw_set.get_ranges(it); if(is_must_alias && (!rd->get_is_threaded()(from) || (!symbol_ptr->is_shared() && !rd->get_is_dirty()(identifier)))) for(const auto &range : ranges) kill(identifier, range.first, range.second); } } }