Beispiel #1
0
void modelchecker_smvt::instantiate_expression(exprt &expr)
{
  Forall_operands(it, expr)
    instantiate_expression(*it);

  if(expr.id()==ID_predicate_symbol)
  {
    unsigned p=atoi(expr.get(ID_identifier).c_str());
    expr.id(ID_symbol);
    expr.set(ID_identifier, variable_names[p]);
  }
  else if(expr.id()==ID_predicate_next_symbol)
  {
    unsigned p=atoi(expr.get(ID_identifier).c_str());
    expr.id(ID_next_symbol);
    expr.set(ID_identifier, variable_names[p]);
  }
  else if(expr.id()==ID_nondet_symbol)
  {
    nondet_symbolst::const_iterator it=
      nondet_symbols.find(
        static_cast<const exprt &>(expr.find("expression")));

    if(it==nondet_symbols.end())
      throw "failed to find nondet_symbol";

    typet type=expr.type();
    expr=exprt(ID_symbol, type);
    expr.set(ID_identifier, it->second);
  }
}
Beispiel #2
0
bool base_type_eqt::base_type_eq_rec(
  const exprt &expr1,
  const exprt &expr2)
{
  if(expr1.id()!=expr2.id())
    return false;

  if(!base_type_eq(expr1.type(), expr2.type()))
    return false;

  const exprt::operandst &expr1_op=expr1.operands();
  const exprt::operandst &expr2_op=expr2.operands();
  if(expr1_op.size()!=expr2_op.size())
    return false;

  for(exprt::operandst::const_iterator
      it1=expr1_op.begin(), it2=expr2_op.begin();
      it1!=expr1_op.end() && it2!=expr2_op.end();
      ++it1, ++it2)
    if(!base_type_eq(*it1, *it2))
      return false;

  if(expr1.id()==ID_constant)
    if(expr1.get(ID_value)!=expr2.get(ID_value))
      return false;

  return true;
}
Beispiel #3
0
std::string expr2javat::convert(
  const exprt &src,
  unsigned &precedence)
{
  if(src.id()=="java-this")
    return convert_java_this(src, precedence=15);
  if(src.id()=="java_instanceof")
    return convert_java_instanceof(src, precedence=15);
  else if(src.id()==ID_side_effect &&
          (src.get(ID_statement)==ID_java_new ||
           src.get(ID_statement)==ID_java_new_array))
    return convert_java_new(src, precedence=15);
  else if(src.id()==ID_side_effect &&
          src.get(ID_statement)==ID_throw)
    return convert_function(src, "throw", precedence=16);
  else if(src.is_constant() && to_constant_expr(src).get_value()==ID_nullptr)
    return "nullptr";
  else if(src.id()==ID_unassigned)
    return "?";
  else if(src.id()=="pod_constructor")
    return "pod_constructor";
  else if(src.id()==ID_virtual_function)
    return convert_function(src, "VIRTUAL_FUNCTION", precedence=16);
  else if(src.id()==ID_java_string_literal)
    return '"'+id2string(src.get(ID_value))+'"'; // Todo: add escaping as needed
  else
    return expr2ct::convert(src, precedence);
}
void remove_virtual_functionst::get_functions(
  const exprt &function,
  functionst &functions)
{
  const irep_idt class_id=function.get(ID_C_class);
  const irep_idt component_name=function.get(ID_component_name);
  assert(!class_id.empty());
  functiont root_function;

  // Start from current class, go to parents until something
  // is found.
  irep_idt c=class_id;
  while(!c.empty())
  {
    exprt method=get_method(c, component_name);
    if(method.is_not_nil())
    {
      root_function.class_id=c;
      root_function.symbol_expr=to_symbol_expr(method);
      root_function.symbol_expr.set(ID_C_class, c);
      break; // abort
    }

    const class_hierarchyt::idst &parents=
      class_hierarchy.class_map[c].parents;

    if(parents.empty())
      break;
    c=parents.front();
  }

  if(root_function.class_id.empty())
  {
    // No definition here; this is an abstract function.
    root_function.class_id=class_id;
  }

  // iterate over all children, transitively
  std::set<irep_idt> visited;
  get_child_functions_rec(
    class_id,
    root_function.symbol_expr,
    component_name,
    functions,
    visited);

  if(root_function.symbol_expr!=symbol_exprt())
    functions.push_back(root_function);
}
void remove_virtual_functionst::get_functions(
  const exprt &function,
  functionst &functions)
{
  const irep_idt class_id=function.get(ID_C_class);
  const irep_idt component_name=function.get(ID_component_name);
  assert(!class_id.empty());

  // iterate over all children, transitively
  std::vector<irep_idt> children=
    class_hierarchy.get_children_trans(class_id);

  for(const auto & child : children)
  {
    exprt method=get_method(child, component_name);
    if(method.is_not_nil())
    {
      functiont function;
      function.class_id=child;
      function.symbol_expr=to_symbol_expr(method);
      function.symbol_expr.set(ID_C_class, child);
      functions.push_back(function);
    }
  }

  // Start from current class, go to parents until something
  // is found.
  irep_idt c=class_id;
  while(!c.empty())
  {
    exprt method=get_method(c, component_name);
    if(method.is_not_nil())
    {
      functiont function;
      function.class_id=c;
      function.symbol_expr=to_symbol_expr(method);
      function.symbol_expr.set(ID_C_class, c);
      functions.push_back(function);
      break; // abort
    }

    const class_hierarchyt::idst &parents=
      class_hierarchy.class_map[c].parents;

    if(parents.empty()) break;
    c=parents.front();
  }
}
Beispiel #6
0
/// automated variable renaming
/// \par parameters: expression, old name, new name
/// \return modifies the expression returns false iff something was renamed
bool rename(exprt &expr, const irep_idt &old_name,
            const irep_idt &new_name)
{
  bool result=true;

  if(expr.id()==ID_symbol)
  {
    if(expr.get(ID_identifier)==old_name)
    {
      expr.set(ID_identifier, new_name);
      result=false;
    }
  }
  else
  {
    if(expr.id()==ID_address_of)
    {
      // TODO
    }
    else
      Forall_operands(it, expr)
        if(!rename(*it, old_name, new_name))
          result=false;
  }

  return result;
}
void goto_convertt::do_printf(
  const exprt &lhs,
  const exprt &function,
  const exprt::operandst &arguments,
  goto_programt &dest)
{
  const irep_idt &f_id=function.get(ID_identifier);

  if(f_id==CPROVER_PREFIX "printf" ||
     f_id=="printf")
  {
    typet return_type=static_cast<const typet &>(function.type().find(ID_return_type));
    side_effect_exprt printf_code(ID_printf, return_type);

    printf_code.operands()=arguments;
    printf_code.add_source_location()=function.source_location();

    if(lhs.is_not_nil())
    {
      code_assignt assignment(lhs, printf_code);
      assignment.add_source_location()=function.source_location();
      copy(assignment, ASSIGN, dest);
    }
    else
    {
      printf_code.id(ID_code);
      printf_code.type()=typet(ID_code);
      copy(to_code(printf_code), OTHER, dest);
    }
  }
  else
    assert(false);
}
Beispiel #8
0
void ansi_c_convertt::convert_expr(exprt &expr)
{
  if(expr.id()==ID_sideeffect)
  {
    const irep_idt &statement=expr.get(ID_statement);

    if(statement==ID_statement_expression)
    {
      assert(expr.operands().size()==1);
      convert_code(to_code(expr.op0()));
      return;
      // done
    }
  }

  Forall_operands(it, expr)
    convert_expr(*it);

  if(expr.id()==ID_symbol)
  {
    expr.remove(ID_C_id_class);
    expr.remove(ID_C_base_name);
  }
  else if(expr.id()==ID_sizeof)
  {
    if(expr.operands().size()==0)
    {
      typet &type=static_cast<typet &>(expr.add(ID_type_arg));
      convert_type(type);
    }
  }
  else if(expr.id()==ID_designated_initializer)
  {
    exprt &designator=static_cast<exprt &>(expr.add(ID_designator));
    convert_expr(designator);
  }
  else if(expr.id()==ID_alignof)
  {
    if(expr.operands().size()==0)
    {
      typet &type=static_cast<typet &>(expr.add(ID_type_arg));
      convert_type(type);
    }
  }
  else if(expr.id()==ID_gcc_builtin_va_arg)
  {
    convert_type(expr.type());
  }
  else if(expr.id()==ID_generic_selection)
  {
    assert(expr.operands().size()==1);

    irept::subt &generic_associations=
      expr.add(ID_generic_associations).get_sub();

    Forall_irep(it, generic_associations)
    {
      convert_expr(static_cast<exprt &>(it->add(ID_value)));
      convert_type(static_cast<typet &>(it->add(ID_type_arg)));
    }
/// does not replace object in address_of expressions
bool replace_symbol_extt::replace(exprt &dest) const
{
  bool result=true;

  // first look at type

  if(have_to_replace(dest.type()))
    if(!replace_symbolt::replace(dest.type()))
      result=false;

  // now do expression itself

  if(!have_to_replace(dest))
    return result;

  // do not replace object in address_of expressions
  if(dest.id()==ID_address_of)
  {
    const exprt &object = to_address_of_expr(dest).object();
    if(object.id()==ID_symbol)
    {
      expr_mapt::const_iterator it=
        expr_map.find(object.get(ID_identifier));

      if(it!=expr_map.end())
        return false;
    }
  }
  else if(dest.id()==ID_symbol)
  {
    expr_mapt::const_iterator it=
      expr_map.find(dest.get(ID_identifier));

    if(it!=expr_map.end())
    {
      dest=it->second;
      return false;
    }
  }

  Forall_operands(it, dest)
    if(!replace(*it))
      result=false;

  const irept &c_sizeof_type=dest.find(ID_C_c_sizeof_type);

  if(c_sizeof_type.is_not_nil() &&
     !replace_symbolt::replace(
       static_cast<typet&>(dest.add(ID_C_c_sizeof_type))))
    result=false;

  const irept &va_arg_type=dest.find(ID_C_va_arg_type);

  if(va_arg_type.is_not_nil() &&
     !replace_symbolt::replace(static_cast<typet&>(dest.add(ID_C_va_arg_type))))
    result=false;

  return result;
}
Beispiel #10
0
void boolbvt::convert_with_struct(
  const struct_typet &type,
  const exprt &op1,
  const exprt &op2,
  const bvt &prev_bv,
  bvt &next_bv)
{
  next_bv=prev_bv;

  const bvt &op2_bv=convert_bv(op2);

  const irep_idt &component_name=op1.get(ID_component_name);
  const struct_typet::componentst &components=
    type.components();

  std::size_t offset=0;

  for(struct_typet::componentst::const_iterator
      it=components.begin();
      it!=components.end();
      it++)
  {

    const typet &subtype=it->type();

    std::size_t sub_width=boolbv_width(subtype);

    if(it->get_name()==component_name)
    {
      if(!base_type_eq(subtype, op2.type(), ns))
      {
        error().source_location=type.source_location();
        error() << "with/struct: component `" << component_name
                << "' type does not match: "
                << subtype.pretty() << " vs. "
                << op2.type().pretty() << eom;
        throw 0;
      }

      if(sub_width!=op2_bv.size())
      {
        error().source_location=type.source_location();
        error() << "convert_with_struct: unexpected operand op2 width"
                << eom;
        throw 0;
      }

      for(std::size_t i=0; i<sub_width; i++)
        next_bv[offset+i]=op2_bv[i];

      break; // done
    }

    offset+=sub_width;
  }
}
Beispiel #11
0
void preconditiont::compute_rec(exprt &dest)
{
  if(dest.id()==ID_address_of)
  {
    // only do index!
    assert(dest.operands().size()==1);
    compute_address_of(dest.op0());
  }
  else if(dest.id()==ID_symbol)
  {
    if(dest.get(ID_identifier)==
       s.get_original_name(SSA_step.ssa_lhs.get_identifier()))
    {
      dest=SSA_step.ssa_rhs;
      s.get_original_name(dest);
    }
  }
  else if(dest.id()==ID_dereference)
  {
    assert(dest.operands().size()==1);

    const irep_idt &lhs_identifier=
      s.get_original_name(SSA_step.ssa_lhs.get_identifier());
  
    // aliasing may happen here

    value_setst::valuest expr_set;
    value_sets.get_values(target, dest.op0(), expr_set);
    hash_set_cont<irep_idt, irep_id_hash> symbols;

    for(value_setst::valuest::const_iterator
        it=expr_set.begin();
        it!=expr_set.end();
        it++)
      find_symbols(*it, symbols);
    
    if(symbols.find(lhs_identifier)!=symbols.end())
    {
      // may alias!
      exprt tmp;
      tmp.swap(dest.op0());
      dereference(target, tmp, ns, value_sets);
      dest.swap(tmp);
      compute_rec(dest);
    }
    else
    {
      // nah, ok
      compute_rec(dest.op0());
    }
  }
  else
    Forall_operands(it, dest)
      compute_rec(*it);
}
Beispiel #12
0
std::string inv_object_storet::build_string(const exprt &expr) const
{
  // we ignore some casts
  if(expr.id()==ID_typecast)
  {
    assert(expr.operands().size()==1);

    if(expr.type().id()==ID_signedbv ||
       expr.type().id()==ID_unsignedbv)
    {
      if(expr.op0().type().id()==ID_signedbv ||
         expr.op0().type().id()==ID_unsignedbv)
      {
        if(to_bitvector_type(expr.type()).get_width()>=
           to_bitvector_type(expr.op0().type()).get_width())
          return build_string(expr.op0());
      }
      else if(expr.op0().type().id()==ID_bool)
      {
        return build_string(expr.op0());
      }
    }
  }

  // we always track constants, but make sure they are uniquely
  // represented
  if(expr.is_constant())
  {
    // NULL?
    if(expr.type().id()==ID_pointer)
      if(expr.get(ID_value)==ID_NULL)
        return "0";

    mp_integer i;

    if(!to_integer(expr, i))
      return integer2string(i);
  }

  // we also like "address_of" and "reference_to"
  // if the object is constant
  if(is_constant_address(expr))
    return from_expr(ns, "", expr);

  if(expr.id()==ID_member)
  {
    assert(expr.operands().size()==1);
    return build_string(expr.op0())+"."+expr.get_string(ID_component_name);
  }

  if(expr.id()==ID_symbol)
    return expr.get_string(ID_identifier);

  return "";
}
mp_integer compute_pointer_offset(
  const namespacet &ns,
  const exprt &expr)
{
  if(expr.id()==ID_symbol)
    return 0;
  else if(expr.id()==ID_index)
  {
    assert(expr.operands().size()==2);
    
    const typet &array_type=ns.follow(expr.op0().type());
    assert(array_type.id()==ID_array);

    mp_integer o=compute_pointer_offset(ns, expr.op0());
    
    if(o!=-1)
    {
      mp_integer sub_size=
        pointer_offset_size(ns, array_type.subtype());

      mp_integer i;

      if(sub_size!=0 && !to_integer(expr.op1(), i))
        return o+i*sub_size;
    }
      
    // don't know
  }
  else if(expr.id()==ID_member)
  {
    assert(expr.operands().size()==1);
    const typet &type=ns.follow(expr.op0().type());
    
    assert(type.id()==ID_struct ||
           type.id()==ID_union);

    mp_integer o=compute_pointer_offset(ns, expr.op0());

    if(o!=-1)
    {    
      if(type.id()==ID_union)
        return o;
    
      return o+member_offset(
        ns, to_struct_type(type), expr.get(ID_component_name));
    }
  }
  else if(expr.id()==ID_string_constant)
    return 0;

  return -1; // don't know
}
Beispiel #14
0
std::string expr2javat::convert(
  const exprt &src,
  unsigned &precedence)
{
  if(src.id()=="java-this")
    return convert_java_this(src, precedence=15);
  else if(src.id()==ID_side_effect &&
          (src.get(ID_statement)==ID_java_new ||
           src.get(ID_statement)==ID_java_new_array))
    return convert_java_new(src, precedence=15);
  else if(src.id()==ID_side_effect &&
          src.get(ID_statement)==ID_throw)
    return convert_function(src, "throw", precedence=16);
  else if(src.is_constant() && to_constant_expr(src).get_value()==ID_nullptr)
    return "nullptr";
  else if(src.id()==ID_unassigned)
    return "?";
  else if(src.id()=="pod_constructor")
    return "pod_constructor";
  else
    return expr2ct::convert(src, precedence);
}
Beispiel #15
0
void termination_baset::remove_ssa_ids(exprt &expr) const
{
  if(expr.id()==ID_symbol)
  {
    irep_idt ident=expr.get(ID_identifier);
    ident = id2string(ident).substr(0, id2string(ident).rfind('@'));
    ident = id2string(ident).substr(0, id2string(ident).rfind('!'));
    expr.set(ID_identifier, ident);
  }

  Forall_operands(it, expr)
    remove_ssa_ids(*it);
}
Beispiel #16
0
void goto_symext::replace_nondet(exprt &expr)
{
  if(expr.id()==ID_side_effect &&
     expr.get(ID_statement)==ID_nondet)
  {
    exprt new_expr(ID_nondet_symbol, expr.type());
    new_expr.set(ID_identifier, "symex::nondet"+std::to_string(nondet_count++));
    new_expr.add_source_location()=expr.source_location();
    expr.swap(new_expr);
  }
  else
    Forall_operands(it, expr)
      replace_nondet(*it);
}
Beispiel #17
0
exprt boolbvt::get(const exprt &expr) const
{
  if(expr.id()==ID_symbol ||
     expr.id()==ID_nondet_symbol)
  {
    const irep_idt &identifier=expr.get(ID_identifier);
    
    boolbv_mapt::mappingt::const_iterator it=
      map.mapping.find(identifier);

    if(it!=map.mapping.end())
    {
      const boolbv_mapt::map_entryt &map_entry=it->second;
    
      if(is_unbounded_array(map_entry.type))
        return bv_get_unbounded_array(identifier, to_array_type(map_entry.type));
        
      std::vector<bool> unknown;
      bvt bv;
      unsigned width=map_entry.width;

      bv.resize(width);
      unknown.resize(width);

      for(unsigned bit_nr=0; bit_nr<width; bit_nr++)
      {
        assert(bit_nr<map_entry.literal_map.size());

        if(map_entry.literal_map[bit_nr].is_set)
        {
          unknown[bit_nr]=false;
          bv[bit_nr]=map_entry.literal_map[bit_nr].l;
        }
        else
        {
          unknown[bit_nr]=true;
          bv[bit_nr].clear();
        }
      }

      return bv_get_rec(bv, unknown, 0, map_entry.type);
    }
  }
  else if(expr.id()==ID_constant)
    return expr;
  else if(expr.id()==ID_infinity)
    return expr;

  return SUB::get(expr);
}
Beispiel #18
0
void termination_baset::replace_nondet_sideeffects(exprt &expr)
{
  if(expr.id()=="sideeffect" &&
     expr.get("statement")=="nondet")
  {
    symbolt symbol;
    symbol.name=std::string("termination::nondet")+i2string(++nondet_counter);
    symbol.base_name=std::string("nondet")+i2string(nondet_counter);
    symbol.type=expr.type();

    expr=symbol_expr(symbol);
    shadow_context.move(symbol);
  }
  else
    Forall_operands(it, expr)
      replace_nondet_sideeffects(*it);
}
Beispiel #19
0
bool parse_format_string(
  const exprt &format_arg,
  format_token_listt &token_list)
{
  token_list.clear();

  if(format_arg.id()==ID_string_constant)
  {
    const std::string &arg_string = id2string(format_arg.get(ID_value));

    std::string::const_iterator it=arg_string.begin();

    while(it!=arg_string.end())
    {
      if(*it=='%')
      {
        token_list.push_back(format_tokent());
        format_tokent &curtok=token_list.back();
        it++;

        parse_flags(it, curtok);
        parse_field_width(it, curtok);
        parse_precision(it, curtok);
        parse_length_modifier(it, curtok);
        parse_conversion_specifier(arg_string, it, curtok);
      }
      else
      {
        if(token_list.back().type!=format_tokent::TEXT)
          token_list.push_back(format_tokent(format_tokent::TEXT));

        std::string tmp;
        for(;it!=arg_string.end() && *it!='%';it++)
          tmp+=*it;

        token_list.back().value=tmp;
      }
    }

    return true;
  }

  return false; // non-const format string
}
static void adjust_pred_index(exprt& expr,
    const predicatest& all_preds,
    const predicatest& passive_preds)
{
  Forall_operands(it, expr)
    adjust_pred_index(*it, all_preds, passive_preds);

  if(expr.id()==ID_predicate_symbol)
  {
    unsigned p=safe_str2unsigned(expr.get(ID_identifier).c_str());
    if(p >= passive_preds.size())
    {
      bool found=passive_preds.find(all_preds[p], p);
      assert(found);
      expr.id(ID_predicate_passive_symbol);
      expr.set(ID_identifier, p);
    }
  }
}
Beispiel #21
0
void trans_wpt::wp_rec(exprt &expr)
{
  Forall_operands(it, expr)
    wp_rec(*it);

  if(expr.id()==ID_symbol)
  {
    const irep_idt &identifier=expr.get(ID_identifier);

    const symbolt &symbol=ns.lookup(identifier);

    if(symbol.is_macro)
    {
      // it's just a macro
      expr=symbol.value;
      wp_rec(expr);
    }
    else if(symbol.is_statevar)
    {
      next_state_functionst::const_iterator
        it=next_state_functions.find(identifier);

      if(it==next_state_functions.end())
      {
        throw "trans_wpt: no next state function for "+
          id2string(identifier);
      }
      else
      {
        // replace!
        expr=it->second;
      }
    }
    else
    {
      // it's an input or so
      throw "trans_wpt: unexpected symbol: "+id2string(identifier);
    }
  }
}
exprt remove_const_function_pointerst::replace_const_symbols(
  const exprt &expression) const
{
  if(expression.id()==ID_symbol)
  {
    if(is_const_expression(expression))
    {
      const symbolt &symbol=
        symbol_table.lookup(expression.get(ID_identifier));
      if(symbol.type.id()!=ID_code)
      {
        const exprt &symbol_value=symbol.value;
        return replace_const_symbols(symbol_value);
      }
      else
      {
        return expression;
      }
    }
    else
    {
      return expression;
    }
  }
  else
  {
    exprt const_symbol_cleared_expr=expression;
    const_symbol_cleared_expr.operands().clear();
    for(const exprt &op : expression.operands())
    {
      exprt const_symbol_cleared_op=replace_const_symbols(op);
      const_symbol_cleared_expr.operands().push_back(const_symbol_cleared_op);
    }

    return const_symbol_cleared_expr;
  }
}
Beispiel #23
0
std::string expr2javat::convert_java_new(
  const exprt &src,
  unsigned precedence)
{
  std::string dest;

  if(src.get(ID_statement)==ID_java_new_array)
  {
    dest="new";

    std::string tmp_size=
      convert(static_cast<const exprt &>(src.find(ID_size)));

    dest+=' ';
    dest+=convert(src.type().subtype());
    dest+='[';
    dest+=tmp_size;
    dest+=']';
  }
  else
    dest="new "+convert(src.type().subtype());

  return dest;
}
void goto_convertt::do_scanf(
  const exprt &lhs,
  const exprt &function,
  const exprt::operandst &arguments,
  goto_programt &dest)
{
  const irep_idt &f_id=function.get(ID_identifier);

  if(f_id==CPROVER_PREFIX "scanf")
  {
    if(arguments.size()<1)
    {
      err_location(function);
      error() << "scanf takes at least one argument" << eom;
      throw 0;
    }
    
    irep_idt format_string;
    
    if(!get_string_constant(arguments[0], format_string))
    {
      // use our model
      format_token_listt token_list=parse_format_string(id2string(format_string));
        
      std::size_t argument_number=1;
      
      for(const auto & t : token_list)
      {
        typet type=get_type(t);
      
        if(type.is_not_nil())
        {
          if(argument_number<arguments.size())
          {
            exprt ptr=
              typecast_exprt(arguments[argument_number], pointer_type(type));
            argument_number++;

            // make it nondet for now
            exprt lhs=dereference_exprt(ptr, type);
            exprt rhs=side_effect_expr_nondett(type);
            code_assignt assign(lhs, rhs);
            assign.add_source_location()=function.source_location();
            copy(assign, ASSIGN, dest);
          }
        }
      }
    }
    else
    {
      // we'll just do nothing
      code_function_callt function_call;
      function_call.lhs()=lhs;
      function_call.function()=function;
      function_call.arguments()=arguments;
      function_call.add_source_location()=function.source_location();

      copy(function_call, FUNCTION_CALL, dest);
    }
  }
  else
    assert(false);
}
Beispiel #25
0
void value_sett::get_value_set_rec(
  const exprt &expr,
  object_mapt &dest,
  const std::string &suffix,
  const typet &original_type,
  const namespacet &ns) const
{
  #if 0
  std::cout << "GET_VALUE_SET_REC EXPR: " << from_expr(ns, "", expr) << "\n";
  std::cout << "GET_VALUE_SET_REC SUFFIX: " << suffix << std::endl;
  #endif

  const typet &expr_type=ns.follow(expr.type());

  if(expr.id()==ID_unknown || expr.id()==ID_invalid)
  {
    insert(dest, exprt(ID_unknown, original_type));
  }
  else if(expr.id()==ID_index)
  {
    assert(expr.operands().size()==2);

    const typet &type=ns.follow(expr.op0().type());

    assert(type.id()==ID_array ||
           type.id()==ID_incomplete_array);

    get_value_set_rec(expr.op0(), dest, "[]"+suffix, original_type, ns);
  }
  else if(expr.id()==ID_member)
  {
    assert(expr.operands().size()==1);

    const typet &type=ns.follow(expr.op0().type());

    assert(type.id()==ID_struct ||
           type.id()==ID_union ||
           type.id()==ID_incomplete_struct ||
           type.id()==ID_incomplete_union);

    const std::string &component_name=
      expr.get_string(ID_component_name);

    get_value_set_rec(expr.op0(), dest,
      "."+component_name+suffix, original_type, ns);
  }
  else if(expr.id()==ID_symbol)
  {
    irep_idt identifier=to_symbol_expr(expr).get_identifier();

    // is it a pointer, integer, array or struct?
    if(expr_type.id()==ID_pointer ||
       expr_type.id()==ID_signedbv ||
       expr_type.id()==ID_unsignedbv ||
       expr_type.id()==ID_struct ||
       expr_type.id()==ID_union ||
       expr_type.id()==ID_array)
    {
      // look it up
      valuest::const_iterator v_it=
        values.find(id2string(identifier)+suffix);

      // try first component name as suffix if not yet found
      if(v_it==values.end() &&
          (expr_type.id()==ID_struct ||
           expr_type.id()==ID_union))
      {
        const struct_union_typet &struct_union_type=
          to_struct_union_type(expr_type);

        const std::string first_component_name=
          struct_union_type.components().front().get_string(ID_name);

        v_it=values.find(
            id2string(identifier)+"."+first_component_name+suffix);
      }

      // not found? try without suffix
      if(v_it==values.end())
        v_it=values.find(identifier);

      if(v_it!=values.end())
        make_union(dest, v_it->second.object_map);
      else
        insert(dest, exprt(ID_unknown, original_type));
    }
    else
      insert(dest, exprt(ID_unknown, original_type));
  }
  else if(expr.id()==ID_if)
  {
    if(expr.operands().size()!=3)
      throw "if takes three operands";

    get_value_set_rec(expr.op1(), dest, suffix, original_type, ns);
    get_value_set_rec(expr.op2(), dest, suffix, original_type, ns);
  }
  else if(expr.id()==ID_address_of)
  {
    if(expr.operands().size()!=1)
      throw expr.id_string()+" expected to have one operand";

    get_reference_set(expr.op0(), dest, ns);
  }
  else if(expr.id()==ID_dereference)
  {
    object_mapt reference_set;
    get_reference_set(expr, reference_set, ns);
    const object_map_dt &object_map=reference_set.read();

    if(object_map.begin()==object_map.end())
      insert(dest, exprt(ID_unknown, original_type));
    else
    {
      for(object_map_dt::const_iterator
          it1=object_map.begin();
          it1!=object_map.end();
          it1++)
      {
        const exprt &object=object_numbering[it1->first];
        get_value_set_rec(object, dest, suffix, original_type, ns);
      }
    }
  }
  else if(expr.id()=="reference_to")
  {
    // old stuff, will go away
    object_mapt reference_set;

    get_reference_set(expr, reference_set, ns);

    const object_map_dt &object_map=reference_set.read();

    if(object_map.begin()==object_map.end())
      insert(dest, exprt(ID_unknown, original_type));
    else
    {
      for(object_map_dt::const_iterator
          it=object_map.begin();
          it!=object_map.end();
          it++)
      {
        const exprt &object=object_numbering[it->first];
        get_value_set_rec(object, dest, suffix, original_type, ns);
      }
    }
  }
  else if(expr.is_constant())
  {
    // check if NULL
    if(expr.get(ID_value)==ID_NULL &&
       expr_type.id()==ID_pointer)
    {
      insert(dest, exprt("NULL-object", expr_type.subtype()), 0);
    }
    else if(expr_type.id()==ID_unsignedbv ||
            expr_type.id()==ID_signedbv)
    {
      // an integer constant got turned into a pointer
      insert(dest, exprt(ID_integer_address, unsigned_char_type()));
    }
    else
      insert(dest, exprt(ID_unknown, original_type));
  }
  else if(expr.id()==ID_typecast)
  {
    if(expr.operands().size()!=1)
      throw "typecast takes one operand";

    // let's see what gets converted to what

    const typet &op_type=ns.follow(expr.op0().type());

    if(op_type.id()==ID_pointer)
    {
      // pointer-to-pointer -- we just ignore these
      get_value_set_rec(expr.op0(), dest, suffix, original_type, ns);
    }
    else if(op_type.id()==ID_unsignedbv ||
            op_type.id()==ID_signedbv)
    {
      // integer-to-pointer

      if(expr.op0().is_zero())
        insert(dest, exprt("NULL-object", expr_type.subtype()), 0);
      else
      {
        // see if we have something for the integer
        object_mapt tmp;

        get_value_set_rec(expr.op0(), tmp, suffix, original_type, ns);

        if(tmp.read().size()==0)
        {
          // if not, throw in integer
          insert(dest, exprt(ID_integer_address, unsigned_char_type()));
        }
        else if(tmp.read().size()==1 &&
                object_numbering[tmp.read().begin()->first].id()==ID_unknown)
        {
          // if not, throw in integer
          insert(dest, exprt(ID_integer_address, unsigned_char_type()));
        }
        else
        {
          // use as is
          dest.write().insert(tmp.read().begin(), tmp.read().end());
        }
      }
    }
    else
      insert(dest, exprt(ID_unknown, original_type));
  }
  else if(expr.id()==ID_plus ||
          expr.id()==ID_minus)
  {
    if(expr.operands().size()<2)
      throw expr.id_string()+" expected to have at least two operands";

    object_mapt pointer_expr_set;
    mp_integer i;
    bool i_is_set=false;

    // special case for pointer+integer

    if(expr.operands().size()==2 &&
       expr_type.id()==ID_pointer)
    {
      exprt ptr_operand;

      if(expr.op0().type().id()!=ID_pointer &&
         expr.op0().is_constant())
      {
        i_is_set=!to_integer(expr.op0(), i);
        ptr_operand=expr.op1();
      }
      else
      {
        i_is_set=!to_integer(expr.op1(), i);
        ptr_operand=expr.op0();
      }

      if(i_is_set)
      {
        i*=pointer_offset_size(ptr_operand.type().subtype(), ns);

        if(expr.id()==ID_minus) i.negate();
      }

      get_value_set_rec(
        ptr_operand, pointer_expr_set, "", ptr_operand.type(), ns);
    }
    else
    {
      // we get the points-to for all operands, even integers
      forall_operands(it, expr)
      {
        get_value_set_rec(
          *it, pointer_expr_set, "", it->type(), ns);
      }
    }

    for(object_map_dt::const_iterator
        it=pointer_expr_set.read().begin();
        it!=pointer_expr_set.read().end();
        it++)
    {
      objectt object=it->second;

      // adjust by offset
      if(object.offset_is_zero() && i_is_set)
        object.offset=i;
      else
        object.offset_is_set=false;

      insert(dest, it->first, object);
    }
  }
Beispiel #26
0
xmlt xml(
  const exprt &expr,
  const namespacet &ns)
{
  xmlt result;
  
  const typet &type=ns.follow(expr.type());

  if(expr.id()==ID_constant)
  {
    if(type.id()==ID_unsignedbv ||
       type.id()==ID_signedbv ||
       type.id()==ID_c_bit_field)
    {
      std::size_t width=to_bitvector_type(type).get_width();
    
      result.name="integer";
      result.set_attribute("binary", expr.get_string(ID_value));
      result.set_attribute("width", width);
      
      const typet &underlying_type=
        type.id()==ID_c_bit_field?type.subtype():
        type;

      bool is_signed=underlying_type.id()==ID_signedbv;
        
      std::string sig=is_signed?"":"unsigned ";

      if(width==config.ansi_c.char_width)
        result.set_attribute("c_type", sig+"char");
      else if(width==config.ansi_c.int_width)
        result.set_attribute("c_type", sig+"int");
      else if(width==config.ansi_c.short_int_width)
        result.set_attribute("c_type", sig+"short int");
      else if(width==config.ansi_c.long_int_width)
        result.set_attribute("c_type", sig+"long int");
      else if(width==config.ansi_c.long_long_int_width)
        result.set_attribute("c_type", sig+"long long int");

      mp_integer i;
      if(!to_integer(expr, i))
        result.data=integer2string(i);
    }
    else if(type.id()==ID_c_enum)
    {
      result.name="integer";
      result.set_attribute("binary", expr.get_string(ID_value));
      result.set_attribute("width", type.subtype().get_string(ID_width));
      result.set_attribute("c_type", "enum");

      mp_integer i;
      if(!to_integer(expr, i))
        result.data=integer2string(i);
    }
    else if(type.id()==ID_c_enum_tag)
    {
      constant_exprt tmp;
      tmp.type()=ns.follow_tag(to_c_enum_tag_type(type));
      tmp.set_value(to_constant_expr(expr).get_value());
      return xml(tmp, ns);
    }
    else if(type.id()==ID_bv)
    {
      result.name="bitvector";
      result.set_attribute("binary", expr.get_string(ID_value));
    }
    else if(type.id()==ID_fixedbv)
    {
      result.name="fixed";
      result.set_attribute("width", type.get_string(ID_width));
      result.set_attribute("binary", expr.get_string(ID_value));
      result.data=fixedbvt(to_constant_expr(expr)).to_ansi_c_string();
    }
    else if(type.id()==ID_floatbv)
    {
      result.name="float";
      result.set_attribute("width", type.get_string(ID_width));
      result.set_attribute("binary", expr.get_string(ID_value));
      result.data=ieee_floatt(to_constant_expr(expr)).to_ansi_c_string();
    }
    else if(type.id()==ID_pointer)
    {
      result.name="pointer";
      result.set_attribute("binary", expr.get_string(ID_value));
      if(expr.get(ID_value)==ID_NULL)
        result.data="NULL";
    }
    else if(type.id()==ID_bool)
    {
      result.name="boolean";
      result.set_attribute("binary", expr.is_true()?"1":"0");
      result.data=expr.is_true()?"TRUE":"FALSE";
    }
    else
    {
      result.name="unknown";
    }
  }
  else if(expr.id()==ID_array)
  {
    result.name="array";
    
    unsigned index=0;
    
    forall_operands(it, expr)
    {
      xmlt &e=result.new_element("element");
      e.set_attribute("index", index);
      e.new_element(xml(*it, ns));
      index++;
    }
Beispiel #27
0
xmlt xml(
  const exprt &expr,
  const namespacet &ns)
{
  const typet &type=ns.follow(expr.type());
  xmlt result;
  
  if(expr.id()==ID_constant)
  {
    if(type.id()==ID_unsignedbv ||
       type.id()==ID_signedbv)
    {
      result.name="integer";
      result.set_attribute("binary", expr.get_string(ID_value));

      mp_integer i;
      if(!to_integer(expr, i))
        result.data=integer2string(i);
    }
    else if(type.id()==ID_bv)
    {
      result.name="bitvector";
      result.set_attribute("binary", expr.get_string(ID_value));
      result.data=expr.get_string(ID_value);
    }
    else if(type.id()==ID_fixedbv)
    {
      result.name="fixed";
      result.set_attribute("binary", expr.get_string(ID_value));
      result.data=fixedbvt(to_constant_expr(expr)).to_ansi_c_string();
    }
    else if(type.id()==ID_floatbv)
    {
      result.name="float";
      result.set_attribute("binary", expr.get_string(ID_value));
      result.data=ieee_floatt(to_constant_expr(expr)).to_ansi_c_string();
    }
    else if(type.id()==ID_pointer)
    {
      result.name="pointer";
      result.set_attribute("binary", expr.get_string(ID_value));
      if(expr.get(ID_value)==ID_NULL)
        result.data="NULL";
    }
    else if(type.id()==ID_bool)
    {
      result.name="boolean";
      result.set_attribute("binary", expr.is_true()?"1":"0");
      result.data=expr.is_true()?"TRUE":"FALSE";
    }
    else
    {
      result.name="unknown";
    }
  }
  else if(expr.id()==ID_array)
  {
    result.name="array";
    
    unsigned index=0;
    
    forall_operands(it, expr)
    {
      xmlt &e=result.new_element("element");
      e.set_attribute("index", index);
      e.new_element(xml(*it, ns));
      index++;
    }
Beispiel #28
0
void dplib_convt::convert_dplib_expr(const exprt &expr)
{
    if(expr.id()==ID_symbol)
    {
        convert_identifier(expr.get_string(ID_identifier));
    }
    else if(expr.id()==ID_nondet_symbol)
    {
        convert_identifier("nondet$"+expr.get_string(ID_identifier));
    }
    else if(expr.id()==ID_typecast)
    {
        assert(expr.operands().size()==1);
        const exprt &op=expr.op0();

        if(expr.type().id()==ID_bool)
        {
            if(op.type().id()==ID_signedbv ||
                    op.type().id()==ID_unsignedbv ||
                    op.type().id()==ID_pointer)
            {
                convert_dplib_expr(op);
                dplib_prop.out << "/=";
                convert_dplib_expr(gen_zero(op.type()));
            }
            else
            {
                throw "TODO typecast1 "+op.type().id_string()+" -> bool";
            }
        }
        else if(expr.type().id()==ID_signedbv ||
                expr.type().id()==ID_unsignedbv)
        {
            unsigned to_width=unsafe_string2unsigned(id2string(expr.type().get(ID_width)));

            if(op.type().id()==ID_signedbv)
            {
                unsigned from_width=unsafe_string2unsigned(id2string(op.type().get(ID_width)));

                if(from_width==to_width)
                    convert_dplib_expr(op);
                else if(from_width<to_width)
                {
                    dplib_prop.out << "SX(";
                    convert_dplib_expr(op);
                    dplib_prop.out << ", " << to_width << ")";
                }
                else
                {
                    dplib_prop.out << "(";
                    convert_dplib_expr(op);
                    dplib_prop.out << ")[" << (to_width-1) << ":0]";
                }
            }
            else if(op.type().id()==ID_unsignedbv)
            {
                unsigned from_width=unsafe_string2unsigned(id2string(op.type().get(ID_width)));

                if(from_width==to_width)
                    convert_dplib_expr(op);
                else if(from_width<to_width)
                {
                    dplib_prop.out << "(0bin";

                    for(unsigned i=from_width; i<to_width; i++)
                        dplib_prop.out << "0";

                    dplib_prop.out << " @ ";

                    dplib_prop.out << "(";
                    convert_dplib_expr(op);
                    dplib_prop.out << "))";
                }
                else
                {
                    dplib_prop.out << "(";
                    convert_dplib_expr(op);
                    dplib_prop.out << ")[" << (to_width-1) << ":0]";
                }
            }
            else if(op.type().id()==ID_bool)
            {
                if(to_width>1)
                {
                    dplib_prop.out << "(0bin";

                    for(unsigned i=1; i<to_width; i++)
                        dplib_prop.out << "0";

                    dplib_prop.out << " @ ";

                    dplib_prop.out << "IF ";
                    convert_dplib_expr(op);
                    dplib_prop.out << " THEN 0bin1 ELSE 0bin0 ENDIF)";
                }
                else
                {
                    dplib_prop.out << "IF ";
                    convert_dplib_expr(op);
                    dplib_prop.out << " THEN 0bin1 ELSE 0bin0 ENDIF";
                }
            }
            else
            {
                throw "TODO typecast2 "+op.type().id_string()+
                " -> "+expr.type().id_string();
            }
        }
        else if(expr.type().id()==ID_pointer)
        {
            if(op.type().id()==ID_pointer)
            {
                convert_dplib_expr(op);
            }
            else
                throw "TODO typecast3 "+op.type().id_string()+" -> pointer";
        }
        else
            throw "TODO typecast4 ? -> "+expr.type().id_string();
    }
    else if(expr.id()==ID_struct)
    {
        dplib_prop.out << "(# ";

        const struct_typet &struct_type=to_struct_type(expr.type());

        const struct_typet::componentst &components=
            struct_type.components();

        assert(components.size()==expr.operands().size());

        unsigned i=0;
        for(struct_typet::componentst::const_iterator
                it=components.begin();
                it!=components.end();
                it++, i++)
        {
            if(i!=0) dplib_prop.out << ", ";
            dplib_prop.out << it->get(ID_name);
            dplib_prop.out << ":=";
            convert_dplib_expr(expr.operands()[i]);
        }

        dplib_prop.out << " #)";
    }
    else if(expr.id()==ID_constant)
    {
        if(expr.type().id()==ID_unsignedbv ||
                expr.type().id()==ID_signedbv ||
                expr.type().id()==ID_bv)
        {
            dplib_prop.out << "0bin" << expr.get(ID_value);
        }
        else if(expr.type().id()==ID_pointer)
        {
            const irep_idt &value=expr.get(ID_value);

            if(value=="NULL")
            {
                dplib_prop.out << "(# object:="
                               << pointer_logic.get_null_object()
                               << ", offset:="
                               << bin_zero(config.ansi_c.pointer_width) << " #)";
            }
            else
                throw "unknown pointer constant: "+id2string(value);
        }
        else if(expr.type().id()==ID_bool)
        {
            if(expr.is_true())
                dplib_prop.out << "TRUE";
            else if(expr.is_false())
                dplib_prop.out << "FALSE";
            else
                throw "unknown boolean constant";
        }
        else if(expr.type().id()==ID_array)
        {
            dplib_prop.out << "ARRAY (i: " << array_index_type() << "):";

            assert(!expr.operands().empty());

            unsigned i=0;
            forall_operands(it, expr)
            {
                if(i==0)
                    dplib_prop.out << "\n  IF ";
                else
                    dplib_prop.out << "\n  ELSIF ";

                dplib_prop.out << "i=" << array_index(i) << " THEN ";
                convert_array_value(*it);
                i++;
            }

            dplib_prop.out << "\n  ELSE ";
            convert_dplib_expr(expr.op0());
            dplib_prop.out << "\n  ENDIF";
        }
        else if(expr.type().id()==ID_integer ||
void goto_convertt::do_prob_uniform(
  const exprt &lhs,
  const exprt &function,
  const exprt::operandst &arguments,
  goto_programt &dest)
{
  const irep_idt &identifier=function.get(ID_identifier);

  // make it a side effect if there is an LHS
  if(arguments.size()!=2)
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected to have two arguments";
  }

  if(lhs.is_nil())
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected to have LHS";
  }

  exprt rhs=side_effect_exprt("prob_uniform", lhs.type());
  rhs.add_source_location()=function.source_location();

  if(lhs.type().id()!=ID_unsignedbv &&
     lhs.type().id()!=ID_signedbv)
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected other type";
  }

  if(arguments[0].type().id()!=lhs.type().id() ||
     arguments[1].type().id()!=lhs.type().id())
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected operands to be of same type as LHS";
  }

  if(!arguments[0].is_constant() ||
     !arguments[1].is_constant())
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected operands to be constant literals";
  }

  mp_integer lb, ub;

  if(to_integer(arguments[0], lb) ||
     to_integer(arguments[1], ub))
  {
    err_location(function);
    throw "error converting operands";
  }

  if(lb > ub)
  {
    err_location(function);
    throw "expected lower bound to be smaller or equal to the upper bound";
  }

  rhs.copy_to_operands(arguments[0], arguments[1]);

  code_assignt assignment(lhs, rhs);
  assignment.add_source_location()=function.source_location();
  copy(assignment, ASSIGN, dest);
}
void goto_convertt::do_prob_coin(
  const exprt &lhs,
  const exprt &function,
  const exprt::operandst &arguments,
  goto_programt &dest)
{
  const irep_idt &identifier=function.get(ID_identifier);

  // make it a side effect if there is an LHS
  if(arguments.size()!=2) 
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected to have two arguments";
  }
  
  if(lhs.is_nil())
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected to have LHS";
  }

  exprt rhs=side_effect_exprt("prob_coin", lhs.type());
  rhs.add_source_location()=function.source_location();

  if(lhs.type()!=bool_typet())
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected bool";
  }

  if(arguments[0].type().id()!=ID_unsignedbv ||
     arguments[0].id()!=ID_constant)
  {
    err_location(function);
    throw "`"+id2string(identifier)+"' expected first "
          "operand to be a constant literal of type unsigned long";
  }

  mp_integer num, den;

  if(to_integer(arguments[0], num) ||
     to_integer(arguments[1], den))
  {
    err_location(function);
    throw "error converting operands";
  }

  if(num-den > mp_integer(0))
  {
    err_location(function);
    throw "probability has to be smaller than 1";
  }

  if(den == mp_integer(0))
  {
    err_location(function);
    throw "denominator may not be zero";
  }

  rationalt numerator(num), denominator(den);
  rationalt prob = numerator / denominator;

  rhs.copy_to_operands(from_rational(prob));

  code_assignt assignment(lhs, rhs);
  assignment.add_source_location()=function.source_location();
  copy(assignment, ASSIGN, dest);
}