Пример #1
0
void rd_range_domaint::transform(
  const namespacet &ns,
  locationt from,
  locationt to)
{
  if(from->is_dead())
  {
    const symbol_exprt &symbol=
      to_symbol_expr(to_code_dead(from->code).symbol());
    values.erase(symbol.get_identifier());
    return;
  }
  else if(!from->is_assign())
    return;

  const exprt &lhs=to_code_assign(from->code).lhs();

  if(lhs.id()==ID_complex_real ||
          lhs.id()==ID_complex_imag)
  {
    assert(lhs.type().id()==ID_complex);
    mp_integer offset=compute_pointer_offset(ns, lhs.op0());
    mp_integer sub_size=pointer_offset_size(ns, lhs.type().subtype());

    assign(
      ns,
      from,
      lhs.op0(),
      offset+((offset==-1 || lhs.id()==ID_complex_real) ? 0 : sub_size),
      sub_size);
  }
  else
  {
    mp_integer size=pointer_offset_size(ns, lhs.type());

    assign(ns, from, lhs, size);
  }
}
Пример #2
0
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);
      }
    }
  }
Пример #3
0
void ssa_domaint::transform(
  locationt from,
  locationt to,
  ai_baset &ai,
  const namespacet &ns)
{
  if(from->is_assign() || from->is_decl() || from->is_function_call())
  {
    const auto &assignments=static_cast<ssa_ait &>(ai).assignments;
    const std::set<ssa_objectt> &assigns=assignments.get(from);

    for(std::set<ssa_objectt>::const_iterator
        o_it=assigns.begin();
        o_it!=assigns.end();
        o_it++)
    {
      if(o_it->get_expr().get_bool("#is_rhs_assign") &&
         is_pointed(o_it->get_root_object()))
      {
        // the second part excluded cases
        // when a result of malloc is at the right-handed side
        const auto object_ai_it=
          static_cast<ssa_ait &>(ai)[from].def_map.find(o_it->get_identifier());
        if(object_ai_it!=static_cast<ssa_ait &>(ai)[from].def_map.end() &&
           object_ai_it->second.def.is_assignment())
        {
          const exprt pointer=
            get_pointer(
              o_it->get_root_object(),
              pointed_level(o_it->get_root_object())-1);
          const auto def_pointer=
            static_cast<ssa_ait &>(ai)[from]
              .def_map.find(
                ssa_objectt(pointer, ns).get_identifier())->second.def;
          if(!def_pointer.is_assignment() ||
             def_pointer.loc->location_number<
               object_ai_it->second.def.loc->location_number)
          {
            continue;
          }
        }
      }
      irep_idt identifier=o_it->get_identifier();

      def_entryt &def_entry=def_map[identifier];
      def_entry.def.loc=from;
      def_entry.source=from;
      auto guard_it=assignments.alloc_guards_map.find({from, *o_it});
      if(guard_it!=assignments.alloc_guards_map.end())
      {
        def_entry.def.kind=deft::ALLOCATION;
        def_entry.def.guard=guard_it->second;
      }
      else
        def_entry.def.kind=deft::ASSIGNMENT;
    }
  }
  else if(from->is_dead())
  {
    const code_deadt &code_dead=to_code_dead(from->code);
    const irep_idt &id=code_dead.get_identifier();
    def_map.erase(id);
  }

  // update source in all defs
  for(def_mapt::iterator
      d_it=def_map.begin(); d_it!=def_map.end(); d_it++)
    d_it->second.source=from;
}