Ejemplo n.º 1
0
LLVMValueRef gen_and_assign(struct node *ast)
{
	LLVMValueRef result;

	result = gen_and(ast);
	check_store(result, lvalue(ast->one));

	return result;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
void predicate_image_satqe(
    message_handlert &message_handler,
    const std::vector<exprt> &deref_curr_predicates,
    const std::vector<exprt> &deref_next_predicates,
    const std::list<exprt> &constraints,
    symex_target_equationt &equation,
    const namespacet &ns,
    abstract_transition_relationt &
    abstract_transition_relation)
{
  const std::set<unsigned> &from_predicates=
    abstract_transition_relation.from_predicates;

  const std::set<unsigned> &to_predicates=
    abstract_transition_relation.to_predicates;

  assert(to_predicates.size()!=0);

  // create SAT solver object
  satqe_satcheckt satqe;
  bv_pointerst solver(satqe);

  solver.unbounded_array=boolbvt::U_ALL;
  solver.set_message_handler(message_handler);

  // turn equation into CNF
  equation.convert(solver);

  for(std::set<unsigned>::const_iterator
      it=from_predicates.begin();
      it!=from_predicates.end();
      it++)
  {
    unsigned i=*it;

    literalt li=make_pos(ns, solver, deref_curr_predicates[i]);
    satqe.quantify(li);
  }

  for(std::set<unsigned>::const_iterator
      it=to_predicates.begin();
      it!=to_predicates.end();
      it++)
  {
    unsigned i=*it;

    literalt lo=make_pos(ns, solver, deref_next_predicates[i]);
    satqe.quantify(lo);
  }

  // we want cubes
  cube_sett cube_set;
  satqe.set_cube_set(cube_set);

  // solve it
  switch(solver.dec_solve())
  {
    case decision_proceduret::D_UNSATISFIABLE:
      // OK, this is what we expect
      break;

    default:
      throw "unexpected result from satqe.solve()";
  }

  message_handler.print(9, "Generated "+
      i2string(cube_set.no_insertions())+" cube(s)");

#if 0
  std::cout << cube_set;
#endif

  exprt constraint_cubes_disj = true_exprt();

  // convert the cubes into constraints
  for(cubest::star_mapt::const_iterator
      it=cube_set.star_map.begin();
      it!=cube_set.star_map.end();
      it++)
  {
    for(cubest::bitssett::const_iterator
        it2=it->second.begin();
        it2!=it->second.end();
        it2++)
    {
      exprt constraint_cube_conj;

      unsigned bit=0;
      unsigned i=0;

      /* Assume it->first[i] is true iff the i-th predicate is in the
         cube. Assume predicates are stored in it->first in the order of
         from_predicates followed by to_predicates. Scan it->first and
         from/to_predicates in parallel to get the cube. */

      for(std::set<unsigned>::const_iterator
          it3=from_predicates.begin();
          it3!=from_predicates.end();
          it3++)
      {
        unsigned id=*it3;

        if(!it->first[i])
        {
          constraint_cube_conj.operands().push_back(exprt());
          exprt &e=constraint_cube_conj.operands().back();
          e=exprt(ID_predicate_symbol, typet(ID_bool));
          e.set(ID_identifier, id);

          if(!(*it2)[bit]) 
            e.make_not();

          bit++;
#if 0
          std::cout << "C: " << from_expr(ns, "", e) << std::endl;
#endif
        }

        i++;
      }

      for(std::set<unsigned>::const_iterator
          it3=to_predicates.begin();
          it3!=to_predicates.end();
          it3++)
      {
        unsigned id=*it3;

        if(!it->first[i])
        {
          constraint_cube_conj.operands().push_back(exprt());
          exprt &e=constraint_cube_conj.operands().back();
          e=exprt(ID_predicate_next_symbol, typet(ID_bool));
          e.set(ID_identifier, id);

          if(!(*it2)[bit]) 
            e.make_not();

          bit++;
#if 0
          std::cout << "C: " << from_expr(ns, "", e) << std::endl;
#endif
        }

        i++;
      }

      assert(i==it->first.size());

      /* Convert the cube into a conjunct. */
      gen_and(constraint_cube_conj);

      /* Add the conjunct in disjunction to previous cubes. */
      if(constraint_cubes_disj.is_true())
        constraint_cubes_disj=constraint_cube_conj;
      else
        constraint_cubes_disj=gen_or(
            constraint_cubes_disj,
            constraint_cube_conj);      
    }
  }

  /* Add the cubes to the contraints of the abstract transition
     relation. Warning: we may want to remove old constrains. */

  abstract_transition_relation.constraints.push_back(constraint_cubes_disj);
}
Ejemplo n.º 4
0
bool transition_refinert::check_guarded_transition(
  const predicatest &predicates,
  const abstract_stept &abstract_state_from,
  unsigned passive_id,
  bool &inconsistent_initial_state)
{
  // get the concrete basic block
  const goto_programt::instructiont &c_instruction=
    *abstract_state_from.pc->code.concrete_pc;

  if (!c_instruction.is_goto() &&
      !c_instruction.is_assume())
    return false; // whatever

  // this is the original guard
  exprt guard=c_instruction.guard; 

  if(guard.is_true()) // boring
    return false;

  // we might need to negate it if the branch was not taken
  if (c_instruction.is_goto() && 
      !abstract_state_from.branch_taken)
    guard.make_not();

  abstract_transition_relationt &abstract_transition_relation=
    abstract_state_from.pc->code.get_transition_relation();

  #ifdef SATCHECK_MINISAT2
  satcheck_minisat_no_simplifiert satcheck;
  #else
  satcheckt satcheck;
  #endif
  bv_pointerst solver(concrete_model.ns, satcheck);
  solver.unbounded_array=boolbvt::U_NONE;

  // Note that we take "thread_nr" from "abstract_state_from", not from "abstract_state_to", as the "from" state determines which thread is executing
  const unsigned active_id=abstract_state_from.thread_nr;
  const unsigned num_threads=abstract_state_from.thread_states.size();

  std::vector<predicatest> active_passive_preds(num_threads, predicatest());

  for(unsigned int t=0; t < num_threads; ++t)
  {
    if(active_id!=t &&
        passive_id < num_threads &&
        t!=passive_id)
      continue;

    for(unsigned int i = 0; i < predicates.size(); i++)
    {
      active_passive_preds[t].lookup(active_id==t?
          predicates[i] :
          predicatest::make_expr_passive(predicates[i], concrete_model.ns, t));
    }
    assert(active_passive_preds[t].size() == predicates.size());
  }

  std::vector<std::vector<literalt> >
    predicate_variables_from(num_threads, std::vector<literalt>(predicates.size(), literalt()));
    
  bvt assumptions;

  std::vector<abstract_stept::thread_to_predicate_valuest::const_iterator>
    from_predicates(num_threads, abstract_state_from.thread_states.end());
  for(unsigned int t=0; t < num_threads; ++t)
  {
    from_predicates[t]=abstract_state_from.thread_states.find(t);
    assert(abstract_state_from.thread_states.end() != from_predicates[t]);
  }

  // we use all predicates in order to also find constraints over invalid
  // from states
  for(unsigned i=0; i < predicates.size(); ++i)
  {
    for(unsigned int t=0; t < num_threads; ++t)
    {
      if(active_id!=t &&
          passive_id < num_threads &&
          t!=passive_id)
        continue;
      // not sure whether we really want the following check
      if(active_id!=t &&
        active_passive_preds[t][i]==predicates[i])
        continue;

      literalt li=make_pos(concrete_model.ns, solver, active_passive_preds[t][i]);
      predicate_variables_from[t][i]=li;

      assumptions.push_back(li.cond_negation(
            !from_predicates[t]->second[i]));

      #ifdef DEBUG
      const std::string predname=
        (active_id==t?"P#":"PP"+i2string(t)+"#")+i2string(i);
      std::cerr
        << "G-F: " << predname << ": "
        << (from_predicates[t]->second[i]?"":"!") << "("
        << from_expr(concrete_model.ns, "", active_passive_preds[t][i]) << ")" << std::endl;
      #endif
    }
  }
  
  satcheck.set_assumptions(assumptions);

  if(!is_satisfiable(solver))
  {
    if(passive_id >= num_threads)
    {
      const std::string opt="Invalid states requiring more than 1 passive thread";
      assert(stats.find(opt)!=stats.end());
      ++(stats[opt].val);
    }
    inconsistent_initial_state = true;
    print(9, "Guarded transition spurious due to invalid abstract state");
    return false; // this has to be fixed in the respective assignment
  }

  // now add the guard
  solver.set_to_true(guard);

  // solve it incrementally
  if(is_satisfiable(solver))
  {
    print(9, "Transition is OK");
    #ifdef DEBUG
    std::cout << "********\n";
    solver.print_assignment(std::cout);
    std::cout << "********\n";
    #endif
    return false; // ok
  }

  if(passive_id >= num_threads)
  {
    const std::string opt="Spurious guard transitions requiring more than 1 passive thread";
    assert(stats.find(opt)!=stats.end());
    ++(stats[opt].val);
    return false; // can't do anything
  }

  print(9, "Guarded transition is spurious, refining");

  exprt condition;

  for(unsigned i=0; i < predicates.size(); ++i)
  {
    if(satcheck.is_in_conflict(predicate_variables_from[active_id][i]))
    {
      condition.operands().push_back(exprt());
      exprt &e=condition.operands().back();
      e=exprt(ID_predicate_symbol, bool_typet());
      e.set(ID_identifier, i);
      if(!from_predicates[active_id]->second[i]) e.make_not();
      #ifdef DEBUG
      std::cout << "G-C: " << from_expr(concrete_model.ns, "", e) << std::endl;
      #endif
    }

    if(passive_id!=active_id &&
        satcheck.is_in_conflict(predicate_variables_from[passive_id][i]))
    {
      condition.operands().push_back(exprt());
      exprt &e=condition.operands().back();
      e=exprt(ID_predicate_passive_symbol, bool_typet());
      e.set(ID_identifier, i);
      if(!from_predicates[passive_id]->second[i]) e.make_not();
#ifdef DEBUG
      std::cout << "G-C-F: " << from_expr(concrete_model.ns, "", e) << std::endl;
#endif
    }
  }

  gen_and(condition);

  if(c_instruction.is_goto())
  {  
    bool neg=abstract_state_from.branch_taken;
    constrain_goto_transition(abstract_transition_relation, condition, neg);
  }
  else
  {
    assert(c_instruction.is_assume());
    constrain_assume_transition(abstract_transition_relation, condition);
  }

  // spurious
  return true;
}
Ejemplo n.º 5
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;
}