Beispiel #1
0
exprt dereference_rec(
  const exprt &src,
  const ssa_value_domaint &ssa_value_domain,
  const std::string &nondet_prefix,
  const namespacet &ns)
{
  if(src.id()==ID_dereference)
  {
    const exprt &pointer=dereference_rec(
      to_dereference_expr(src).pointer(),
      ssa_value_domain,
      nondet_prefix,
      ns);

    const typet &pointed_type=ns.follow(pointer.type().subtype());

    const ssa_value_domaint::valuest values=ssa_value_domain(pointer, ns);

    exprt result;
    if(values.value_set.empty())
    {
      result=pointed_object(pointer, ns);
    }
    else
    {
      auto it=values.value_set.begin();

      if(values.null || values.unknown ||
         (values.value_set.size()>1 && it->type().get_bool("#dynamic")))
      {
        std::string dyn_type_name=pointed_type.id_string();
        if(pointed_type.id()==ID_struct)
          dyn_type_name+="_"+id2string(to_struct_type(pointed_type).get_tag());
        irep_idt identifier="ssa::"+dyn_type_name+"_obj$unknown";

        result=symbol_exprt(identifier, src.type());
        result.set("#unknown_obj", true);
      }
      else
      {
        result=ssa_alias_value(src, (it++)->get_expr(), ns);
        result.set("#heap_access", result.type().get_bool("#dynamic"));
      }

      for(; it!=values.value_set.end(); ++it)
      {
        exprt guard=ssa_alias_guard(src, it->get_expr(), ns);
        exprt value=ssa_alias_value(src, it->get_expr(), ns);
        result=if_exprt(guard, value, result);
        result.set(
          "#heap_access",
          result.get_bool("#heap_access") ||
          value.type().get_bool("#dynamic"));
      }
    }

    return result;
  }
  else if(src.id()==ID_member)
  {
    member_exprt tmp=to_member_expr(src);
    tmp.struct_op()=
      dereference_rec(tmp.struct_op(), ssa_value_domain, nondet_prefix, ns);
    tmp.set("#heap_access", tmp.struct_op().get_bool("#heap_access"));

    #ifdef DEBUG
    std::cout << "dereference_rec tmp: " << from_expr(ns, "", tmp) << '\n';
    #endif

    if(tmp.struct_op().is_nil())
      return nil_exprt();

    return lift_if(tmp);
  }
  else if(src.id()==ID_address_of)
  {
    address_of_exprt tmp=to_address_of_expr(src);
    tmp.object()=
      dereference_rec(tmp.object(), ssa_value_domain, nondet_prefix, ns);
    tmp.set("#heap_access", tmp.object().get_bool("#heap_access"));

    if(tmp.object().is_nil())
      return nil_exprt();

    return lift_if(tmp);
  }
  else
  {
    exprt tmp=src;
    Forall_operands(it, tmp)
    {
      *it=dereference_rec(*it, ssa_value_domain, nondet_prefix, ns);
      if(it->get_bool("#heap_access"))
        tmp.set("#heap_access", true);
    }
    return tmp;
  }
exprt dereference_rec(
 const exprt &src,
 const ssa_value_domaint &ssa_value_domain, 
 const std::string &nondet_prefix,
 const namespacet &ns)
{
  if(src.id()==ID_dereference)
  {
    const exprt &pointer=to_dereference_expr(src).pointer();
    exprt pointer_deref=dereference(pointer, ssa_value_domain, nondet_prefix, ns);

    // We use the identifier produced by
    // local_SSAt::replace_side_effects_rec
    exprt result=symbol_exprt(nondet_prefix, src.type());

    // query the value sets
    const ssa_value_domaint::valuest values=
      ssa_value_domain(pointer, ns);

    for(ssa_value_domaint::valuest::value_sett::const_iterator
        it=values.value_set.begin();
        it!=values.value_set.end();
        it++)
    {
      exprt guard=ssa_alias_guard(src, it->get_expr(), ns);
      exprt value=ssa_alias_value(src, it->get_expr(), ns);
      result=if_exprt(guard, value, result);
    }

    return result;
  }
  else if(src.id()==ID_member)
  {
    member_exprt tmp=to_member_expr(src);
    tmp.struct_op()=dereference_rec(tmp.struct_op(), ssa_value_domain, nondet_prefix, ns);
    
    #ifdef DEBUG
    std::cout << "dereference_rec tmp: " << from_expr(ns, "", tmp) << '\n';
    #endif

    if(tmp.struct_op().is_nil())
      return nil_exprt();
      
    return lift_if(tmp);
  }
  else if(src.id()==ID_address_of)
  {
    address_of_exprt tmp=to_address_of_expr(src);
    tmp.object()=dereference_rec(tmp.object(), ssa_value_domain, nondet_prefix, ns);

    if(tmp.object().is_nil())
      return nil_exprt();
    
    return lift_if(tmp);
  }
  else
  {
    exprt tmp=src;
    Forall_operands(it, tmp)
      *it=dereference_rec(*it, ssa_value_domain, nondet_prefix, ns);
    return tmp;
  }
}