Пример #1
0
static bool special_case_operator(compile_t* c, ast_t* ast,
  LLVMValueRef *value, bool short_circuit, bool native128)
{
  AST_GET_CHILDREN(ast, positional, named, postfix);
  AST_GET_CHILDREN(postfix, left, method);

  ast_t* right = ast_child(positional);
  const char* name = ast_name(method);
  *value = NULL;

  if(name == c->str_add)
    *value = gen_add(c, left, right);
  else if(name == c->str_sub)
    *value = gen_sub(c, left, right);
  else if((name == c->str_mul) && native128)
    *value = gen_mul(c, left, right);
  else if((name == c->str_div) && native128)
    *value = gen_div(c, left, right);
  else if((name == c->str_mod) && native128)
    *value = gen_mod(c, left, right);
  else if(name == c->str_neg)
    *value = gen_neg(c, left);
  else if((name == c->str_and) && short_circuit)
    *value = gen_and_sc(c, left, right);
  else if((name == c->str_or) && short_circuit)
    *value = gen_or_sc(c, left, right);
  else if((name == c->str_and) && !short_circuit)
    *value = gen_and(c, left, right);
  else if((name == c->str_or) && !short_circuit)
    *value = gen_or(c, left, right);
  else if(name == c->str_xor)
    *value = gen_xor(c, left, right);
  else if(name == c->str_not)
    *value = gen_not(c, left);
  else if(name == c->str_shl)
    *value = gen_shl(c, left, right);
  else if(name == c->str_shr)
    *value = gen_shr(c, left, right);
  else if(name == c->str_eq)
    *value = gen_eq(c, left, right);
  else if(name == c->str_ne)
    *value = gen_ne(c, left, right);
  else if(name == c->str_lt)
    *value = gen_lt(c, left, right);
  else if(name == c->str_le)
    *value = gen_le(c, left, right);
  else if(name == c->str_ge)
    *value = gen_ge(c, left, right);
  else if(name == c->str_gt)
    *value = gen_gt(c, left, right);
  else
    return false;

  return true;
}
Пример #2
0
void abstract_expression(
  const predicatest &predicates,
  exprt &expr,
  const namespacet &ns)
{
  if(expr.type().id()!=ID_bool)
    throw "abstract_expression expects expression of type Boolean";

  simplify(expr, ns);

  if(is_valid(expr, ns))
  {
	  // If expr is valid, we can abstract it as 'true'
	  expr.make_true();
  } else if(is_unsatisfiable(expr, ns))
  {
	  // If expr is unsatisfiable, we can abstract it as 'false'
	  expr.make_false();
  } else if(expr.id()==ID_and || expr.id()==ID_or ||
     expr.id()==ID_implies || expr.id()==ID_xor)
  {
    Forall_operands(it, expr)
      abstract_expression(predicates, *it, ns);
  }
  else if(expr.id()==ID_not)
  {
    assert(expr.operands().size()==1);

    abstract_expression(predicates, expr.op0(), ns);

    // remove double negation
    if(expr.op0().id()==ID_not &&
       expr.op0().operands().size()==1)
    {
      exprt tmp;
      tmp.swap(expr.op0().op0());
      expr.swap(tmp);
    }
  }
  else if(expr.id()==ID_if)
  {
    assert(expr.operands().size()==3);
  
    Forall_operands(it, expr)
      abstract_expression(predicates, *it, ns);

    exprt true_expr(ID_and, bool_typet());
    true_expr.copy_to_operands(expr.op0(), expr.op1());
    
    exprt false_expr(ID_and, bool_typet());
    false_expr.copy_to_operands(gen_not(expr.op0()), expr.op2());
    
    exprt or_expr(ID_or, bool_typet());
    or_expr.move_to_operands(true_expr, false_expr);
    
    expr.swap(or_expr);
  }
  else if(expr.id()==ID_equal || expr.id()==ID_notequal)
  {
    if(expr.operands().size()!=2)
      throw expr.id_string()+" takes two operands";

    // Is it equality on Booleans?

    if(expr.op0().type().id()==ID_bool &&
       expr.op1().type().id()==ID_bool)
    {
      // leave it in

      Forall_operands(it, expr)
        abstract_expression(predicates, *it, ns);
    }
    else // other types, make it a predicate
    {
      if(has_non_boolean_if(expr))
      {
        lift_if(expr);
        abstract_expression(predicates, expr, ns);
      }
      else
        make_it_a_predicate(predicates, expr, ns);
    }
  }
  else if(expr.is_constant())
  {
    // leave it as is
  }
  else if(has_non_boolean_if(expr))
  {
    lift_if(expr);
    abstract_expression(predicates, expr, ns);
  }
  else
  {
    make_it_a_predicate(predicates, expr, ns);
  }
}
Пример #3
0
static bool special_case_operator(compile_t* c, ast_t* ast,
  LLVMValueRef *value, bool short_circuit, bool native128)
{
  AST_GET_CHILDREN(ast, postfix, positional, named, question);
  AST_GET_CHILDREN(postfix, left, method);

  ast_t* right = ast_child(positional);
  const char* name = ast_name(method);
  bool special_case = true;
  *value = NULL;

  codegen_debugloc(c, ast);

  if(name == c->str_add)
    *value = gen_add(c, left, right, true);
  else if(name == c->str_sub)
    *value = gen_sub(c, left, right, true);
  else if((name == c->str_mul) && native128)
    *value = gen_mul(c, left, right, true);
  else if((name == c->str_div) && native128)
    *value = gen_div(c, left, right, true);
  else if((name == c->str_rem) && native128)
    *value = gen_rem(c, left, right, true);
  else if(name == c->str_neg)
    *value = gen_neg(c, left, true);
  else if(name == c->str_add_unsafe)
    *value = gen_add(c, left, right, false);
  else if(name == c->str_sub_unsafe)
    *value = gen_sub(c, left, right, false);
  else if((name == c->str_mul_unsafe) && native128)
    *value = gen_mul(c, left, right, false);
  else if((name == c->str_div_unsafe) && native128)
    *value = gen_div(c, left, right, false);
  else if((name == c->str_rem_unsafe) && native128)
    *value = gen_rem(c, left, right, false);
  else if(name == c->str_neg_unsafe)
    *value = gen_neg(c, left, false);
  else if((name == c->str_and) && short_circuit)
    *value = gen_and_sc(c, left, right);
  else if((name == c->str_or) && short_circuit)
    *value = gen_or_sc(c, left, right);
  else if((name == c->str_and) && !short_circuit)
    *value = gen_and(c, left, right);
  else if((name == c->str_or) && !short_circuit)
    *value = gen_or(c, left, right);
  else if(name == c->str_xor)
    *value = gen_xor(c, left, right);
  else if(name == c->str_not)
    *value = gen_not(c, left);
  else if(name == c->str_shl)
    *value = gen_shl(c, left, right, true);
  else if(name == c->str_shr)
    *value = gen_shr(c, left, right, true);
  else if(name == c->str_shl_unsafe)
    *value = gen_shl(c, left, right, false);
  else if(name == c->str_shr_unsafe)
    *value = gen_shr(c, left, right, false);
  else if(name == c->str_eq)
    *value = gen_eq(c, left, right, true);
  else if(name == c->str_ne)
    *value = gen_ne(c, left, right, true);
  else if(name == c->str_lt)
    *value = gen_lt(c, left, right, true);
  else if(name == c->str_le)
    *value = gen_le(c, left, right, true);
  else if(name == c->str_ge)
    *value = gen_ge(c, left, right, true);
  else if(name == c->str_gt)
    *value = gen_gt(c, left, right, true);
  else if(name == c->str_eq_unsafe)
    *value = gen_eq(c, left, right, false);
  else if(name == c->str_ne_unsafe)
    *value = gen_ne(c, left, right, false);
  else if(name == c->str_lt_unsafe)
    *value = gen_lt(c, left, right, false);
  else if(name == c->str_le_unsafe)
    *value = gen_le(c, left, right, false);
  else if(name == c->str_ge_unsafe)
    *value = gen_ge(c, left, right, false);
  else if(name == c->str_gt_unsafe)
    *value = gen_gt(c, left, right, false);
  else
    special_case = false;

  codegen_debugloc(c, NULL);
  return special_case;
}
Пример #4
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);
  }
}