示例#1
0
void local_SSAt::replace_side_effects_rec(
  exprt &expr, locationt loc, unsigned &counter) const
{
  Forall_operands(it, expr)
    replace_side_effects_rec(*it, loc, counter);

  if(expr.id()==ID_side_effect)
  {
    const side_effect_exprt &side_effect_expr=
      to_side_effect_expr(expr);
    const irep_idt statement=side_effect_expr.get_statement();

    if(statement==ID_nondet)
    {
      // turn into nondet_symbol
      exprt nondet_symbol(ID_nondet_symbol, expr.type());
      counter++;
      const irep_idt identifier=
        "ssa::nondet"+
        i2string(loc->location_number)+
        "."+i2string(counter)+suffix;
      nondet_symbol.set(ID_identifier, identifier);
      
      expr.swap(nondet_symbol);
    }
    else if(statement==ID_malloc)
    {
      counter++;
      std::string tmp_suffix=
        i2string(loc->location_number)+
        "."+i2string(counter)+suffix;
      expr=malloc_ssa(side_effect_expr, tmp_suffix, ns);
    }
    else
      throw "unexpected side effect: "+id2string(statement);
  }
}
示例#2
0
bool is_nondet(goto_programt::const_targett target,
    goto_programt::const_targett end)
{
  const goto_programt::instructiont &instr=*target;
  switch (instr.type)
  {
  case goto_program_instruction_typet::DECL:
  {
    goto_programt::const_targett next=std::next(target);
    if (next == end) return true;
    if (goto_program_instruction_typet::FUNCTION_CALL == next->type)
    {
      if (to_code_function_call(next->code).lhs().is_not_nil()) return false;
      else ++next;
    }
    const goto_programt::instructiont next_instr=*next;
    if (goto_program_instruction_typet::ASSIGN != next_instr.type) return true;
    const irep_idt id(get_affected_variable(instr));
    if (id != get_affected_variable(next_instr)) return true;
    return contains(to_code_assign(next_instr.code).rhs(), id);
  }
  case goto_program_instruction_typet::ASSIGN:
  {
    const exprt &rhs=to_code_assign(instr.code).rhs();
    if (ID_side_effect != rhs.id()) return false;
    return ID_nondet == to_side_effect_expr(rhs).get_statement();
  }
  case goto_program_instruction_typet::FUNCTION_CALL:
  {
    const code_function_callt &call=to_code_function_call(instr.code);
    if (call.lhs().is_not_nil()) return false;
  }
  default:
    return false;
  }
}
exprt path_symex_statet::instantiate_rec(
  const exprt &src,
  bool propagate)
{
  #ifdef DEBUG
  std::cout << "instantiate_rec: "
            << from_expr(var_map.ns, "", src) << '\n';
  #endif

  // check whether this is a symbol(.member|[index])*

  if(is_symbol_member_index(src))
  {
    exprt tmp_symbol_member_index=
      read_symbol_member_index(src, propagate);

    assert(tmp_symbol_member_index.is_not_nil());
    return tmp_symbol_member_index; // yes!
  }

  if(src.id()==ID_address_of)
  {
    assert(src.operands().size()==1);
    exprt tmp=src;
    tmp.op0()=instantiate_rec_address(tmp.op0(), propagate);
    return tmp;
  }
  else if(src.id()==ID_side_effect)
  {
    // could be done separately
    const irep_idt &statement=to_side_effect_expr(src).get_statement();

    if(statement==ID_nondet)
    {
      irep_idt id="symex::nondet"+std::to_string(var_map.nondet_count);
      var_map.nondet_count++;
      return symbol_exprt(id, src.type());
    }
    else
      throw "instantiate_rec: unexpected side effect "+id2string(statement);
  }
  else if(src.id()==ID_dereference)
  {
    // dereferencet has run already, so we should only be left with
    // integer addresses. Will transform into __CPROVER_memory[]
    // eventually.
  }
  else if(src.id()==ID_member)
  {
    const typet &compound_type=
      var_map.ns.follow(to_member_expr(src).struct_op().type());

    if(compound_type.id()==ID_struct)
    {
      // do nothing
    }
    else if(compound_type.id()==ID_union)
    {
      // should already have been rewritten to byte_extract
      throw "unexpected union member";
    }
    else
    {
      throw "member expects struct or union type"+src.pretty();
    }
  }
  else if(src.id()==ID_byte_extract_little_endian ||
          src.id()==ID_byte_extract_big_endian)
  {
  }
  else if(src.id()==ID_symbol)
  {
    // must be SSA already, or code
    assert(src.type().id()==ID_code ||
           src.get_bool(ID_C_SSA_symbol));
  }

  if(!src.has_operands())
    return src;

  exprt src2=src;

  // recursive calls on structure of 'src'
  Forall_operands(it, src2)
  {
    exprt tmp_op=instantiate_rec(*it, propagate);
    *it=tmp_op;
  }
示例#4
0
exprt path_symex_statet::instantiate_rec(
  const exprt &src,
  bool propagate)
{
  #ifdef DEBUG
  std::cout << "instantiate_rec: "
            << from_expr(var_map.ns, "", src) << std::endl;
  #endif

  const typet &src_type=var_map.ns.follow(src.type());

  if(src_type.id()==ID_struct) // src is a struct
  {
    const struct_typet &struct_type=to_struct_type(src_type);
    const struct_typet::componentst &components=struct_type.components();

    struct_exprt result(src.type());
    result.operands().resize(components.size());

    // split it up into components
    for(unsigned i=0; i<components.size(); i++)
    {
      const typet &subtype=components[i].type();
      const irep_idt &component_name=components[i].get_name();

      exprt new_src;
      if(src.id()==ID_struct) // struct constructor?
      {
        assert(src.operands().size()==components.size());
        new_src=src.operands()[i];
      }
      else
        new_src=member_exprt(src, component_name, subtype);

      // recursive call
      result.operands()[i]=instantiate_rec(new_src, propagate);
    }

    return result; // done
  }
  else if(src_type.id()==ID_array) // src is an array
  {
    const array_typet &array_type=to_array_type(src_type);
    const typet &subtype=array_type.subtype();

    if(array_type.size().is_constant())
    {
      mp_integer size;
      if(to_integer(array_type.size(), size))
        throw "failed to convert array size";

      unsigned long long size_int=integer2unsigned(size);

      array_exprt result(array_type);
      result.operands().resize(size_int);

      // split it up into elements
      for(unsigned long long i=0; i<size_int; ++i)
      {
        exprt index=from_integer(i, array_type.size().type());
        exprt new_src=index_exprt(src, index, subtype);

        // array constructor?
        if(src.id()==ID_array)
          new_src=simplify_expr(new_src, var_map.ns);

        // recursive call
        result.operands()[i]=instantiate_rec(new_src, propagate);
      }

      return result; // done
    }
    else
    {
      // TODO
    }
  }
  else if(src_type.id()==ID_vector) // src is a vector
  {
    const vector_typet &vector_type=to_vector_type(src_type);
    const typet &subtype=vector_type.subtype();

    if(!vector_type.size().is_constant())
      throw "vector with non-constant size";

    mp_integer size;
    if(to_integer(vector_type.size(), size))
      throw "failed to convert vector size";

    unsigned long long int size_int=integer2unsigned(size);

    vector_exprt result(vector_type);
    exprt::operandst &operands=result.operands();
    operands.resize(size_int);

    // split it up into elements
    for(unsigned long long i=0; i<size_int; ++i)
    {
      exprt index=from_integer(i, vector_type.size().type());
      exprt new_src=index_exprt(src, index, subtype);

      // vector constructor?
      if(src.id()==ID_vector)
        new_src=simplify_expr(new_src, var_map.ns);

      // recursive call
      operands[i]=instantiate_rec(new_src, propagate);
    }

    return result; // done
  }

  // check whether this is a symbol(.member|[index])*

  {
    exprt tmp_symbol_member_index=
      read_symbol_member_index(src, propagate);

    if(tmp_symbol_member_index.is_not_nil())
      return tmp_symbol_member_index; // yes!
  }

  if(src.id()==ID_address_of)
  {
    assert(src.operands().size()==1);
    exprt tmp=src;
    tmp.op0()=instantiate_rec_address(tmp.op0(), propagate);
    return tmp;
  }
  else if(src.id()==ID_sideeffect)
  {
    // could be done separately
    const irep_idt &statement=to_side_effect_expr(src).get_statement();

    if(statement==ID_nondet)
    {
      irep_idt id="symex::nondet"+i2string(var_map.nondet_count);
      var_map.nondet_count++;
      return symbol_exprt(id, src.type());
    }
    else
      throw "instantiate_rec: unexpected side effect "+id2string(statement);
  }
  else if(src.id()==ID_dereference)
  {
    // dereferencet has run already, so we should only be left with
    // integer addresses. Will transform into __CPROVER_memory[]
    // eventually.
  }
  else if(src.id()==ID_index)
  {
    // avoids indefinite recursion above
    return src;
  }
  else if(src.id()==ID_member)
  {
    const typet &compound_type=
      var_map.ns.follow(to_member_expr(src).struct_op().type());

    if(compound_type.id()==ID_struct)
    {
      // avoids indefinite recursion above
      return src;
    }
    else if(compound_type.id()==ID_union)
    {
      member_exprt tmp=to_member_expr(src);
      tmp.struct_op()=instantiate_rec(tmp.struct_op(), propagate);
      return tmp;
    }
    else
    {
      throw "member expects struct or union type"+src.pretty();
    }
  }

  if(!src.has_operands())
    return src;

  exprt src2=src;

  // recursive calls on structure of 'src'
  Forall_operands(it, src2)
  {
    exprt tmp_op=instantiate_rec(*it, propagate);
    *it=tmp_op;
  }