예제 #1
0
void goto_checkt::pointer_rel_check(
  const exprt &expr,
  const guardt &guard)
{
  if(!enable_pointer_check)
    return;

  if(expr.operands().size()!=2)
    throw expr.id_string()+" takes two arguments";

  if(expr.op0().type().id()==ID_pointer &&
     expr.op1().type().id()==ID_pointer)
  {
    // add same-object subgoal

    if(enable_pointer_check)
    {
      exprt same_object=::same_object(expr.op0(), expr.op1());

      add_guarded_claim(
        same_object,
        "same object violation",
        "pointer",
        expr.find_source_location(),
        expr,
        guard);
    }
  }
}
예제 #2
0
bool simplify_exprt::simplify_ieee_float_relation(exprt &expr)
{
  assert(expr.id()==ID_ieee_float_equal ||
         expr.id()==ID_ieee_float_notequal);

  exprt::operandst &operands=expr.operands();

  if(expr.type().id()!=ID_bool)
    return true;

  if(operands.size()!=2)
    return true;

  // types must match
  if(expr.op0().type()!=expr.op1().type())
    return true;

  if(expr.op0().type().id()!=ID_floatbv)
    return true;

  // first see if we compare to a constant

  if(expr.op0().is_constant() &&
     expr.op1().is_constant())
  {
    ieee_floatt f0(to_constant_expr(expr.op0()));
    ieee_floatt f1(to_constant_expr(expr.op1()));

    if(expr.id()==ID_ieee_float_notequal)
      expr.make_bool(f0.ieee_not_equal(f1));
    else if(expr.id()==ID_ieee_float_equal)
      expr.make_bool(f0.ieee_equal(f1));
    else
      assert(false);

    return false;
  }

  if(expr.op0()==expr.op1())
  {
    // x!=x is the same as saying isnan(op)
    exprt isnan(ID_isnan, bool_typet());
    isnan.copy_to_operands(expr.op0());

    if(expr.id()==ID_ieee_float_notequal)
    {
    }
    else if(expr.id()==ID_ieee_float_equal)
      isnan.make_not();
    else
      assert(false);

    expr.swap(isnan);
    return false;
  }

  return true;
}
예제 #3
0
void boolbvt::convert_div(const exprt &expr, bvt &bv)
{
  if(expr.type().id()!=ID_unsignedbv &&
     expr.type().id()!=ID_signedbv &&
     expr.type().id()!=ID_fixedbv)
    return conversion_failed(expr, bv);

  unsigned width=boolbv_width(expr.type());
  
  if(width==0)
    return conversion_failed(expr, bv);

  if(expr.operands().size()!=2)
    throw "division takes two operands";

  if(expr.op0().type().id()!=expr.type().id() ||
     expr.op1().type().id()!=expr.type().id())
    return conversion_failed(expr, bv);

  bvt op0=convert_bv(expr.op0());
  bvt op1=convert_bv(expr.op1());

  if(op0.size()!=width ||
     op1.size()!=width)
    throw "convert_div: unexpected operand width";

  bvt res, rem;

  if(expr.type().id()==ID_fixedbv)
  {
    unsigned fraction_bits=
      to_fixedbv_type(expr.type()).get_fraction_bits();

    bvt zeros;
    zeros.resize(fraction_bits, const_literal(false));

    // add fraction_bits least-significant bits
    op0.insert(op0.begin(), zeros.begin(), zeros.end());
    op1=bv_utils.sign_extension(op1, op1.size()+fraction_bits);
  
    bv_utils.divider(op0, op1, res, rem, bv_utilst::SIGNED);
    
    // cut it down again
    res.resize(width);
  }
  else
  {
    bv_utilst::representationt rep=
      expr.type().id()==ID_signedbv?bv_utilst::SIGNED:
                                   bv_utilst::UNSIGNED;

    bv_utils.divider(op0, op1, res, rem, rep);
  }

  bv=res;
}
예제 #4
0
void invariant_sett::strengthen_rec(const exprt &expr)
{
  if(expr.type().id()!=ID_bool)
    throw "non-Boolean argument to strengthen()";

  #if 0
  std::cout << "S: " << from_expr(*ns, "", expr) << '\n';
  #endif

  if(is_false)
  {
    // we can't get any stronger
    return;
  }

  if(expr.is_true())
  {
    // do nothing, it's useless
  }
  else if(expr.is_false())
  {
    // wow, that's strong
    make_false();
  }
  else if(expr.id()==ID_not)
  {
    // give up, we expect NNF
  }
  else if(expr.id()==ID_and)
  {
    forall_operands(it, expr)
      strengthen_rec(*it);
  }
  else if(expr.id()==ID_le ||
          expr.id()==ID_lt)
  {
    assert(expr.operands().size()==2);

    // special rule: x <= (a & b)
    // implies:      x<=a && x<=b

    if(expr.op1().id()==ID_bitand)
    {
      const exprt &bitand_op=expr.op1();

      forall_operands(it, bitand_op)
      {
        exprt tmp(expr);
        tmp.op1()=*it;
        strengthen_rec(tmp);
      }

      return;
    }
예제 #5
0
void boolbvt::convert_replication(const exprt &expr, bvt &bv)
{
  unsigned width=boolbv_width(expr.type());
  
  if(width==0)
    return conversion_failed(expr, bv);

  if(expr.operands().size()!=2)
    throw "replication takes two operands";

  mp_integer times;
  if(to_integer(expr.op0(), times))
    throw "replication takes constant as first parameter";
  const unsigned u_times=integer2unsigned(times);

  const bvt &op=convert_bv(expr.op1());

  unsigned offset=0;
  bv.resize(width);

  for(unsigned i=0; i<u_times; i++)
  {
    if(op.size()+offset>width)
      throw "replication operand width too big";

    for(unsigned i=0; i<op.size(); i++)
      bv[i+offset]=op[i];

    offset+=op.size();
  }    

  if(offset!=bv.size())
    throw "replication operand width too small";
}
예제 #6
0
exprt dereferencet::dereference_plus(
  const exprt &expr,
  const exprt &offset,
  const typet &type)
{
  if(expr.operands().size()>2)
    return dereference_rec(make_binary(expr), offset, type);

  // binary
  exprt pointer=expr.op0(), integer=expr.op1();

  if(ns.follow(integer.type()).id()==ID_pointer)
    std::swap(pointer, integer);

  // multiply integer by object size
  exprt size=size_of_expr(pointer.type().subtype(), ns);
  if(size.is_nil())
    throw "dereference failed to get object size for pointer arithmetic";

  // make types of offset and size match
  if(size.type()!=integer.type())
    integer.make_typecast(size.type());

  exprt new_offset=plus_exprt(offset, mult_exprt(size, integer));

  return dereference_rec(pointer, new_offset, type);
}
예제 #7
0
exprt modelchecker_smvt::convert_schoose_expression(
  const exprt &expr, const exprt &guard)
{
  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";
  
  exprt nondet("symbol", typet("bool"));
  nondet.set("identifier", it->second);
  
  exprt conj("and", typet("bool"));
  conj.move_to_operands(nondet);
  conj.copy_to_operands(expr.op1());
  conj.op1().make_not();

  //exprt disj("or", typet("bool"));
  //disj.copy_to_operands(expr.op0(), guard);

  exprt target("or", typet("bool"));

  target.move_to_operands(conj);
  target.copy_to_operands(expr.op0());
  
  return target;
}
예제 #8
0
/// checks whether a termination argument implies termination
threevalt summarizer_fw_termt::check_termination_argument(exprt expr)
{
  if(expr.is_false())
    return YES;

  // should be of the form /\_i g_i=> R_i
  if(expr.id()==ID_and)
  {
    threevalt result=YES;
    for(exprt::operandst::iterator it=expr.operands().begin();
        it!=expr.operands().end(); it++)
    {
      if(it->is_true())
        result=UNKNOWN;
      if(it->id()==ID_implies)
      {
        if(it->op1().is_true())
          result=UNKNOWN;
      }
    }
    return result;
  }
  else
  {
    if(expr.id()==ID_implies)
    {
      if(expr.op1().is_true())
        return UNKNOWN;
    }
    else
      return !expr.is_true() ? YES : UNKNOWN;
  }
  return YES;
}
예제 #9
0
literalt boolbvt::convert_ieee_float_rel(const exprt &expr)
{
  const exprt::operandst &operands=expr.operands();
  const irep_idt &rel=expr.id();

  if(operands.size()==2)
  {
    const exprt &op0=expr.op0();
    const exprt &op1=expr.op1();

    bvtypet bvtype0=get_bvtype(op0.type());
    bvtypet bvtype1=get_bvtype(op1.type());

    const bvt &bv0=convert_bv(op0);
    const bvt &bv1=convert_bv(op1);

    if(bv0.size()==bv1.size() && !bv0.empty() &&
       bvtype0==IS_FLOAT && bvtype1==IS_FLOAT)
    {
      float_utilst float_utils(prop);
      float_utils.spec=to_floatbv_type(op0.type());

      if(rel==ID_ieee_float_equal)
        return float_utils.relation(bv0, float_utilst::EQ, bv1);
      else if(rel==ID_ieee_float_notequal)
        return !float_utils.relation(bv0, float_utilst::EQ, bv1);
      else
        return SUB::convert_rest(expr);
    }
  }

  return SUB::convert_rest(expr);
}
예제 #10
0
void jsil_typecheckt::typecheck_expr_ref(exprt &expr)
{
  if(expr.operands().size()!=3)
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects three operands" << eom;
    throw 0;
  }

  make_type_compatible(expr.op0(), jsil_value_type(), true);
  make_type_compatible(expr.op1(), string_typet(), true);

  exprt &operand3=expr.op2();
  make_type_compatible(operand3, jsil_kind(), true);

  if(operand3.id()==ID_member)
    expr.type()=jsil_member_reference_type();
  else if(operand3.id()=="variable")
    expr.type()=jsil_variable_reference_type();
  else
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects reference type in the third parameter. Got:"
            << operand3.pretty() << eom;
    throw 0;
  }
}
예제 #11
0
void goto_checkt::pointer_rel_check(const exprt &expr, const guardt &guard)
{
  if (expr.operands().size() != 2)
    throw expr.id_string() + " takes one argument";

  if (expr.op0().type().id() == "pointer"
      && expr.op1().type().id() == "pointer")
  {
    // add same-object subgoal

    if (!options.get_bool_option("no-pointer-check"))
    {
      exprt same_object("same-object", bool_typet());
      same_object.copy_to_operands(expr.op0(), expr.op1());
      add_guarded_claim(same_object, "same object violation", "pointer",
          expr.find_location(), guard);
    }
  }
}
예제 #12
0
void jsil_typecheckt::typecheck_expr_index(exprt &expr)
{
  if(expr.operands().size()!=2)
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects two operands" << eom;
    throw 0;
  }

  make_type_compatible(expr.op0(), jsil_object_type(), true);
  make_type_compatible(expr.op1(), string_typet(), true);

  // special case for function identifiers
  if (expr.op1().id()=="fid" || expr.op1().id()=="constructid")
    expr.type()=code_typet();
  else
    expr.type()=jsil_value_type();
}
예제 #13
0
void bv_refinementt::convert_mod(const exprt &expr, bvt &bv)
{
  // we catch any mod
  // unless it's integer + constant

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

  if(expr.op1().is_constant())
    return SUB::convert_mod(expr, bv);

  add_approximation(expr, bv);
}
예제 #14
0
void goto_checkt::div_by_zero_check(const exprt &expr, const guardt &guard)
{
  if (options.get_bool_option("no-div-by-zero-check"))
    return;

  if (expr.operands().size() != 2)
    throw expr.id_string() + " takes two arguments";

  // add divison by zero subgoal

  exprt zero = gen_zero(expr.op1().type());

  if (zero.is_nil())
    throw "no zero of argument type of operator " + expr.id_string();

  exprt inequality("notequal", bool_typet());
  inequality.copy_to_operands(expr.op1(), zero);

  add_guarded_claim(inequality, "division by zero", "division-by-zero",
      expr.find_location(), guard);
}
예제 #15
0
파일: expr2java.cpp 프로젝트: diffblue/cbmc
std::string expr2javat::convert_java_instanceof(
  const exprt &src,
  unsigned precedence)
{
  if(src.operands().size()!=2)
  {
    unsigned precedence;
    return convert_norep(src, precedence);
  }

  return convert(src.op0())+" instanceof "+convert(src.op1().type());
}
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
}
예제 #17
0
bool simplify_exprt::simplify_inequality_address_of(exprt &expr)
{
    assert(expr.type().id()==ID_bool);
    assert(expr.operands().size()==2);
    assert(expr.id()==ID_equal || expr.id()==ID_notequal);

    exprt tmp0=expr.op0();
    if(tmp0.id()==ID_typecast)
        tmp0=expr.op0().op0();
    if(tmp0.op0().id()==ID_index &&
            to_index_expr(tmp0.op0()).index().is_zero())
        tmp0=address_of_exprt(to_index_expr(tmp0.op0()).array());
    exprt tmp1=expr.op1();
    if(tmp1.id()==ID_typecast)
        tmp1=expr.op1().op0();
    if(tmp1.op0().id()==ID_index &&
            to_index_expr(tmp1.op0()).index().is_zero())
        tmp1=address_of_exprt(to_index_expr(tmp1.op0()).array());
    assert(tmp0.id()==ID_address_of);
    assert(tmp1.id()==ID_address_of);

    if(tmp0.operands().size()!=1) return true;
    if(tmp1.operands().size()!=1) return true;

    if(tmp0.op0().id()==ID_symbol &&
            tmp1.op0().id()==ID_symbol)
    {
        bool equal=
            tmp0.op0().get(ID_identifier)==
            tmp1.op0().get(ID_identifier);

        expr.make_bool(expr.id()==ID_equal?equal:!equal);

        return false;
    }

    return true;
}
예제 #18
0
void jsil_typecheckt::typecheck_expr_binary_compare(exprt &expr)
{
  if(expr.operands().size()!=2)
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects two operands" << eom;
    throw 0;
  }

  make_type_compatible(expr.op0(), floatbv_typet(), true);
  make_type_compatible(expr.op1(), floatbv_typet(), true);

  expr.type()=bool_typet();
}
예제 #19
0
void jsil_typecheckt::typecheck_expr_concatenation(exprt &expr)
{
  if(expr.operands().size()!=2)
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects two operands" << eom;
    throw 0;
  }

  make_type_compatible(expr.op0(), string_typet(), true);
  make_type_compatible(expr.op1(), string_typet(), true);

  expr.type()=string_typet();
}
예제 #20
0
void goto_symext::rewrite_quantifiers(exprt &expr, statet &state)
{
  if(expr.id()==ID_forall)
  {
    // forall X. P -> P
    // we keep the quantified variable unique by means of L2 renaming
    assert(expr.operands().size()==2);
    assert(expr.op0().id()==ID_symbol);
    symbol_exprt tmp0=
      to_symbol_expr(to_ssa_expr(expr.op0()).get_original_expr());
    symex_decl(state, tmp0);
    exprt tmp=expr.op1();
    expr.swap(tmp);
  }
}
예제 #21
0
void jsil_typecheckt::typecheck_expr_proto_obj(exprt &expr)
{
  if(expr.operands().size()!=2)
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects two operands";
    throw 0;
  }

  make_type_compatible(expr.op0(), jsil_object_type(), true);
  make_type_compatible(expr.op1(), jsil_object_type(), true);

  expr.type()=bool_typet();
}
예제 #22
0
void jsil_typecheckt::typecheck_expr_proto_field(exprt &expr)
{
  if(expr.operands().size()!=2)
  {
    err_location(expr);
    error() << "operator `" << expr.id()
            << "' expects two operands" << eom;
    throw 0;
  }

  make_type_compatible(expr.op0(), jsil_object_type(), true);
  make_type_compatible(expr.op1(), string_typet(), true);

  expr.type()=jsil_value_or_empty_type();
}
예제 #23
0
void goto_symext::replace_array_equal(exprt &expr)
{
  if(expr.id()==ID_array_equal)
  {
    assert(expr.operands().size()==2);
   
    // we expect two index expressions
    process_array_expr(expr.op0());
    process_array_expr(expr.op1());

    // type checking
    if(ns.follow(expr.op0().type())!=
       ns.follow(expr.op1().type()))
      expr=false_exprt();
    else
    {
      equal_exprt equality_expr(expr.op0(), expr.op1());
      expr.swap(equality_expr);
    }
  }

  Forall_operands(it, expr)
    replace_array_equal(*it);
}
예제 #24
0
void bv_refinementt::set_to(const exprt &expr, bool value)
{
  #if 0
  unsigned prev=prop.no_variables();
  SUB::set_to(expr, value);
  unsigned n=prop.no_variables()-prev;
  std::cout << n << " EEE " << expr.id() << "@" << expr.type().id();
  forall_operands(it, expr) std::cout << " " << it->id() << "@" << it->type().id();
  if(expr.id()=="=" && expr.operands().size()==2)
    forall_operands(it, expr.op1()) std::cout << " " << it->id() << "@" << it->type().id();
  std::cout << std::endl;
  #else
  SUB::set_to(expr, value);
  #endif
}
예제 #25
0
bool inv_object_storet::is_constant_address_rec(const exprt &expr)
{
  if(expr.id()==ID_symbol)
    return true;
  else if(expr.id()==ID_member)
  {
    assert(expr.operands().size()==1);
    return is_constant_address_rec(expr.op0());
  }
  else if(expr.id()==ID_index)
  {
    assert(expr.operands().size()==2);
    if(expr.op1().is_constant())
      return is_constant_address_rec(expr.op0());
  }

  return false;
}
예제 #26
0
void interval_domaint::assume_rec(
  const exprt &cond,
  bool negation)
{
  if(cond.id()==ID_lt || cond.id()==ID_le ||
     cond.id()==ID_gt || cond.id()==ID_ge ||
     cond.id()==ID_equal || cond.id()==ID_notequal)
  {
    assert(cond.operands().size()==2);

    if(negation) // !x<y  ---> x>=y
    {
      if(cond.id()==ID_lt)
        assume_rec(cond.op0(), ID_ge, cond.op1());
      else if(cond.id()==ID_le)
        assume_rec(cond.op0(), ID_gt, cond.op1());
      else if(cond.id()==ID_gt)
        assume_rec(cond.op0(), ID_le, cond.op1());
      else if(cond.id()==ID_ge)
        assume_rec(cond.op0(), ID_lt, cond.op1());
      else if(cond.id()==ID_equal)
        assume_rec(cond.op0(), ID_notequal, cond.op1());
      else if(cond.id()==ID_notequal)
        assume_rec(cond.op0(), ID_equal, cond.op1());
    }
    else
      assume_rec(cond.op0(), cond.id(), cond.op1());
  }
  else if(cond.id()==ID_not)
  {
    assume_rec(to_not_expr(cond).op(), !negation);
  }
  else if(cond.id()==ID_and)
  {
    if(!negation)
      forall_operands(it, cond)
        assume_rec(*it, false);
  }
  else if(cond.id()==ID_or)
  {
    if(negation)
      forall_operands(it, cond)
        assume_rec(*it, true);
  }
}
예제 #27
0
void boolbvt::convert_update(const exprt &expr, bvt &bv)
{
  const exprt::operandst &ops=expr.operands();

  if(ops.size()!=3)
    throw "update takes at three operands";

  std::size_t width=boolbv_width(expr.type());

  if(width==0)
    return conversion_failed(expr, bv);

  bv=convert_bv(ops[0]);

  if(bv.size()!=width)
    throw "update: unexpected operand 0 width";

  // start the recursion
  convert_update_rec(
    expr.op1().operands(), 0, expr.type(), 0, expr.op2(), bv);
}
예제 #28
0
literalt dplib_convt::convert_rest(const exprt &expr)
{
    //dplib_prop.out << "%% E: " << expr << std::endl;

    literalt l=prop.new_variable();

    find_symbols(expr);

    if(expr.id()==ID_equal || expr.id()==ID_notequal)
    {
        assert(expr.operands().size()==2);

        dplib_prop.out << "ASSERT " << dplib_prop.dplib_literal(l) << " <=> (";
        convert_dplib_expr(expr.op0());
        dplib_prop.out << ((expr.id()==ID_equal)?"=":"/=");
        convert_dplib_expr(expr.op1());
        dplib_prop.out << ");" << std::endl;
    }

    return l;
}
예제 #29
0
파일: path_slicer.cpp 프로젝트: olivo/BP
void path_slicert::get_symbols(const exprt &expr, string_sett &s)
{
    if(expr.id()==ID_symbol)
    {
        s.insert(to_symbol_expr(expr).get_identifier());
    }
    else if(expr.id()==ID_index)
    {
        assert(expr.operands().size()==2);
        string_sett tmp;
        get_symbols(expr.op0(), tmp);
        get_symbols(expr.op1(), s);

        for(string_sett::const_iterator
                it=tmp.begin();
                it!=tmp.end();
                it++)
            s.insert(id2string(*it)+"[]");
    }
    else if(expr.id()==ID_member)
    {
        assert(expr.operands().size()==1);

        string_sett tmp;

        get_symbols(expr.op0(), tmp);

        std::string suffix="."+expr.get_string(ID_component_name);

        for(string_sett::const_iterator
                it=tmp.begin();
                it!=tmp.end();
                it++)
            s.insert(id2string(*it)+suffix);
    }
    else
        forall_operands(it, expr)
        get_symbols(*it, s);
}
예제 #30
0
void boolbvt::convert_shift(const exprt &expr, bvt &bv)
{
  if(expr.type().id()!=ID_unsignedbv &&
     expr.type().id()!=ID_signedbv)
    return conversion_failed(expr, bv);

  unsigned width=boolbv_width(expr.type());
  
  if(width==0)
    return conversion_failed(expr, bv);

  if(width==0)
    throw "zero length bit vector type: "+expr.type().to_string();

  if(expr.operands().size()!=2)
    throw "shifting takes two operands";

  bvt op, dist;

  convert_bv(expr.op0(), op);
  convert_bv(expr.op1(), dist);

  if(op.size()!=width)
    throw "convert_shift: unexpected operand width";

  bv_utilst::shiftt shift;

  if(expr.id()==ID_shl)
    shift=bv_utilst::LEFT;
  else if(expr.id()==ID_ashr)
    shift=bv_utilst::ARIGHT;
  else if(expr.id()==ID_lshr)
    shift=bv_utilst::LRIGHT;
  else
    throw "unexpected operand";

  bv=bv_utils.shift(op, shift, dist);
}