예제 #1
0
void goto_checkt::check_rec(const exprt &expr, guardt &guard, bool address)
{

  if (address)
  {
    if (expr.id() == "dereference")
    {
      assert(expr.operands().size() == 1);
      check_rec(expr.op0(), guard, false);
    }
    else if (expr.id() == "index")
    {
      assert(expr.operands().size() == 2);
      check_rec(expr.op0(), guard, true);
      check_rec(expr.op1(), guard, false);
    }
    else
    {
      forall_operands(it, expr)
        check_rec(*it, guard, true);
    }
    return;
  }

  if (expr.is_address_of())
  {
    assert(expr.operands().size() == 1);
    check_rec(expr.op0(), guard, true);
    return;
  }
  else if (expr.is_and() || expr.id() == "or")
  {
    if (!expr.is_boolean())
      throw expr.id_string() + " must be Boolean, but got " + expr.pretty();

    unsigned old_guards = guard.size();

    for (unsigned i = 0; i < expr.operands().size(); i++)
    {
      const exprt &op = expr.operands()[i];

      if (!op.is_boolean())
        throw expr.id_string() + " takes Boolean operands only, but got "
            + op.pretty();

      check_rec(op, guard, false);

      if (expr.id() == "or")
      {
        exprt tmp(op);
        tmp.make_not();
        expr2tc tmp_expr;
        migrate_expr(tmp, tmp_expr);
        guard.move(tmp_expr);
      }
      else
      {
        expr2tc tmp;
        migrate_expr(op, tmp);
        guard.add(tmp);
      }
    }

    guard.resize(old_guards);

    return;
  }
  else if (expr.id() == "if")
  {
    if (expr.operands().size() != 3)
      throw "if takes three arguments";

    if (!expr.op0().is_boolean())
    {
      std::string msg = "first argument of if must be boolean, but got "
          + expr.op0().to_string();
      throw msg;
    }

    check_rec(expr.op0(), guard, false);

    {
      unsigned old_guard = guard.size();
      expr2tc tmp;
      migrate_expr(expr.op0(), tmp);
      guard.add(tmp);
      check_rec(expr.op1(), guard, false);
      guard.resize(old_guard);
    }

    {
      unsigned old_guard = guard.size();
      exprt tmp(expr.op0());
      tmp.make_not();
      expr2tc tmp_expr;
      migrate_expr(tmp, tmp_expr);
      guard.move(tmp_expr);
      check_rec(expr.op2(), guard, false);
      guard.resize(old_guard);
    }

    return;
  }

  forall_operands(it, expr)
    check_rec(*it, guard, false);

  if (expr.id() == "index")
  {
    bounds_check(expr, guard);
  }
  else if (expr.id() == "/")
  {
    div_by_zero_check(expr, guard);
    if (expr.type().id() == "signedbv")
    {
      overflow_check(expr, guard);
    }
    else if (expr.type().id() == "floatbv")
    {
      nan_check(expr, guard);
    }
  }
  else if (expr.id() == "+" || expr.id() == "-" || expr.id() == "*"
      || expr.id() == "unary-" || expr.id() == "typecast")
  {

    if (expr.type().id() == "signedbv")
    {
      overflow_check(expr, guard);
    }
    else if (expr.type().id() == "floatbv")
    {
      nan_check(expr, guard);
    }
  }
  else if (expr.id() == "<=" || expr.id() == "<" || expr.id() == ">="
      || expr.id() == ">")
  {
    pointer_rel_check(expr, guard);
  }
  else if (expr.id() == "mod")
  {
    div_by_zero_check(expr, guard);
    if (expr.type().id() == "signedbv")
    {
      overflow_check(expr, guard);
    }
    else if (expr.type().id() == "floatbv")
    {
      nan_check(expr, guard);
    }
  }
}
예제 #2
0
void rw_sett::read_write_rec(
  const exprt &expr,
  bool r, bool w,
  const std::string &suffix,
  const guardt &guard)
{
  if(expr.id()=="symbol" && !expr.has_operands())
  {
    const symbol_exprt &symbol_expr=to_symbol_expr(expr);

    const symbolt *symbol;
    if(!ns.lookup(symbol_expr.get_identifier(), symbol))
    {

      if(!symbol->static_lifetime /*&& expr.type().id()=="pointer"*/)
      {
        return; // ignore for now
      }

      if(symbol->name=="c::__ESBMC_alloc" ||
         symbol->name=="c::__ESBMC_alloc_size" ||
         symbol->name=="c::stdin" ||
         symbol->name=="c::stdout" ||
         symbol->name=="c::stderr" ||
         symbol->name=="c::sys_nerr")
      {
        return; // ignore for now
      }
    }

    irep_idt object=id2string(symbol_expr.get_identifier())+suffix;

    entryt &entry=entries[object];
    entry.object=object;
    entry.r=entry.r || r;
    entry.w=entry.w || w;
    entry.guard = migrate_expr_back(guard.as_expr());
  }
  else if(expr.id()=="member")
  {
    assert(expr.operands().size()==1);
    const std::string &component_name=expr.component_name().as_string();
    read_write_rec(expr.op0(), r, w, "."+component_name+suffix, guard);
  }
  else if(expr.id()=="index")
  {
    // we don't distinguish the array elements for now
    assert(expr.operands().size()==2);
    std::string tmp;

    tmp = integer2string(binary2integer(expr.op1().value().as_string(), true),10);

    read_write_rec(expr.op0(), r, w, "["+suffix+tmp+"]", guard);
    read(expr.op1(), guard);
  }
  else if(expr.id()=="dereference")
  {
    assert(expr.operands().size()==1);
    read(expr.op0(), guard);

    exprt tmp(expr.op0());
    expr2tc tmp_expr;
    migrate_expr(tmp, tmp_expr);
    dereference(target, tmp_expr, ns, value_sets);
    tmp = migrate_expr_back(tmp_expr);

    read_write_rec(tmp, r, w, suffix, guard);
  }
  else if(expr.is_address_of() ||
          expr.id()=="implicit_address_of")
  {
    assert(expr.operands().size()==1);

  }
  else if(expr.id()=="if")
  {
    assert(expr.operands().size()==3);
    read(expr.op0(), guard);

    guardt true_guard(guard);
    expr2tc tmp_expr;
    migrate_expr(expr.op0(), tmp_expr);
    true_guard.add(tmp_expr);
    read_write_rec(expr.op1(), r, w, suffix, true_guard);

    guardt false_guard(guard);
    migrate_expr(gen_not(expr.op0()), tmp_expr);
    false_guard.add(tmp_expr);
    read_write_rec(expr.op2(), r, w, suffix, false_guard);
  }
  else
  {
    forall_operands(it, expr)
      read_write_rec(*it, r, w, suffix, guard);
  }
}