コード例 #1
0
ファイル: equality_domain.cpp プロジェクト: diffblue/2ls
void equality_domaint::project_on_vars(
  valuet &value,
  const var_sett &vars,
  exprt &result)
{
#if 0
  if(templ.size()==0)
    return domaint::project_on_vars(value, vars, result);
#endif

  equ_valuet &v=static_cast<equ_valuet &>(value);

  exprt::operandst c;
  for(unsigned index=0; index<templ.size(); index++)
  {
    const var_pairt &vv=templ[index].var_pair;

#if 0
    std::cout << vv.second << std::endl;
#endif
    if(vars.find(vv.first)==vars.end() ||
       (vars.find(vv.second)==vars.end() &&
        !(vv.second.id()==ID_constant &&
          to_constant_expr(vv.second).get_value()=="NULL")))
      continue;

    if(v.equs.same_set(vv.first, vv.second))
    {
      if(templ[index].kind==LOOP)
        c.push_back(
          implies_exprt(
            templ[index].pre_guard,
            equal_exprt(vv.first, vv.second)));
      else
        c.push_back(equal_exprt(vv.first, vv.second));
    }
  }

  for(index_sett::const_iterator it=v.disequs.begin();
      it!=v.disequs.end(); it++)
  {
    const var_pairt &vv=templ[*it].var_pair;

    if(vars.find(vv.first)==vars.end() ||
       (vars.find(vv.second)==vars.end() &&
        !(vv.second.id()==ID_constant &&
          to_constant_expr(vv.second).get_value()=="NULL")))
      continue;

    if(templ[*it].kind==LOOP)
      c.push_back(
        implies_exprt(
          templ[*it].pre_guard,
          notequal_exprt(vv.first, vv.second)));
    else
      c.push_back(notequal_exprt(vv.first, vv.second));
  }
  result=conjunction(c);
}
コード例 #2
0
ファイル: memory_model_sc.cpp プロジェクト: diffblue/cbmc
void memory_model_sct::write_serialization_external(
  symex_target_equationt &equation)
{
  for(address_mapt::const_iterator
      a_it=address_map.begin();
      a_it!=address_map.end();
      a_it++)
  {
    const a_rect &a_rec=a_it->second;

    // This is quadratic in the number of writes
    // per address. Perhaps some better encoding
    // based on 'places'?
    for(event_listt::const_iterator
        w_it1=a_rec.writes.begin();
        w_it1!=a_rec.writes.end();
        ++w_it1)
    {
      event_listt::const_iterator next=w_it1;
      ++next;

      for(event_listt::const_iterator w_it2=next;
          w_it2!=a_rec.writes.end();
          ++w_it2)
      {
        // external?
        if((*w_it1)->source.thread_nr==
           (*w_it2)->source.thread_nr)
          continue;

        // ws is a total order, no two elements have the same rank
        // s -> w_evt1 before w_evt2; !s -> w_evt2 before w_evt1

        symbol_exprt s=nondet_bool_symbol("ws-ext");

        // write-to-write edge
        add_constraint(
          equation,
          implies_exprt(s, before(*w_it1, *w_it2)),
          "ws-ext",
          (*w_it1)->source);

        add_constraint(
          equation,
          implies_exprt(not_exprt(s), before(*w_it2, *w_it1)),
          "ws-ext",
          (*w_it1)->source);
      }
    }
  }
}
コード例 #3
0
ファイル: predabs_domain.cpp プロジェクト: diffblue/2ls
/// post_guard=> (row_value=> row_expr)
exprt predabs_domaint::get_row_post_constraint(
  const rowt &row,
  const row_valuet &row_value)
{
  assert(row<templ.size());
  const template_rowt &templ_row=templ[row];
  if(templ_row.kind==IN)
    return true_exprt();
  exprt c=implies_exprt(
    templ_row.post_guard,
    implies_exprt(row_value, templ[row].expr));
  if(templ_row.kind==LOOP)
    rename(c);
  return c;
}
コード例 #4
0
ファイル: equality_domain.cpp プロジェクト: diffblue/2ls
void equality_domaint::make_not_post_constraints(
  valuet &_value,
  exprt::operandst &cond_exprs)
{
  assert(*e_it<templ.size());
  cond_exprs.resize(1);
  if(check_dis)
  {
    cond_exprs[0]=get_post_not_disequ_constraint(*e_it);
    return;
  }
  const template_rowt &templ_row=templ[*e_it];
  if(templ_row.kind==IN)
  {
    cond_exprs[0]=true_exprt();
    return;
  }

  const var_pairt &vv=templ_row.var_pair;
  exprt c=
    and_exprt(
      templ_row.aux_expr,
      not_exprt(
        implies_exprt(
          templ_row.post_guard,
          equal_exprt(vv.first, vv.second))));
  rename(c);
  cond_exprs[0]=c;
}
コード例 #5
0
ファイル: summarizer_bw.cpp プロジェクト: AnnaTrost/2ls
void summarizer_bwt::collect_postconditions(
  const function_namet &function_name,
  const local_SSAt &SSA, 
  const summaryt &summary,
  exprt::operandst &postconditions,
  bool sufficient)
{
  for(local_SSAt::nodest::const_iterator n_it = SSA.nodes.begin();
      n_it != SSA.nodes.end(); n_it++)
  {
    for(local_SSAt::nodet::assertionst::const_iterator 
	  a_it = n_it->assertions.begin();
	a_it != n_it->assertions.end(); a_it++)
    {
      postconditions.push_back(*a_it);
    }
  }
  /*  if(termination) 
  {
    if(!summary.termination_argument.is_nil()) 
      postconditions.push_back(summary.termination_argument);
      }*/

  exprt guard = SSA.guard_symbol(--SSA.goto_function.body.instructions.end());
  if(!sufficient) 
    postconditions.push_back(and_exprt(guard,summary.bw_postcondition));
  else
    postconditions.push_back(implies_exprt(guard,summary.bw_postcondition));
}
コード例 #6
0
ファイル: summarizer_fw_term.cpp プロジェクト: diffblue/2ls
void summarizer_fw_termt::do_nontermination(
  const function_namet &function_name,
  local_SSAt &SSA,
  summaryt &summary)
{
  // calling context, invariant, function call summaries
  exprt::operandst cond;
  if(!summary.fw_invariant.is_nil())
    cond.push_back(summary.fw_invariant);
  if(!summary.fw_precondition.is_nil())
    cond.push_back(summary.fw_precondition);
  cond.push_back(ssa_inliner.get_summaries(SSA));

  if(!check_end_reachable(function_name, SSA, conjunction(cond)))
  {
    status() << "Function never terminates normally" << eom;

    if(summary.fw_precondition.is_true())
      summary.fw_transformer=false_exprt();
    else
      summary.fw_transformer=
        implies_exprt(summary.fw_precondition, false_exprt());

    summary.terminates=NO;
  }
}
コード例 #7
0
ファイル: predabs_domain.cpp プロジェクト: diffblue/2ls
/// /\_all_rows ( pre_guard==> (row_value=> row_expr) )
exprt predabs_domaint::to_pre_constraints(valuet &_value)
{
  assert(*e_it<templ.size());
  const template_rowt &templ_row=templ[*e_it];
  kindt k=templ_row.kind;
  if(k==OUT || k==OUTL)
    return true_exprt();
  return implies_exprt(true_exprt(), templ[*e_it].expr);
}
コード例 #8
0
ファイル: local_ssa.cpp プロジェクト: AnnaTrost/deltacheck
void local_SSAt::build_assertions(locationt loc)
{
  if(loc->is_assert())
  {
    exprt c=read_rhs(loc->guard, loc);
    exprt g=guard_symbol(loc);    
    nodes[loc].assertion=implies_exprt(g, c);
  }
}
コード例 #9
0
ファイル: equality_domain.cpp プロジェクト: diffblue/2ls
exprt equality_domaint::get_pre_equ_constraint(unsigned index)
{
  assert(index<templ.size());
  const template_rowt &templ_row=templ[index];
  if(templ_row.kind==OUT || templ_row.kind==OUTL)
    return true_exprt();

  const var_pairt &vv=templ_row.var_pair;
  return implies_exprt(templ_row.pre_guard, equal_exprt(vv.first, vv.second));
}
コード例 #10
0
ファイル: predabs_domain.cpp プロジェクト: diffblue/2ls
/// pre_guard==> (row_value=> row_expr)
exprt predabs_domaint::get_row_constraint(
  const rowt &row,
  const row_valuet &row_value)
{
  assert(row<templ.size());
  kindt k=templ[row].kind;
  if(k==OUT || k==OUTL)
    return true_exprt();
  return implies_exprt(row_value, templ[row].expr);
}
コード例 #11
0
ファイル: predabs_domain.cpp プロジェクト: diffblue/2ls
void predabs_domaint::project_on_vars(
  valuet &value,
  const var_sett &vars,
  exprt &result)
{
  const templ_valuet &v=static_cast<const templ_valuet &>(value);

  assert(v.size()==templ.size());
  exprt::operandst c;
  for(std::size_t row=0; row<templ.size(); row++)
  {
    const template_rowt &templ_row=templ[row];

    std::set<symbol_exprt> symbols;
    find_symbols(templ_row.expr, symbols);

    bool pure=true;
    for(const auto &symbol : symbols)
    {
      if(vars.find(symbol)==vars.end())
      {
        pure=false;
        break;
      }
    }
    if(!pure)
      continue;

    const row_valuet &row_v=v[row];
    if(templ_row.kind==LOOP)
    {
      c.push_back(
        implies_exprt(
          templ_row.pre_guard,
          implies_exprt(row_v, templ_row.expr)));
    }
    else
    {
      c.push_back(implies_exprt(row_v, templ_row.expr));
    }
  }
  result=conjunction(c);
}
コード例 #12
0
ファイル: equality_domain.cpp プロジェクト: diffblue/2ls
exprt equality_domaint::to_pre_constraints(valuet &_value)
{
  if(check_dis)
    return get_pre_disequ_constraint(*e_it);
  assert(*e_it<templ.size());
  const template_rowt &templ_row=templ[*e_it];
  if(templ_row.kind==OUT || templ_row.kind==OUTL)
    return true_exprt();

  const var_pairt &vv=templ_row.var_pair;
  return implies_exprt(templ_row.pre_guard, equal_exprt(vv.first, vv.second));
}
コード例 #13
0
ファイル: polynomial_accelerator.cpp プロジェクト: bkolb/cbmc
exprt polynomial_acceleratort::precondition(patht &path) {
  exprt ret = false_exprt();

  for (patht::reverse_iterator r_it = path.rbegin();
       r_it != path.rend();
       ++r_it) {
    goto_programt::const_targett t = r_it->loc;

    if (t->is_assign()) {
      // XXX Need to check for aliasing...
      const code_assignt &assignment = to_code_assign(t->code);
      const exprt &lhs = assignment.lhs();
      const exprt &rhs = assignment.rhs();

      if (lhs.id() == ID_symbol) {
        replace_expr(lhs, rhs, ret);
      } else if (lhs.id() == ID_index ||
                 lhs.id() == ID_dereference) {
        continue;
      } else {
        throw "Couldn't take WP of " + expr2c(lhs, ns) + " = " + expr2c(rhs, ns);
      }
    } else if (t->is_assume() || t->is_assert()) {
      ret = implies_exprt(t->guard, ret);
    } else {
      // Ignore.
    }

    if (!r_it->guard.is_true() && !r_it->guard.is_nil()) {
      // The guard isn't constant true, so we need to accumulate that too.
      ret = implies_exprt(r_it->guard, ret);
    }
  }

  simplify(ret, ns);

  return ret;
}
コード例 #14
0
ファイル: summarizer_fw_term.cpp プロジェクト: diffblue/2ls
void summarizer_fw_termt::do_termination(
  const function_namet &function_name,
  local_SSAt &SSA,
  summaryt &summary)
{
  // calling context, invariant, function call summaries
  exprt::operandst cond;
  if(!summary.fw_invariant.is_nil())
    cond.push_back(summary.fw_invariant);
  if(!summary.fw_precondition.is_nil())
    cond.push_back(summary.fw_precondition);
  cond.push_back(ssa_inliner.get_summaries(SSA));

  status() << "Synthesizing ranking function to prove termination" << eom;
  // solver
  incremental_solvert &solver=ssa_db.get_solver(function_name);
  solver.set_message_handler(get_message_handler());

  template_generator_rankingt template_generator1(
    options, ssa_db, ssa_unwinder.get(function_name));
  template_generator1.set_message_handler(get_message_handler());
  template_generator1(solver.next_domain_number(), SSA, true);

  if(template_generator1.all_vars().empty())
    return; // nothing to do

  get_assertions(SSA, cond); // add assertions as assumptions

  // compute ranking functions
  ssa_analyzert analyzer1;
  analyzer1.set_message_handler(get_message_handler());
  analyzer1(solver, SSA, conjunction(cond), template_generator1);
  analyzer1.get_result(
    summary.termination_argument, template_generator1.all_vars());

  // extract information whether a ranking function was found for all loops
  summary.terminates=check_termination_argument(summary.termination_argument);
  if(!summary.fw_precondition.is_true())
    summary.termination_argument=
      implies_exprt(summary.fw_precondition, summary.termination_argument);

  // statistics
  solver_instances+=analyzer1.get_number_of_solver_instances();
  solver_calls+=analyzer1.get_number_of_solver_calls();
  termargs_computed++;
}
コード例 #15
0
ファイル: equality_domain.cpp プロジェクト: diffblue/2ls
exprt equality_domaint::get_post_not_disequ_constraint(unsigned index)
{
  assert(index<templ.size());
  const template_rowt &templ_row=templ[index];
  if(templ_row.kind==IN)
    return true_exprt();

  const var_pairt &vv=templ_row.var_pair;
  exprt c=
    and_exprt(
      templ_row.aux_expr,
      not_exprt(
        implies_exprt(
          templ_row.post_guard,
          notequal_exprt(vv.first, vv.second))));
  rename(c);
  return c;
}
コード例 #16
0
ファイル: summarizer_fw.cpp プロジェクト: kumarmadhukar/2ls
void summarizer_fwt::do_summary(const function_namet &function_name, 
				local_SSAt &SSA,
				summaryt &summary,
				exprt cond,
				bool context_sensitive)
{
  status() << "Computing summary" << eom;

  // solver
  incremental_solvert &solver = ssa_db.get_solver(function_name);
  solver.set_message_handler(get_message_handler());

  //analyze
  ssa_analyzert analyzer;
  analyzer.set_message_handler(get_message_handler());

  template_generator_summaryt template_generator(
    options,ssa_db,ssa_unwinder.get(function_name));
  template_generator.set_message_handler(get_message_handler());
  template_generator(solver.next_domain_number(),SSA,true);

  exprt::operandst conds;
  conds.reserve(5);
  conds.push_back(cond);
  conds.push_back(summary.fw_precondition);
  conds.push_back(ssa_inliner.get_summaries(SSA));

#ifdef REUSE_INVARIANTS
  if(summary_db.exists(function_name)) //reuse existing invariants
  {
    const exprt &old_inv = summary_db.get(function_name).fw_invariant;
    exprt inv = ssa_unwinder.get(function_name).rename_invariant(old_inv);
    conds.push_back(inv);

#if 0
    std::ostringstream out;
    out << "(original inv)" << from_expr(SSA.ns,"",old_inv) << "\n";
    debug() << out.str() << eom;
    out << "(renamed inv)" << from_expr(SSA.ns,"",inv)<<"\n";
    debug() << out.str() << eom;
#endif
  }
#endif

  cond = conjunction(conds);

  bool assertions_check = false; //options.get_bool_option("k-induction");
  bool assertions_hold = analyzer(solver,SSA,cond,template_generator,
                                  assertions_check);
  if(assertions_hold)
  {
    analyzer.get_result(summary.fw_transformer,template_generator.inout_vars());
    analyzer.get_result(summary.fw_invariant,template_generator.loop_vars());

#ifdef SHOW_WHOLE_RESULT
    // to see all the custom template values
    exprt whole_result;
    analyzer.get_result(whole_result,template_generator.all_vars());
    debug() << "whole result: " << from_expr(SSA.ns,"",whole_result) << eom;
#endif

    if(context_sensitive && !summary.fw_precondition.is_true())
    {
      summary.fw_transformer = 
	implies_exprt(summary.fw_precondition,summary.fw_transformer);
      summary.fw_invariant = 
	implies_exprt(summary.fw_precondition,summary.fw_invariant);
    }
  }
  else //!assertions_hold
  {
    nonpassed_assertions = true; 
    summary.nonpassed_assertions = analyzer.get_nonpassed_assertions();
  }

  solver_instances += analyzer.get_number_of_solver_instances();
  solver_calls += analyzer.get_number_of_solver_calls();
}
コード例 #17
0
ファイル: memory_model_sc.cpp プロジェクト: diffblue/cbmc
void memory_model_sct::from_read(symex_target_equationt &equation)
{
  // from-read: (w', w) in ws and (w', r) in rf -> (r, w) in fr

  for(address_mapt::const_iterator
      a_it=address_map.begin();
      a_it!=address_map.end();
      a_it++)
  {
    const a_rect &a_rec=a_it->second;

    // This is quadratic in the number of writes per address.
    for(event_listt::const_iterator
        w_prime=a_rec.writes.begin();
        w_prime!=a_rec.writes.end();
        ++w_prime)
    {
      event_listt::const_iterator next=w_prime;
      ++next;

      for(event_listt::const_iterator w=next;
          w!=a_rec.writes.end();
          ++w)
      {
        exprt ws1, ws2;

        if(po(*w_prime, *w) &&
           !program_order_is_relaxed(*w_prime, *w))
        {
          ws1=true_exprt();
          ws2=false_exprt();
        }
        else if(po(*w, *w_prime) &&
                !program_order_is_relaxed(*w, *w_prime))
        {
          ws1=false_exprt();
          ws2=true_exprt();
        }
        else
        {
          ws1=before(*w_prime, *w);
          ws2=before(*w, *w_prime);
        }

        // smells like cubic
        for(choice_symbolst::const_iterator
            c_it=choice_symbols.begin();
            c_it!=choice_symbols.end();
            c_it++)
        {
          event_it r=c_it->first.first;
          exprt rf=c_it->second;
          exprt cond;
          cond.make_nil();

          if(c_it->first.second==*w_prime && !ws1.is_false())
          {
            exprt fr=before(r, *w);

            // the guard of w_prime follows from rf; with rfi
            // optimisation such as the previous write_symbol_primed
            // it would even be wrong to add this guard
            cond=
              implies_exprt(
                and_exprt(r->guard, (*w)->guard, ws1, rf),
                fr);
          }
          else if(c_it->first.second==*w && !ws2.is_false())
          {
            exprt fr=before(r, *w_prime);

            // the guard of w follows from rf; with rfi
            // optimisation such as the previous write_symbol_primed
            // it would even be wrong to add this guard
            cond=
              implies_exprt(
                and_exprt(r->guard, (*w_prime)->guard, ws2, rf),
                fr);
          }

          if(cond.is_not_nil())
            add_constraint(equation,
              cond, "fr", r->source);
        }

      }
    }
  }
}
コード例 #18
0
ファイル: summarizer_bw_term.cpp プロジェクト: diffblue/2ls
void summarizer_bw_termt::do_summary_term(
  const function_namet &function_name,
  local_SSAt &SSA,
  const summaryt &old_summary,
  summaryt &summary,
  bool context_sensitive)
{
  status() << "Computing preconditions for termination" << eom;

  // solver
  incremental_solvert &solver=ssa_db.get_solver(function_name);
  solver.set_message_handler(get_message_handler());

  // templates for ranking functions
  template_generator_rankingt template_generator1(
    options, ssa_db, ssa_unwinder.get(function_name));
  template_generator1.set_message_handler(get_message_handler());
  template_generator1(solver.next_domain_number(), SSA, true);

  // templates for backward summary
  template_generator_summaryt template_generator2(
    options, ssa_db, ssa_unwinder.get(function_name));
  template_generator2.set_message_handler(get_message_handler());
  template_generator2(solver.next_domain_number(), SSA, false);

  exprt::operandst bindings;
  exprt::operandst postcond;
  // backward summaries
  ssa_inliner.get_summaries(SSA, false, postcond, bindings);
  collect_postconditions(function_name, SSA, summary, postcond, true);

  // prepare solver
  solver << SSA;
  solver.new_context();
  solver << SSA.get_enabling_exprs();
  solver << old_summary.fw_precondition;
  solver << old_summary.fw_invariant;
  solver << ssa_inliner.get_summaries(SSA); // forward summaries
  solver << conjunction(bindings); // bindings for backward summaries

#if 0
  // compute preconditions individually
  // TODO: this should be done more transparently
  for(unsigned i=0; i<postcond.size(); i++)
  {
    exprt::operandst postcond2;
    postcond2.push_back(postcond[i]);
    compute_precondition(
      SSA, summary, postcond2, solver, template_generator2, context_sensitive);
  }
  postcond.clear();
#endif

  if(template_generator1.all_vars().empty())
  {
    compute_precondition(
      SSA, summary, postcond, solver, template_generator2, context_sensitive);
    solver.pop_context();
    return;
  }

  summary.bw_precondition=false_exprt(); // initialize
  unsigned number_disjuncts=0;
  while(number_disjuncts++<MAX_PRECONDITION_DISJUNCTS)
  {
    // bootstrap preconditions
    exprt termination_argument;
    if(!bootstrap_preconditions(
         SSA,
         summary,
         solver,
         template_generator1,
         template_generator2,
         termination_argument))
    {
      break;
    }

    // compute precondition
    // compute for individual termination arguments separately
    // TODO: this should be done more transparently
    if(termination_argument.id()==ID_and)
    {
      for(unsigned i=0; i<termination_argument.operands().size(); i++)
      {
        postcond.push_back(termination_argument.operands()[i]);

        exprt precondition=
          compute_precondition(
            SSA,
            summary,
            postcond,
            solver,
            template_generator2,
            context_sensitive);

        // join results
        if(summary.termination_argument.is_nil())
        {
          summary.termination_argument=
            implies_exprt(precondition, termination_argument);
        }
        else
        {
          summary.termination_argument=
            and_exprt(
              summary.termination_argument,
              implies_exprt(precondition, termination_argument));
        }

        // TODO: this is a bit asymmetric:
        //  the first precondition is joined with all other sources
        //  of non-termination (calls, bw calling context)
        postcond.clear();
      }
    }
    else // do not split termination arguments
    {
      postcond.push_back(termination_argument);
      exprt precondition=
        compute_precondition(
          SSA,
          summary,
          postcond,
          solver,
          template_generator2,
          context_sensitive);

      // join results
      if(summary.termination_argument.is_nil())
      {
        summary.termination_argument=
          implies_exprt(precondition, termination_argument);
      }
      else
      {
        summary.termination_argument=
          and_exprt(
            summary.termination_argument,
            implies_exprt(precondition, termination_argument));
      }

      // TODO: this is a bit asymmetric:
      //  the first precondition is joined with all other sources
      //  of non-termination (calls, bw calling context)
      postcond.clear();
    }
  }

  solver.pop_context();
}
コード例 #19
0
ファイル: goto_check.cpp プロジェクト: diffblue/cbmc
void goto_checkt::pointer_validity_check(
  const dereference_exprt &expr,
  const guardt &guard)
{
  if(!enable_pointer_check)
    return;

  const exprt &pointer=expr.op0();
  const typet &pointer_type=to_pointer_type(ns.follow(pointer.type()));

  assert(base_type_eq(pointer_type.subtype(), expr.type(), ns));

  local_bitvector_analysist::flagst flags=
    local_bitvector_analysis->get(t, pointer);

  const typet &dereference_type=pointer_type.subtype();

  // For Java, we only need to check for null
  if(mode==ID_java)
  {
    if(flags.is_unknown() || flags.is_null())
    {
      notequal_exprt not_eq_null(pointer, gen_zero(pointer.type()));

      add_guarded_claim(
        not_eq_null,
        "reference is null",
        "pointer dereference",
        expr.find_source_location(),
        expr,
        guard);
    }
  }
  else
  {
    if(flags.is_unknown() || flags.is_null())
    {
      add_guarded_claim(
        not_exprt(null_pointer(pointer)),
        "dereference failure: pointer NULL",
        "pointer dereference",
        expr.find_source_location(),
        expr,
        guard);
    }

    if(flags.is_unknown())
      add_guarded_claim(
        not_exprt(invalid_pointer(pointer)),
        "dereference failure: pointer invalid",
        "pointer dereference",
        expr.find_source_location(),
        expr,
        guard);

    if(flags.is_uninitialized())
      add_guarded_claim(
        not_exprt(invalid_pointer(pointer)),
        "dereference failure: pointer uninitialized",
        "pointer dereference",
        expr.find_source_location(),
        expr,
        guard);

    if(mode != ID_java)
    {
      if(flags.is_unknown() || flags.is_dynamic_heap())
        add_guarded_claim(
          not_exprt(deallocated(pointer, ns)),
          "dereference failure: deallocated dynamic object",
          "pointer dereference",
          expr.find_source_location(),
          expr,
          guard);

      if(flags.is_unknown() || flags.is_dynamic_local())
        add_guarded_claim(
          not_exprt(dead_object(pointer, ns)),
          "dereference failure: dead object",
          "pointer dereference",
          expr.find_source_location(),
          expr,
          guard);
    }

    if(enable_bounds_check)
    {
      if(flags.is_unknown() || flags.is_dynamic_heap())
      {
        exprt dynamic_bounds=
          or_exprt(dynamic_object_lower_bound(pointer),
                   dynamic_object_upper_bound(pointer, dereference_type, ns));

        add_guarded_claim(
          implies_exprt(malloc_object(pointer, ns), not_exprt(dynamic_bounds)),
          "dereference failure: dynamic object bounds",
          "pointer dereference",
          expr.find_source_location(),
          expr,
          guard);
      }
    }

    if(enable_bounds_check)
    {
      if(flags.is_unknown() ||
         flags.is_dynamic_local() ||
         flags.is_static_lifetime())
      {
        exprt object_bounds=
          or_exprt(object_lower_bound(pointer),
                   object_upper_bound(pointer, dereference_type, ns));

        add_guarded_claim(
          or_exprt(dynamic_object(pointer), not_exprt(object_bounds)),
          "dereference failure: object bounds",
          "pointer dereference",
          expr.find_source_location(),
          expr,
          guard);
      }
    }
  }
}
コード例 #20
0
ファイル: summarizer_bw_term.cpp プロジェクト: diffblue/2ls
exprt summarizer_bw_termt::compute_precondition(
  local_SSAt &SSA,
  summaryt &summary,
  const exprt::operandst &postconditions,
  incremental_solvert &solver,
  template_generator_summaryt &template_generator,
  bool context_sensitive)
{
  exprt postcond=not_exprt(conjunction(postconditions));

  // compute backward summary
  exprt bw_transformer, bw_invariant, bw_precondition;
  if(!template_generator.out_vars().empty())
  {
    ssa_analyzert analyzer;
    analyzer.set_message_handler(get_message_handler());
    analyzer(solver, SSA, postcond, template_generator);
    analyzer.get_result(bw_transformer, template_generator.inout_vars());
    analyzer.get_result(bw_invariant, template_generator.loop_vars());
    analyzer.get_result(bw_precondition, template_generator.out_vars());

    // statistics
    solver_instances+=analyzer.get_number_of_solver_instances();
    solver_calls+=analyzer.get_number_of_solver_calls();
  }
#if 1
  // TODO: yet another workaround for ssa_analyzer
  //  not being able to handle empty templates properly
  else
  {
    solver << SSA;
    solver.new_context();
    solver << SSA.get_enabling_exprs();
    solver << postcond;
    exprt result=true_exprt();
    if(solver()==decision_proceduret::D_UNSATISFIABLE)
      result=false_exprt();
    solver.pop_context();
    bw_transformer=result;
    bw_invariant=result;
    bw_precondition=result;
  }
#endif

  bw_transformer=not_exprt(bw_transformer);
  bw_invariant=not_exprt(bw_invariant);
  bw_precondition=not_exprt(bw_precondition);

  if(context_sensitive && !summary.bw_postcondition.is_true())
  {
    bw_transformer=implies_exprt(summary.bw_postcondition, bw_transformer);
    bw_invariant=implies_exprt(summary.bw_postcondition, bw_invariant);
    bw_precondition=implies_exprt(summary.bw_postcondition, bw_precondition);
  }

  // join // TODO: should go into summaryt
  if(summary.bw_transformer.is_nil())
  {
    summary.bw_transformer=bw_transformer;
    summary.bw_invariant=bw_invariant;
    summary.bw_precondition=bw_precondition;
  }
  else
  {
    summary.bw_transformer=or_exprt(summary.bw_transformer, bw_transformer);
    summary.bw_invariant=or_exprt(summary.bw_invariant, bw_invariant);
    summary.bw_precondition=or_exprt(summary.bw_precondition, bw_precondition);
  }

  return bw_precondition;
}
コード例 #21
0
ファイル: summarizer_bw.cpp プロジェクト: AnnaTrost/2ls
void summarizer_bwt::do_summary(const function_namet &function_name, 
				local_SSAt &SSA,
				const summaryt &old_summary,
				summaryt &summary,
				bool context_sensitive)
{
  bool sufficient = options.get_bool_option("sufficient");
  status() << "Computing preconditions" << eom;

  // solver
  incremental_solvert &solver = ssa_db.get_solver(function_name);
  solver.set_message_handler(get_message_handler());

  template_generator_summaryt template_generator(
    options,ssa_db,ssa_unwinder.get(function_name));
  template_generator.set_message_handler(get_message_handler());
  template_generator(solver.next_domain_number(),SSA,false);

  exprt::operandst c;
  c.push_back(old_summary.fw_precondition);
  c.push_back(old_summary.fw_invariant);
  c.push_back(ssa_inliner.get_summaries(SSA)); //forward summaries
  exprt::operandst postcond;
  ssa_inliner.get_summaries(SSA,false,postcond,c); //backward summaries
  collect_postconditions(function_name, SSA, summary, postcond,sufficient);
  if(!sufficient)
  {
    c.push_back(conjunction(postcond)); 
  }
  else //sufficient
  {
    c.push_back(not_exprt(conjunction(postcond))); 
  }

  if(!template_generator.out_vars().empty())
  {
    ssa_analyzert analyzer;
    analyzer.set_message_handler(get_message_handler());
    analyzer(solver,SSA,conjunction(c),template_generator);
    analyzer.get_result(summary.bw_transformer,template_generator.inout_vars());
    analyzer.get_result(summary.bw_invariant,template_generator.loop_vars());
    analyzer.get_result(summary.bw_precondition,template_generator.out_vars());

    //statistics
    solver_instances += analyzer.get_number_of_solver_instances();
    solver_calls += analyzer.get_number_of_solver_calls();
  }
  else // TODO: yet another workaround for ssa_analyzer not being able to handle empty templates properly
  {
    solver << SSA;
    solver.new_context();
    solver << SSA.get_enabling_exprs();
    solver << conjunction(c);
    exprt result = true_exprt();
    if(solver()==decision_proceduret::D_UNSATISFIABLE) result = false_exprt();
    solver.pop_context();
    summary.bw_transformer = result;
    summary.bw_invariant = result;
    summary.bw_precondition = result;
  }

  if(sufficient)
  {
    summary.bw_transformer = not_exprt(summary.bw_transformer);
    summary.bw_invariant = not_exprt(summary.bw_invariant);
    summary.bw_precondition = not_exprt(summary.bw_precondition);
  }

  if(context_sensitive && !summary.bw_postcondition.is_true())
  {
    summary.bw_transformer = 
      implies_exprt(summary.bw_postcondition,summary.bw_transformer);
    summary.bw_invariant = 
      implies_exprt(summary.bw_postcondition,summary.bw_invariant);
    summary.bw_precondition = 
      implies_exprt(summary.bw_postcondition,summary.bw_precondition);
  }
}
コード例 #22
0
ファイル: refiner_wp.cpp プロジェクト: olivo/BP
bool refiner_wpt::refine_prefix(
  predicatest &predicates, 
  abstract_modelt &abstract_model,
  const fail_infot &fail_info)
{
  status("Refining set of predicates according to counterexample (WP)");

  reset_num_predicates_added();

  bool found_new=false;

  // keep track of the loops that we're in (may be nested)
  std::list<fail_infot::induction_infot> loops;
  exprt invariant;
  if(fail_info.use_invariants)
    status("Using recurrence predicates detected by loop detection.");
  
  print(10, "refiner_wpt::refine_prefix_async 1");
  
  print(10, "Inconsistent prefix:");

  for(abstract_counterexamplet::stepst::const_reverse_iterator 
      r_it=fail_info.steps.rbegin();
      r_it!=fail_info.steps.rend();
      r_it++)
  {
    std::stringstream str;

    abstract_programt::targett abstract_pc=r_it->pc;

    goto_programt::const_targett concrete_pc=
      abstract_pc->code.concrete_pc;

    if(concrete_pc->is_goto())
      str << "GUARD: " << (r_it->branch_taken?"(":"!(")
                << from_expr(concrete_model.ns, "", concrete_pc->guard) << ")";
    else if(concrete_pc->is_assert())
      str << "ASSERT: "
                << from_expr(concrete_model.ns, "", concrete_pc->guard);
    else if(concrete_pc->is_location())
      str << "LOC" << std::endl;
    else if(concrete_pc->is_other() || concrete_pc->is_assign() || concrete_pc->is_decl())
      str << from_expr(concrete_model.ns, "", concrete_pc->code);
    else
    {
      str << concrete_pc->type;
    }

    str << "  // " << (concrete_pc->location);

    str << std::endl << "**********";

    print(10, str.str());
  }

  
  {
    // get the constraint causing the failure

    exprt predicate=fail_info.guard;

    #ifdef DEBUG
    std::cout << "P start0: " 
              << from_expr(concrete_model.ns, "", predicate) << std::endl;
    #endif

    simplify(predicate, concrete_model.ns);

    abstract_counterexamplet::stepst::const_iterator 
      it=--fail_info.steps.end();

    // there must be at least two steps, or it's odd
    assert(it!=fail_info.steps.begin());

    {
      abstract_programt::targett abstract_pc=it->pc;

      #ifdef DEBUG
      std::cout << "P start1: " 
                << from_expr(concrete_model.ns, "", predicate) << std::endl;
      #endif

      add_predicates(
        abstract_pc, predicates, predicate, found_new, FROM);
    }
      
    // now do the WPs
    goto_symex_statet renaming_state;
    renaming_state.source.thread_nr=it->thread_nr;
    renaming_state.rename(predicate, concrete_model.ns, goto_symex_statet::L0);

    for(it--; // skip last instruction
        it!=fail_info.steps.begin();
        it--)
    {
      #ifdef DEBUG
      std::cout << "refiner_wpt::refine_prefix_async 2\n";
      #endif

      // handle loops 
      if(fail_info.use_invariants)
      {
        if(it->is_loop_begin())
        {
          loops.pop_back(); // pop induction_info if we leave loop
          
#ifdef DEBUG
          std::cout << "INV: "
                    << from_expr(concrete_model.ns, "", invariant) << std::endl;
#endif           
          
          exprt wp(ID_and, typet(ID_bool));
          wp.operands().resize(2);
          wp.op0().swap(invariant);
          wp.op1().swap(predicate);
          predicate.swap(wp);
        }
        else if (it->is_loop_end())
        {
          push_induction_info(fail_info, it, loops);
          invariant.make_true();
        }
      }

      if(!it->is_state())
        continue;

      if(predicate.is_true() && found_new)
      {
        // ok, refuted it, done
        break;
      }
        
      // add the predicate

      goto_programt::const_targett concrete_pc=
        it->pc->code.concrete_pc;
        
      abstract_programt::targett abstract_pc=it->pc;
        
      #ifdef DEBUG
      std::cout << from_expr(concrete_model.ns, "", predicate) << std::endl;
      #endif
      
      exprt no_tid_predicate=predicate;
      renaming_state.get_original_name(no_tid_predicate);
      add_predicates(abstract_pc, predicates, no_tid_predicate, found_new, TO);

      // skip irrelevant instructions
      if(!it->relevant) continue;

      exprt pred_bak=predicate;
#ifdef DEBUG
      goto_programt tmp;
      tmp.output_instruction(concrete_model.ns, "", std::cerr, concrete_pc);
#endif

      // compute weakest precondition
      switch(it->pc->type)
      {
      case ASSUME:
        // we only do this for assumptions
        // if we haven't found a new predicate so far
        if(1/*!found_new*/)
        {
          exprt tid_guard=concrete_pc->guard;
          renaming_state.source.thread_nr=it->thread_nr;
          renaming_state.rename(tid_guard, concrete_model.ns, goto_symex_statet::L0);
          predicate=implies_exprt(tid_guard, predicate);
          simplify(predicate, concrete_model.ns);
        }
        break;

      case GOTO:
        {
          exprt tid_guard=concrete_pc->guard;
          if(!it->branch_taken) tid_guard.make_not();
          renaming_state.source.thread_nr=it->thread_nr;
          renaming_state.rename(tid_guard, concrete_model.ns, goto_symex_statet::L0);
          predicate=implies_exprt(tid_guard, predicate);
          simplify(predicate, concrete_model.ns);
        }
        break;

      case OTHER:
    	/* Ignore if user-specified predicate, otherwise treat like assign */
    	if(it->pc->code.concrete_pc->code.get_statement()==ID_user_specified_predicate || it->pc->code.concrete_pc->code.get_statement()==ID_user_specified_parameter_predicates || it->pc->code.concrete_pc->code.get_statement()==ID_user_specified_return_predicates)
    		break;
      case DECL:
      case ASSIGN:
        #ifdef DEBUG
        std::cout << "OTHER/ASSIGN/DECL\n";
        #endif

        {
          codet tid_tmp_code;
          if(!fail_info.use_invariants ||
             !get_instruction(concrete_pc, loops, tid_tmp_code, invariant))
            tid_tmp_code=to_code(concrete_pc->code);

#ifdef DEBUG
          std::cout << "A P before: " << from_expr(concrete_model.ns, "", predicate) << std::endl;
          std::cout << "Code:     " << from_expr(concrete_model.ns, "", tid_tmp_code) << std::endl;
#endif
          
          // compute weakest precondition
          if(tid_tmp_code.get_statement()==ID_assign)
            approximate_nondet(to_code_assign(tid_tmp_code).rhs());
          renaming_state.source.thread_nr=it->thread_nr;
          renaming_state.rename(tid_tmp_code, concrete_model.ns, goto_symex_statet::L0);
          exprt predicate_wp=wp(tid_tmp_code, predicate, concrete_model.ns);
      
          simplify(predicate_wp, concrete_model.ns);
          predicate=predicate_wp;

#ifdef DEBUG
          std::cout << "A P after:  " << from_expr(concrete_model.ns, "", predicate) << std::endl;
#endif
        }
        break;

      default:
        // ignore
        break;
      }

#ifdef DEBUG
          std::cout << "B P to-check:  " << from_expr(concrete_model.ns, "", predicate) << std::endl;
#endif
          
      if(pred_bak != predicate)
      {
        satcheckt satcheck;
        bv_pointerst solver(concrete_model.ns, satcheck);
        solver.unbounded_array=boolbvt::U_NONE;
        literalt li=make_pos(concrete_model.ns, solver, predicate);
        satcheck.set_assumptions(bvt(1, li));
        propt::resultt result=satcheck.prop_solve();
        assert(propt::P_SATISFIABLE==result || propt::P_UNSATISFIABLE==result);
        if(propt::P_UNSATISFIABLE==result)
          predicate.make_false();
        else
        {
          satcheck.set_assumptions(bvt(1, li.negation()));
          propt::resultt result=satcheck.prop_solve();
          assert(propt::P_SATISFIABLE==result || propt::P_UNSATISFIABLE==result);
          if(propt::P_UNSATISFIABLE==result)
          {
            predicate.make_true();
            if(it->pc->type==ASSIGN)
            {
              const codet &code=concrete_pc->code;
              if(code.get_statement()==ID_assign)
              {
                equal_exprt pred_new(to_code_assign(code).lhs(),
                    to_code_assign(code).rhs());
                simplify(pred_new, concrete_model.ns);
#ifdef DEBUG
                std::cout << "Adding new predicate as we arrived at TRUE: "
                  << from_expr(concrete_model.ns, "", pred_new) << std::endl;
#endif
                no_tid_predicate=pred_new;
                renaming_state.get_original_name(no_tid_predicate);
                add_predicates(abstract_pc, predicates, no_tid_predicate, found_new, FROM);
              }
            }
            else if(it->pc->type==ASSUME || it->pc->type==GOTO)
            {
              exprt pred_new=concrete_pc->guard;
              simplify(pred_new, concrete_model.ns);
#ifdef DEBUG
              std::cout << "Adding new predicate as we arrived at TRUE: "
                << from_expr(concrete_model.ns, "", pred_new) << std::endl;
#endif
              no_tid_predicate=pred_new;
              renaming_state.get_original_name(no_tid_predicate);
              add_predicates(abstract_pc, predicates, no_tid_predicate, found_new, FROM);
            }
          }
        }
      }
      
      #ifdef DEBUG
      std::cout << "B P after:   " << from_expr(concrete_model.ns, "", predicate) << std::endl;
      #endif

      no_tid_predicate=predicate;
      renaming_state.get_original_name(no_tid_predicate);
      add_predicates(abstract_pc, predicates, no_tid_predicate, found_new, FROM);
    }

    if(!predicate.is_true() && fail_info.warn_on_failure)
    {
      warning("Failed to refute spurious trace with WPs (got "+
              from_expr(concrete_model.ns, "", predicate)+")");
    }
  }

  if(found_new && fail_info.use_invariants)
  {
    add_induction_predicates(
      fail_info,
      abstract_model,
      predicates);
  }
  
  // make sure we have progress
  return !found_new;
}