示例#1
0
void c_typecheck_baset::do_designated_initializer(
  exprt &result,
  designatort &designator,
  const exprt &value,
  bool force_constant)
{
  assert(!designator.empty());

  if(value.id()==ID_designated_initializer)
  {
    assert(value.operands().size()==1);

    designator=
      make_designator(
        designator.front().type,
        static_cast<const exprt &>(value.find(ID_designator)));

    assert(!designator.empty());

    return do_designated_initializer(
      result, designator, value.op0(), force_constant);
  }

  exprt *dest=&result;

  // first phase: follow given designator

  for(size_t i=0; i<designator.size(); i++)
  {
    size_t index=designator[i].index;
    const typet &type=designator[i].type;
    const typet &full_type=follow(type);

    if(full_type.id()==ID_array ||
       full_type.id()==ID_vector)
    {
      if(index>=dest->operands().size())
      {
        if(full_type.id()==ID_array &&
           (to_array_type(full_type).size().is_zero() ||
            to_array_type(full_type).size().is_nil()))
        {
          // we are willing to grow an incomplete or zero-sized array
          exprt zero=zero_initializer(full_type.subtype(), value.source_location(), *this, get_message_handler());
          dest->operands().resize(integer2size_t(index)+1, zero);

          // todo: adjust type!
        }
        else
        {
          err_location(value);
          error() << "array index designator " << index
                  << " out of bounds (" << dest->operands().size()
                  << ")" << eom;
          throw 0;
        }
      }

      dest=&(dest->operands()[integer2size_t(index)]);
    }
    else if(full_type.id()==ID_struct)
    {
      const struct_typet::componentst &components=
        to_struct_type(full_type).components();

      if(index>=dest->operands().size())
      {
        err_location(value);
        error() << "structure member designator " << index
                << " out of bounds (" << dest->operands().size()
                << ")" << eom;
        throw 0;
      }

      assert(index<components.size());
      assert(components[index].type().id()!=ID_code &&
             !components[index].get_is_padding());

      dest=&(dest->operands()[index]);
    }
    else if(full_type.id()==ID_union)
    {
      const union_typet &union_type=to_union_type(full_type);

      const union_typet::componentst &components=
        union_type.components();

      assert(index<components.size());

      const union_typet::componentt &component=union_type.components()[index];

      if(dest->id()==ID_union &&
         dest->get(ID_component_name)==component.get_name())
      {
        // Already right union component. We can initialize multiple submembers,
        // so do not overwrite this.
      }
      else
      {
        // Note that gcc issues a warning if the union component is switched.
        // Build a union expression from given component.
        union_exprt union_expr(type);
        union_expr.op()=zero_initializer(component.type(), value.source_location(), *this, get_message_handler());
        union_expr.add_source_location()=value.source_location();
        union_expr.set_component_name(component.get_name());
        *dest=union_expr;
      }

      dest=&(dest->op0());
    }
    else
      assert(false);
  }

  // second phase: assign value
  // for this, we may need to go down, adding to the designator

  while(true)
  {
    // see what type we have to initialize

    const typet &type=designator.back().subtype;
    const typet &full_type=follow(type);
    assert(full_type.id()!=ID_symbol);

    // do we initialize a scalar?
    if(full_type.id()!=ID_struct &&
       full_type.id()!=ID_union &&
       full_type.id()!=ID_array &&
       full_type.id()!=ID_vector)
    {
      // The initializer for a scalar shall be a single expression,
      // * optionally enclosed in braces. *

      if(value.id()==ID_initializer_list &&
         value.operands().size()==1)
        *dest=do_initializer_rec(value.op0(), type, force_constant);
      else
        *dest=do_initializer_rec(value, type, force_constant);

      assert(full_type==follow(dest->type()));

      return; // done
    }

    // union? The component in the zero initializer might
    // not be the first one.
    if(full_type.id()==ID_union)
    {
      const union_typet &union_type=to_union_type(full_type);

      const union_typet::componentst &components=
        union_type.components();

      if(!components.empty())
      {
        const union_typet::componentt &component=union_type.components().front();

        union_exprt union_expr(type);
        union_expr.op()=zero_initializer(component.type(), value.source_location(), *this, get_message_handler());
        union_expr.add_source_location()=value.source_location();
        union_expr.set_component_name(component.get_name());
        *dest=union_expr;
      }
    }

    // see what initializer we are given
    if(value.id()==ID_initializer_list)
    {
      *dest=do_initializer_rec(value, type, force_constant);
      return; // done
    }
    else if(value.id()==ID_string_constant)
    {
      // We stop for initializers that are string-constants,
      // which are like arrays. We only do so if we are to
      // initialize an array of scalars.
      if(full_type.id()==ID_array &&
         (follow(full_type.subtype()).id()==ID_signedbv ||
          follow(full_type.subtype()).id()==ID_unsignedbv))
      {
        *dest=do_initializer_rec(value, type, force_constant);
        return; // done
      }
    }
    else if(follow(value.type())==full_type)
    {
      // a struct/union/vector can be initialized directly with
      // an expression of the right type. This doesn't
      // work with arrays, unfortunately.
      if(full_type.id()==ID_struct ||
         full_type.id()==ID_union ||
         full_type.id()==ID_vector)
      {
        *dest=value;
        return; // done
      }
    }

    assert(full_type.id()==ID_struct ||
           full_type.id()==ID_union ||
           full_type.id()==ID_array ||
           full_type.id()==ID_vector);

    // we are initializing a compound type, and enter it!
    // this may change the type, full_type might not be valid anymore
    const typet dest_type=full_type;
    designator_enter(type, designator);

    if(dest->operands().empty())
    {
      err_location(value);
      error() << "cannot initialize type `"
              << to_string(dest_type) << "' using value `"
              << to_string(value) << "'" << eom;
      throw 0;
    }

    dest=&(dest->op0());

    // we run into another loop iteration
  }
}
示例#2
0
int goto_fence_inserter_parse_optionst::doit()
{
  if(cmdline.isset("version"))
  {
    std::cout << MUSKETEER_VERSION << std::endl;
    return 0;
  }

  if(cmdline.args.size()!=1 && cmdline.args.size()!=2)
  {
    help();
    return 0;
  }

  set_verbosity();

  try
  {
    register_languages();

    goto_functionst goto_functions;

    get_goto_program(goto_functions);

    instrument_goto_program(goto_functions);

    // write new binary?
    if(cmdline.args.size()==2)
    {
      status() << "Writing GOTO program to " << cmdline.args[1] << eom;

      if(write_goto_binary(
        cmdline.args[1], symbol_table, goto_functions, get_message_handler()))
        return 1;
      else
        return 0;
    }

    // help();
    return 0;
  }

  catch(const char *e)
  {
    error() << e << eom;
    return 11;
  }

  catch(const std::string e)
  {
    error() << e << eom;
    return 11;
  }

  catch(int)
  {
    return 11;
  }

  catch(std::bad_alloc)
  {
    error() << "Out of memory" << eom;
    return 11;
  }
}
示例#3
0
bool language_filest::typecheck(contextt &context)
{
  // typecheck interfaces

  for(filemapt::iterator it=filemap.begin();
      it!=filemap.end(); it++)
  {
    if(it->second.language->interfaces(context, get_message_handler()))
      return true;
  }

  // build module map
  
  unsigned collision_counter=0;

  for(filemapt::iterator fm_it=filemap.begin();
      fm_it!=filemap.end(); fm_it++)
  {
    const language_filet::modulest &modules=
      fm_it->second.modules;

    for(language_filet::modulest::const_iterator
        mo_it=modules.begin();
        mo_it!=modules.end();
        mo_it++)
    {
      // these may collide, and then get renamed
      std::string module_name=*mo_it;
      
      while(modulemap.find(module_name)!=modulemap.end())
      {
        module_name=*mo_it+"#"+i2string(collision_counter);
        collision_counter++;
      }
      
      language_modulet module;
      module.file=&fm_it->second;
      module.name=module_name;
      modulemap.insert(
        std::pair<std::string, language_modulet>(module.name, module));
    }
  }

  // typecheck files

  for(filemapt::iterator it=filemap.begin();
      it!=filemap.end(); it++)
  {
    if(it->second.modules.empty())
      if(it->second.language->typecheck(context, "", get_message_handler()))
        return true;
  }

  // typecheck modules

  for(modulemapt::iterator it=modulemap.begin();
      it!=modulemap.end(); it++)
  {
    if(typecheck_module(context, it->second))
      return true;
  }

  return false;
}
bool cbmc_parseoptionst::process_goto_program(
  const optionst &options,
  goto_functionst &goto_functions)
{
  try
  {
    namespacet ns(context);

    if(cmdline.isset("string-abstraction"))
      string_instrumentation(
        context, get_message_handler(), goto_functions);

    status("Function Pointer Removal");
    remove_function_pointers(ns, goto_functions,
      cmdline.isset("pointer-check"));

    status("Partial Inlining");
    // do partial inlining
    goto_partial_inline(goto_functions, ns, ui_message_handler);
    
    status("Generic Property Instrumentation");
    // add generic checks
    goto_check(ns, options, goto_functions);
    
    if(cmdline.isset("string-abstraction"))
    {
      status("String Abstraction");
      string_abstraction(context,
        get_message_handler(), goto_functions);
    }

    // add failed symbols
    // needs to be done before pointer analysis
    add_failed_symbols(context);
    
    if(cmdline.isset("pointer-check") ||
       cmdline.isset("show-value-sets"))
    {
      status("Pointer Analysis");
      value_set_analysist value_set_analysis(ns);
      value_set_analysis(goto_functions);

      // show it?
      if(cmdline.isset("show-value-sets"))
      {
        show_value_sets(get_ui(), goto_functions, value_set_analysis);
        return true;
      }

      status("Adding Pointer Checks");

      // add pointer checks
      pointer_checks(
        goto_functions, context, options, value_set_analysis);
    }

    // recalculate numbers, etc.
    goto_functions.update();

    // add loop ids
    goto_functions.compute_loop_numbers();
    
    // if we aim to cover, replace
    // all assertions by false to prevent simplification
    
    if(cmdline.isset("cover-assertions"))
      make_assertions_false(goto_functions);

    // show it?
    if(cmdline.isset("show-loops"))
    {
      show_loop_numbers(get_ui(), goto_functions);
      return true;
    }

    // show it?
    if(cmdline.isset("show-goto-functions"))
    {
      goto_functions.output(ns, std::cout);
      return true;
    }
  }

  catch(const char *e)
  {
    error(e);
    return true;
  }

  catch(const std::string e)
  {
    error(e);
    return true;
  }
  
  catch(int)
  {
    return true;
  }
  
  catch(std::bad_alloc)
  {
    error("Out of memory");
    return true;
  }
  
  return false;
}
示例#5
0
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;
}
示例#6
0
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();
}
示例#7
0
void cover_goals_extt::assignment()
{
  // check loop head choices in model
  bool invariants_involved=false;
  if(spurious_check)
  {
    for(exprt::operandst::const_iterator l_it=loophead_selects.begin();
        l_it!=loophead_selects.end(); l_it++)
    {
      if(solver.get(l_it->op0()).is_true())
      {
        invariants_involved=true;
        break;
      }
    }
  }
  if(!invariants_involved || !spurious_check)
  {
    std::list<cover_goals_extt::cover_goalt>::const_iterator g_it=goals.begin();
    for(goal_mapt::const_iterator it=goal_map.begin();
        it!=goal_map.end(); it++, g_it++)
    {
      if(property_map[it->first].result==property_checkert::UNKNOWN &&
         solver.l_get(g_it->condition).is_true())
      {
        property_map[it->first].result=property_checkert::FAIL;
        if(build_error_trace)
        {
          ssa_build_goto_tracet build_goto_trace(SSA, solver.get_solver());
          build_goto_trace(property_map[it->first].error_trace);
          if(!all_properties)
            break;
        }
      }
    }
    return;
  }

  solver.new_context();
  // force avoiding paths going through invariants

  solver << conjunction(loophead_selects);

  switch(solver())
  {
  case decision_proceduret::D_SATISFIABLE:
  {
    std::list<cover_goals_extt::cover_goalt>::const_iterator g_it=goals.begin();
    for(goal_mapt::const_iterator it=goal_map.begin();
        it!=goal_map.end(); it++, g_it++)
    {
      if(property_map[it->first].result==property_checkert::UNKNOWN &&
         solver.l_get(g_it->condition).is_true())
      {
        property_map[it->first].result=property_checkert::FAIL;
        if(build_error_trace)
        {
          ssa_build_goto_tracet build_goto_trace(SSA, solver.get_solver());
          build_goto_trace(property_map[it->first].error_trace);

#if 0
          show_raw_countermodel(
            it->first, SSA, *solver.solver, debug(), get_message_handler());
#endif
          if(!all_properties)
            break;
        }
      }
    }
    break;
  }
  case decision_proceduret::D_UNSATISFIABLE:
    break;

  case decision_proceduret::D_ERROR:
  default:
    throw "error from decision procedure";
  }

  solver.pop_context();

  _iterations++; // statistics
}
示例#8
0
safety_checkert::resultt bmc_all_propertiest::operator()()
{
  status() << "Passing problem to " << solver.decision_procedure_text() << eom;

  solver.set_message_handler(get_message_handler());

  // stop the time
  absolute_timet sat_start=current_time();

  bmc.do_conversion();

  // Collect _all_ goals in `goal_map'.
  // This maps property IDs to 'goalt'
  forall_goto_functions(f_it, goto_functions)
    forall_goto_program_instructions(i_it, f_it->second.body)
      if(i_it->is_assert())
        goal_map[i_it->source_location.get_property_id()]=goalt(*i_it);

  // get the conditions for these goals from formula
  // collect all 'instances' of the properties
  for(symex_target_equationt::SSA_stepst::iterator
      it=bmc.equation.SSA_steps.begin();
      it!=bmc.equation.SSA_steps.end();
      it++)
  {
    if(it->is_assert())
    {
      irep_idt property_id;

      if(it->source.pc->is_assert())
        property_id=it->source.pc->source_location.get_property_id();
      else if(it->source.pc->is_goto())
      {
        // this is likely an unwinding assertion
        property_id=id2string(
          it->source.pc->source_location.get_function())+".unwind."+
          std::to_string(it->source.pc->loop_number);
        goal_map[property_id].description=it->comment;
      }
      else
        continue;

      goal_map[property_id].instances.push_back(it);
    }
  }

  do_before_solving();

  cover_goalst cover_goals(solver);

  cover_goals.set_message_handler(get_message_handler());
  cover_goals.register_observer(*this);

  for(const auto &g : goal_map)
  {
    // Our goal is to falsify a property, i.e., we will
    // add the negation of the property as goal.
    literalt p=!solver.convert(g.second.as_expr());
    cover_goals.add(p);
  }

  status() << "Running " << solver.decision_procedure_text() << eom;

  bool error=false;

  decision_proceduret::resultt result=cover_goals();

  if(result==decision_proceduret::resultt::D_ERROR)
  {
    error=true;
    for(auto &g : goal_map)
      if(g.second.status==goalt::statust::UNKNOWN)
        g.second.status=goalt::statust::ERROR;
  }
  else
  {
    for(auto &g : goal_map)
      if(g.second.status==goalt::statust::UNKNOWN)
        g.second.status=goalt::statust::SUCCESS;
  }

  // output runtime

  {
    absolute_timet sat_stop=current_time();
    status() << "Runtime decision procedure: "
             << (sat_stop-sat_start) << "s" << eom;
  }

  // report
  report(cover_goals);

  if(error)
    return safety_checkert::resultt::ERROR;

  bool safe=(cover_goals.number_covered()==0);

  if(safe)
    bmc.report_success(); // legacy, might go away
  else
    bmc.report_failure(); // legacy, might go away

  return safe?safety_checkert::resultt::SAFE:safety_checkert::resultt::UNSAFE;
}
示例#9
0
    get_message_handler()))
  {
    return true;
  }

  remove_internal_symbols(new_symbol_table);

  if(linking(symbol_table, new_symbol_table, get_message_handler()))
    return true;

  return false;
}

bool ansi_c_languaget::final(symbol_tablet &symbol_table)
{
  if(ansi_c_entry_point(symbol_table, "main", get_message_handler()))
    return true;

  return false;
}

void ansi_c_languaget::show_parse(std::ostream &out)
{
  parse_tree.output(out);
}

languaget *new_ansi_c_language()
{
  return new ansi_c_languaget;
}
示例#10
0
bool get_goto_modelt::operator()(const std::vector<std::string> &files)
{
  if(files.empty())
  {
    error() << "Please provide a program" << eom;
    return true;
  }

  try
  {
    std::vector<std::string> binaries, sources;
    binaries.reserve(files.size());
    sources.reserve(files.size());

    for(const auto &file : files)
    {
      if(is_goto_binary(file))
        binaries.push_back(file);
      else
        sources.push_back(file);
    }

    if(!sources.empty())
    {
      language_filest language_files;

      language_files.set_message_handler(get_message_handler());

      for(const auto &filename : sources)
      {
        #ifdef _MSC_VER
        std::ifstream infile(widen(filename));
        #else
        std::ifstream infile(filename);
        #endif

        if(!infile)
        {
          error() << "failed to open input file `" << filename
                  << '\'' << eom;
          return true;
        }

        std::pair<language_filest::file_mapt::iterator, bool>
          result=language_files.file_map.insert(
            std::pair<std::string, language_filet>(filename, language_filet()));

        language_filet &lf=result.first->second;

        lf.filename=filename;
        lf.language=get_language_from_filename(filename);

        if(lf.language==NULL)
        {
          error("failed to figure out type of file", filename);
          return true;
        }

        languaget &language=*lf.language;
        language.set_message_handler(get_message_handler());

        status() << "Parsing " << filename << eom;

        if(language.parse(infile, filename))
        {
          error() << "PARSING ERROR" << eom;
          return true;
        }

        lf.get_modules();
      }

      status() << "Converting" << eom;

      if(language_files.typecheck(symbol_table))
      {
        error() << "CONVERSION ERROR" << eom;
        return true;
      }

      if(binaries.empty())
      {
        if(language_files.final(symbol_table))
        {
          error() << "CONVERSION ERROR" << eom;
          return true;
        }
      }
    }

    for(const auto &file : binaries)
    {
      status() << "Reading GOTO program from file" << eom;

      if(read_object_and_link(file, *this, get_message_handler()))
        return true;
    }

    if(!binaries.empty())
      config.set_from_symbol_table(symbol_table);

    status() << "Generating GOTO Program" << eom;

    goto_convert(symbol_table,
                 goto_functions,
                 get_message_handler());
  }
示例#11
0
bool ansi_c_languaget::parse(
  std::istream &instream,
  const std::string &path)
{
  // store the path

  parse_path=path;

  // preprocessing

  std::ostringstream o_preprocessed;

  if(preprocess(instream, path, o_preprocessed))
    return true;

  std::istringstream i_preprocessed(o_preprocessed.str());

  // parsing

  std::string code;
  ansi_c_internal_additions(code);
  std::istringstream codestr(code);

  ansi_c_parser.clear();
  ansi_c_parser.set_file(ID_built_in);
  ansi_c_parser.in=&codestr;
  ansi_c_parser.set_message_handler(get_message_handler());
  ansi_c_parser.for_has_scope=config.ansi_c.for_has_scope;
  ansi_c_parser.cpp98=false; // it's not C++
  ansi_c_parser.cpp11=false; // it's not C++

  switch(config.ansi_c.mode)
  {
  case configt::ansi_ct::flavourt::MODE_CODEWARRIOR_C_CPP:
    ansi_c_parser.mode=ansi_c_parsert::CW;
    break;
   
  case configt::ansi_ct::flavourt::MODE_VISUAL_STUDIO_C_CPP:
    ansi_c_parser.mode=ansi_c_parsert::MSC;
    break;
    
  case configt::ansi_ct::flavourt::MODE_ANSI_C_CPP:
    ansi_c_parser.mode=ansi_c_parsert::ANSI;
    break;
    
  case configt::ansi_ct::flavourt::MODE_GCC_C:
  case configt::ansi_ct::flavourt::MODE_GCC_CPP:
    ansi_c_parser.mode=ansi_c_parsert::GCC;
    break;
    
  case configt::ansi_ct::flavourt::MODE_ARM_C_CPP:
    ansi_c_parser.mode=ansi_c_parsert::ARM;
    break;
    
  default:
    assert(false);
  }

  ansi_c_scanner_init();

  bool result=ansi_c_parser.parse();

  if(!result)
  {
    ansi_c_parser.set_line_no(0);
    ansi_c_parser.set_file(path);
    ansi_c_parser.in=&i_preprocessed;
    ansi_c_scanner_init();
    result=ansi_c_parser.parse();
  }

  // save result
  parse_tree.swap(ansi_c_parser.parse_tree);

  // save some memory
  ansi_c_parser.clear();

  return result;
}
示例#12
0
bool cbmc_parse_optionst::process_goto_program(
  const optionst &options,
  goto_functionst &goto_functions)
{
  try
  {
    namespacet ns(symbol_table);
    
    // Remove inline assembler; this needs to happen before
    // adding the library.
    remove_asm(symbol_table, goto_functions);

    // add the library
    status() << "Adding CPROVER library (" 
             << config.ansi_c.arch << ")" << eom;
    link_to_library(symbol_table, goto_functions, ui_message_handler);

    if(cmdline.isset("string-abstraction"))
      string_instrumentation(
        symbol_table, get_message_handler(), goto_functions);

    // remove function pointers
    status() << "Function Pointer Removal" << eom;
    remove_function_pointers(symbol_table, goto_functions,
      cmdline.isset("pointer-check"));

    // full slice?
    if(cmdline.isset("full-slice"))
    {
      status() << "Performing a full slice" << eom;
      full_slicer(goto_functions, ns);
    }
  
    // do partial inlining
    status() << "Partial Inlining" << eom;
    goto_partial_inline(goto_functions, ns, ui_message_handler);
    
    // remove returns, gcc vectors, complex
    remove_returns(symbol_table, goto_functions);
    remove_vector(symbol_table, goto_functions);
    remove_complex(symbol_table, goto_functions);
    
    // add generic checks
    status() << "Generic Property Instrumentation" << eom;
    goto_check(ns, options, goto_functions);
    
    if(cmdline.isset("string-abstraction"))
    {
      status() << "String Abstraction" << eom;
      string_abstraction(symbol_table,
        get_message_handler(), goto_functions);
    }

    // add failed symbols
    // needs to be done before pointer analysis
    add_failed_symbols(symbol_table);
    
    // recalculate numbers, etc.
    goto_functions.update();

    // add loop ids
    goto_functions.compute_loop_numbers();
    
    // if we aim to cover assertions, replace
    // all assertions by false to prevent simplification
    
    if(cmdline.isset("cover") &&
       cmdline.get_value("cover")=="assertions")
      make_assertions_false(goto_functions);

    // show it?
    if(cmdline.isset("show-loops"))
    {
      show_loop_ids(get_ui(), goto_functions);
      return true;
    }

    // show it?
    if(cmdline.isset("show-goto-functions"))
    {
      goto_functions.output(ns, std::cout);
      return true;
    }
  }

  catch(const char *e)
  {
    error() << e << eom;
    return true;
  }

  catch(const std::string e)
  {
    error() << e << eom;
    return true;
  }
  
  catch(int)
  {
    return true;
  }
  
  catch(std::bad_alloc)
  {
    error() << "Out of memory" << eom;
    return true;
  }
  
  return false;
}
示例#13
0
int cbmc_parse_optionst::get_goto_program(
  const optionst &options,
  bmct &bmc, // for get_modules
  goto_functionst &goto_functions)
{
  if(cmdline.args.empty())
  {
    error() << "Please provide a program to verify" << eom;
    return 6;
  }

  try
  {
    if(cmdline.isset("show-parse-tree"))
    {
      if(cmdline.args.size()!=1 ||
         is_goto_binary(cmdline.args[0]))
      {
        error() << "Please give exactly one source file" << eom;
        return 6;
      }
      
      std::string filename=cmdline.args[0];
      
      #ifdef _MSC_VER
      std::ifstream infile(widen(filename).c_str());
      #else
      std::ifstream infile(filename.c_str());
      #endif
                
      if(!infile)
      {
        error() << "failed to open input file `" << filename << "'" << eom;
        return 6;
      }
                              
      languaget *language=get_language_from_filename(filename);
      
      if(language==NULL)
      {
        error() << "failed to figure out type of file `" <<  filename << "'" << eom;
        return 6;
      }
      
      language->set_message_handler(get_message_handler());
                                                                
      status("Parsing", filename);
  
      if(language->parse(infile, filename))
      {
        error() << "PARSING ERROR" << eom;
        return 6;
      }
      
      language->show_parse(std::cout);
      return 0;
    }

    cmdlinet::argst binaries;
    binaries.reserve(cmdline.args.size());

    for(cmdlinet::argst::iterator
        it=cmdline.args.begin();
        it!=cmdline.args.end();
        ) // no ++it
    {
      if(is_goto_binary(*it))
      {
        binaries.push_back(*it);
        it=cmdline.args.erase(it);
        continue;
      }

      ++it;
    }

    if(!cmdline.args.empty())
    {
      if(parse()) return 6;
      if(typecheck()) return 6;
      int get_modules_ret=get_modules(bmc);
      if(get_modules_ret!=-1) return get_modules_ret;
      if(binaries.empty() && final()) return 6;

      // we no longer need any parse trees or language files
      clear_parse();
    }

    for(cmdlinet::argst::const_iterator
        it=binaries.begin();
        it!=binaries.end();
        ++it)
    {
      status() << "Reading GOTO program from file " << eom;

      if(read_object_and_link(*it, symbol_table, goto_functions, *this))
        return 6;
    }

    if(!binaries.empty())
      config.set_from_symbol_table(symbol_table);

    if(cmdline.isset("show-symbol-table"))
    {
      show_symbol_table();
      return 0;
    }

    if(entry_point(symbol_table, "main", get_message_handler()))
      return 6;

    status() << "Generating GOTO Program" << eom;

    goto_convert(symbol_table, goto_functions, ui_message_handler);

    if(process_goto_program(options, goto_functions))
      return 6;
  }

  catch(const char *e)
  {
    error() << e << eom;
    return 6;
  }

  catch(const std::string e)
  {
    error() << e << eom;
    return 6;
  }
  
  catch(int)
  {
    return 6;
  }
  
  catch(std::bad_alloc)
  {
    error() << "Out of memory" << eom;
    return 6;
  }
  
  return -1; // no error, continue
}
示例#14
0
void c_typecheck_baset::typecheck_type(typet &type)
{
  // we first convert, and then check
  {
    ansi_c_convert_typet ansi_c_convert_type(get_message_handler());

    ansi_c_convert_type.read(type);
    ansi_c_convert_type.write(type);
  }

  if(type.id()==ID_already_typechecked)
  {
    // need to preserve any qualifiers
    c_qualifierst c_qualifiers(type);
    c_qualifiers+=c_qualifierst(type.subtype());
    bool packed=type.get_bool(ID_C_packed);
    exprt alignment=static_cast<const exprt &>(type.find(ID_C_alignment));

    type.swap(type.subtype());

    c_qualifiers.write(type);
    if(packed)
      type.set(ID_C_packed, true);
    if(alignment.is_not_nil())
      type.add(ID_C_alignment, alignment);

    return; // done
  }

  // do we have alignment?
  if(type.find(ID_C_alignment).is_not_nil())
  {
    exprt &alignment=static_cast<exprt &>(type.add(ID_C_alignment));
    if(alignment.id()!=ID_default)
    {
      typecheck_expr(alignment);
      make_constant(alignment);
    }
  }

  if(type.id()==ID_code)
    typecheck_code_type(to_code_type(type));
  else if(type.id()==ID_array)
    typecheck_array_type(to_array_type(type));
  else if(type.id()==ID_pointer)
    typecheck_type(type.subtype());
  else if(type.id()==ID_struct ||
          type.id()==ID_union)
    typecheck_compound_type(to_struct_union_type(type));
  else if(type.id()==ID_c_enum)
    typecheck_c_enum_type(type);
  else if(type.id()==ID_c_enum_tag)
    typecheck_c_enum_tag_type(to_c_enum_tag_type(type));
  else if(type.id()==ID_c_bit_field)
    typecheck_c_bit_field_type(to_c_bit_field_type(type));
  else if(type.id()==ID_typeof)
    typecheck_typeof_type(type);
  else if(type.id()==ID_symbol)
    typecheck_symbol_type(type);
  else if(type.id()==ID_vector)
    typecheck_vector_type(to_vector_type(type));
  else if(type.id()==ID_custom_unsignedbv ||
          type.id()==ID_custom_signedbv ||
          type.id()==ID_custom_floatbv ||
          type.id()==ID_custom_fixedbv)
    typecheck_custom_type(type);
  else if(type.id()==ID_gcc_attribute_mode)
  {
    // get that mode
    irep_idt mode=type.get(ID_size);

    // A list of all modes ist at
    // http://www.delorie.com/gnu/docs/gcc/gccint_53.html
    typecheck_type(type.subtype());

    typet underlying_type=type.subtype();

    // gcc allows this, but clang doesn't; it's a compiler hint only,
    // but we'll try to interpret it the GCC way
    if(underlying_type.id()==ID_c_enum_tag)
    {
      underlying_type=
        follow_tag(to_c_enum_tag_type(underlying_type)).subtype();

      assert(underlying_type.id()==ID_signedbv ||
             underlying_type.id()==ID_unsignedbv);
    }

    if(underlying_type.id()==ID_signedbv ||
       underlying_type.id()==ID_unsignedbv)
    {
      bool is_signed=underlying_type.id()==ID_signedbv;

      typet result;

      if(mode=="__QI__") // 8 bits
        result=is_signed?signed_char_type():unsigned_char_type();
      else if(mode=="__byte__") // 8 bits
        result=is_signed?signed_char_type():unsigned_char_type();
      else if(mode=="__HI__") // 16 bits
        result=is_signed?signed_short_int_type():unsigned_short_int_type();
      else if(mode=="__SI__") // 32 bits
        result=is_signed?signed_int_type():unsigned_int_type();
      else if(mode=="__word__") // long int, we think
        result=is_signed?signed_long_int_type():unsigned_long_int_type();
      else if(mode=="__pointer__") // we think this is size_t/ssize_t
        result=is_signed?signed_size_type():size_type();
      else if(mode=="__DI__") // 64 bits
      {
        if(config.ansi_c.long_int_width==64)
          result=is_signed?signed_long_int_type():unsigned_long_int_type();
        else
        {
          assert(config.ansi_c.long_long_int_width==64);
          result=
            is_signed?signed_long_long_int_type():unsigned_long_long_int_type();
        }
      }
      else if(mode=="__TI__") // 128 bits
        result=is_signed?gcc_signed_int128_type():gcc_unsigned_int128_type();
      else if(mode=="__V2SI__") // vector of 2 ints, deprecated by gcc
        result=
          vector_typet(
            is_signed?signed_int_type():unsigned_int_type(),
            from_integer(2, size_type()));
      else if(mode=="__V4SI__") // vector of 4 ints, deprecated by gcc
        result=
          vector_typet(
            is_signed?signed_int_type():unsigned_int_type(),
            from_integer(4, size_type()));
      else // give up, just use subtype
        result=type.subtype();

      // save the location
      result.add_source_location()=type.source_location();

      if(type.subtype().id()==ID_c_enum_tag)
      {
        const irep_idt &tag_name=
          to_c_enum_tag_type(type.subtype()).get_identifier();

        symbol_tablet::symbolst::iterator entry=
          symbol_table.symbols.find(tag_name);
        assert(entry!=symbol_table.symbols.end());

        entry->second.type.subtype()=result;
      }

      type=result;
    }
    else if(underlying_type.id()==ID_floatbv)
    {
      typet result;

      if(mode=="__SF__") // 32 bits
        result=float_type();
      else if(mode=="__DF__") // 64 bits
        result=double_type();
      else if(mode=="__TF__") // 128 bits
        result=gcc_float128_type();
      else if(mode=="__V2SF__") // vector of 2 floats, deprecated by gcc
        result=vector_typet(float_type(), from_integer(2, size_type()));
      else if(mode=="__V2DF__") // vector of 2 doubles, deprecated by gcc
        result=vector_typet(double_type(), from_integer(2, size_type()));
      else if(mode=="__V4SF__") // vector of 4 floats, deprecated by gcc
        result=vector_typet(float_type(), from_integer(4, size_type()));
      else if(mode=="__V4DF__") // vector of 4 doubles, deprecated by gcc
        result=vector_typet(double_type(), from_integer(4, size_type()));
      else // give up, just use subtype
        result=type.subtype();

      // save the location
      result.add_source_location()=type.source_location();

      type=result;
    }
    else if(underlying_type.id()==ID_complex)
    {
      // gcc allows this, but clang doesn't -- see enums above
      typet result;

      if(mode=="__SC__") // 32 bits
        result=float_type();
      else if(mode=="__DC__") // 64 bits
        result=double_type();
      else if(mode=="__TC__") // 128 bits
        result=gcc_float128_type();
      else // give up, just use subtype
        result=type.subtype();

      // save the location
      result.add_source_location()=type.source_location();

      type=complex_typet(result);
    }
    else
    {
      error().source_location=type.source_location();
      error() << "attribute mode `" << mode
              << "' applied to inappropriate type `"
              << to_string(type) << "'" << eom;
      throw 0;
    }
  }

  // do a mild bit of rule checking

  if(type.get_bool(ID_C_restricted) &&
     type.id()!=ID_pointer &&
     type.id()!=ID_array)
  {
    error().source_location=type.source_location();
    error() << "only a pointer can be 'restrict'" << eom;
    throw 0;
  }
}
示例#15
0
exprt c_typecheck_baset::do_initializer_rec(
  const exprt &value,
  const typet &type,
  bool force_constant)
{
  const typet &full_type=follow(type);

  if(full_type.id()==ID_incomplete_struct)
  {
    err_location(value);
    error() << "type `" << to_string(full_type)
            << "' is still incomplete -- cannot initialize" << eom;
    throw 0;
  }

  if(value.id()==ID_initializer_list)
    return do_initializer_list(value, type, force_constant);

  if(value.id()==ID_array &&
     value.get_bool(ID_C_string_constant) &&
     full_type.id()==ID_array &&
     (full_type.subtype().id()==ID_signedbv ||
      full_type.subtype().id()==ID_unsignedbv) &&
      full_type.subtype().get(ID_width)==value.type().subtype().get(ID_width))
  {
    exprt tmp=value;

    // adjust char type
    tmp.type().subtype()=full_type.subtype();

    Forall_operands(it, tmp)
      it->type()=full_type.subtype();

    if(full_type.id()==ID_array &&
       to_array_type(full_type).is_complete())
    {
      // check size
      mp_integer array_size;
      if(to_integer(to_array_type(full_type).size(), array_size))
      {
        err_location(value);
        error() << "array size needs to be constant, got "
                << to_string(to_array_type(full_type).size()) << eom;
        throw 0;
      }

      if(array_size<0)
      {
        err_location(value);
        error() << "array size must not be negative" << eom;
        throw 0;
      }

      if(mp_integer(tmp.operands().size())>array_size)
      {
        // cut off long strings. gcc does a warning for this
        tmp.operands().resize(integer2size_t(array_size));
        tmp.type()=type;
      }
      else if(mp_integer(tmp.operands().size())<array_size)
      {
        // fill up
        tmp.type()=type;
        exprt zero=zero_initializer(full_type.subtype(), value.source_location(),
                                    *this, get_message_handler());
        tmp.operands().resize(integer2size_t(array_size), zero);
      }
    }

    return tmp;
  }

  if(value.id()==ID_string_constant &&
     full_type.id()==ID_array &&
     (full_type.subtype().id()==ID_signedbv ||
      full_type.subtype().id()==ID_unsignedbv) &&
      full_type.subtype().get(ID_width)==char_type().get(ID_width))
  {
    // will go away, to be replaced by the above block

    string_constantt tmp1=to_string_constant(value);
    // adjust char type
    tmp1.type().subtype()=full_type.subtype();

    exprt tmp2=tmp1.to_array_expr();

    if(full_type.id()==ID_array &&
       to_array_type(full_type).is_complete())
    {
      // check size
      mp_integer array_size;
      if(to_integer(to_array_type(full_type).size(), array_size))
      {
        err_location(value);
        error() << "array size needs to be constant, got "
                << to_string(to_array_type(full_type).size()) << eom;
        throw 0;
      }

      if(array_size<0)
      {
        err_location(value);
        error() << "array size must not be negative" << eom;
        throw 0;
      }

      if(mp_integer(tmp2.operands().size())>array_size)
      {
        // cut off long strings. gcc does a warning for this
        tmp2.operands().resize(integer2size_t(array_size));
        tmp2.type()=type;
      }
      else if(mp_integer(tmp2.operands().size())<array_size)
      {
        // fill up
        tmp2.type()=type;
        exprt zero=zero_initializer(full_type.subtype(), value.source_location(),
                                    *this, get_message_handler());
        tmp2.operands().resize(integer2size_t(array_size), zero);
      }
    }

    return tmp2;
  }

  if(full_type.id()==ID_array &&
     to_array_type(full_type).size().is_nil())
  {
    err_location(value);
    error() << "type `" << to_string(full_type)
            << "' cannot be initialized with `" << to_string(value)
            << "'" << eom;
    throw 0;
  }

  if(value.id()==ID_designated_initializer)
  {
    err_location(value);
    error() << "type `" << to_string(full_type)
            << "' cannot be initialized with designated initializer"
            << eom;
    throw 0;
  }

  exprt result=value;
  implicit_typecast(result, type);
  return result;
}
示例#16
0
property_checkert::resultt summary_checker_acdlt::operator()(
  const goto_modelt &goto_model)
{
  const namespacet ns(goto_model.symbol_table);

  SSA_functions(goto_model, ns);
  ssa_unwinder.init(false, false);

  unsigned unwind=options.get_unsigned_int_option("unwind");
  if(unwind>0)
  {
    status() << "Unwinding" << messaget::eom;
    ssa_unwinder.init_localunwinders();
    ssa_unwinder.unwind_all(unwind);
  }

  irep_idt entry_point=goto_model.goto_functions.entry_point();
  std::cout << entry_point << std::endl;
  local_SSAt &SSA=ssa_db.get(entry_point);
  ssa_local_unwindert &ssa_local_unwinder=ssa_unwinder.get(entry_point);

  const goto_programt &goto_program=SSA.goto_function.body;
  for(goto_programt::instructionst::const_iterator
        i_it=goto_program.instructions.begin();
      i_it!=goto_program.instructions.end();
      i_it++)
  {
    /*if(!i_it->is_assert() || !i_it->is_assume())
      continue;
    */

    const source_locationt &location=i_it->source_location;
    irep_idt property_id=location.get_property_id();

    if(i_it->guard.is_true())
    {
      property_map[property_id].result=PASS;
      continue;
    }

    if(property_id=="") // TODO: some properties do not show up in initialize_property_map
      continue;

    // get loophead selects
    exprt::operandst loophead_selects;
    for(local_SSAt::nodest::const_iterator n_it=SSA.nodes.begin();
        n_it!=SSA.nodes.end(); n_it++)
    {
      if(n_it->loophead==SSA.nodes.end()) continue;
      symbol_exprt lsguard=
        SSA.name(SSA.guard_symbol(), local_SSAt::LOOP_SELECT, n_it->location);
      ssa_unwinder.get(entry_point).unwinder_rename(lsguard, *n_it, true);
      loophead_selects.push_back(not_exprt(lsguard));
    }

    // iterate over assumptions
    exprt::operandst assumptions;
    for(local_SSAt::nodest::const_iterator n_it=SSA.nodes.begin();
        n_it!=SSA.nodes.end(); n_it++)
    {
      for(local_SSAt::nodet::assumptionst::const_iterator
            a_it=n_it->assumptions.begin();
          a_it!=n_it->assumptions.end(); a_it++)
      {
        std::cout << "Assumption:: " << from_expr(*a_it) << std::endl;
        assumptions.push_back(*a_it);
      }
    }
    // iterate over assertions
    std::list<local_SSAt::nodest::const_iterator> assertion_nodes;
    SSA.find_nodes(i_it, assertion_nodes);
    std::cout << "The number of assertions are: "
              << assertion_nodes.size() << std::endl;
    exprt::operandst assertions;
    for(std::list<local_SSAt::nodest::const_iterator>::const_iterator
          n_it=assertion_nodes.begin();
        n_it!=assertion_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++)
      {
        assertions.push_back(*a_it);
      }
    }

    // if(simplify) property=simplify_expr(property, SSA.ns);
    property_map[property_id].location=i_it;

    // TODO: make the solver incremental

    // configure components of acdl solver
    // domain
    acdl_domaint domain(options, SSA, ssa_db, ssa_local_unwinder);
    domain.set_message_handler(get_message_handler());

    // worklist heuristics
    std::unique_ptr<acdl_worklist_baset> worklist;
    if(options.get_option("propagate")=="forward")
      worklist=std::unique_ptr<acdl_worklist_baset>(
        new acdl_worklist_forwardt());
    if(options.get_option("propagate")=="backward")
      worklist=std::unique_ptr<acdl_worklist_baset>(
        new acdl_worklist_backwardt());
    else if(options.get_option("propagate")=="chaotic")
      worklist=std::unique_ptr<acdl_worklist_baset>(
        new acdl_worklist_orderedt());

    // conflict analysis heuristics
    std::unique_ptr<acdl_analyze_conflict_baset> conflict_analysis;
    if(options.get_option("learning")=="first-uip")
      // TODO: no 'new' with base class!
      conflict_analysis=std::unique_ptr<acdl_analyze_conflict_baset>(
        new acdl_analyze_conflict_baset(domain));

    // decision heuristics
    std::unique_ptr<acdl_decision_heuristics_baset> decision_heuristics;
    if(options.get_option("decision")=="random")
      decision_heuristics=std::unique_ptr<acdl_decision_heuristics_baset>(
        new acdl_decision_heuristics_randt(domain));
    else if(options.get_option("decision")=="ordered")
      decision_heuristics=std::unique_ptr<acdl_decision_heuristics_baset>(
        new acdl_decision_heuristics_orderedt(domain));
    else if(options.get_option("decision")=="octagon")
      decision_heuristics=std::unique_ptr<acdl_decision_heuristics_baset>(
        new acdl_decision_heuristics_octagont(domain));
    else if(options.get_option("decision")=="berkmin")
      decision_heuristics=std::unique_ptr<acdl_decision_heuristics_baset>(
        new acdl_decision_heuristics_berkmint(domain, *conflict_analysis));
    else if(options.get_option("decision")=="range")
      decision_heuristics=std::unique_ptr<acdl_decision_heuristics_baset>(
        new acdl_decision_heuristics_ranget(domain));

    // now instantiate solver
    acdl_solvert acdl_solver(
      options,
      domain,
      *decision_heuristics,
      *worklist,
      *conflict_analysis);

    acdl_solver.set_message_handler(get_message_handler());

    property_map[property_id].result=
      acdl_solver(
        ssa_db.get(goto_model.goto_functions.entry_point()),
        conjunction(assertions),
        conjunction(loophead_selects),
        conjunction(assumptions));
  }

  summary_checker_baset::resultt result=property_checkert::PASS;
  for(property_mapt::const_iterator
        p_it=property_map.begin(); p_it!=property_map.end(); p_it++)
  {
    if(p_it->second.result==FAIL)
      return property_checkert::FAIL;
    if(p_it->second.result==UNKNOWN)
      result=property_checkert::UNKNOWN;
  }

  return result;
}
示例#17
0
exprt c_typecheck_baset::do_initializer_list(
  const exprt &value,
  const typet &type,
  bool force_constant)
{
  assert(value.id()==ID_initializer_list);

  const typet &full_type=follow(type);

  exprt result;
  if(full_type.id()==ID_struct ||
     full_type.id()==ID_union ||
     full_type.id()==ID_vector)
  {
    // start with zero everywhere
    result=zero_initializer(type, value.source_location(), *this, get_message_handler());
  }
  else if(full_type.id()==ID_array)
  {
    if(to_array_type(full_type).size().is_nil())
    {
      // start with empty array
      result=exprt(ID_array, full_type);
      result.add_source_location()=value.source_location();
    }
    else
    {
      // start with zero everywhere
      result=zero_initializer(type, value.source_location(), *this, get_message_handler());
    }

    // 6.7.9, 14: An array of character type may be initialized by a character
    // string literal or UTF-8 string literal, optionally enclosed in braces.
    if(value.operands().size()>=1 &&
       value.op0().id()==ID_string_constant &&
       (full_type.subtype().id()==ID_signedbv ||
        full_type.subtype().id()==ID_unsignedbv) &&
       full_type.subtype().get(ID_width)==char_type().get(ID_width))
    {
      if(value.operands().size()>1)
      {
        warning().source_location=value.find_source_location();
        warning() << "ignoring excess initializers" << eom;
      }

      return do_initializer_rec(value.op0(), type, force_constant);
    }
  }
  else
  {
    // The initializer for a scalar shall be a single expression,
    // * optionally enclosed in braces. *

    if(value.operands().size()==1)
      return do_initializer_rec(value.op0(), type, force_constant);

    err_location(value);
    error() << "cannot initialize `" << to_string(full_type)
            << "' with an initializer list" << eom;
    throw 0;
  }

  designatort current_designator;

  designator_enter(type, current_designator);

  forall_operands(it, value)
  {
    do_designated_initializer(
      result, current_designator, *it, force_constant);

    // increase designator -- might go up
    increment_designator(current_designator);
  }
示例#18
0
文件: ranking_sat.cpp 项目: olivo/BP
satcheckt::resultt ranking_synthesis_satt::check_for_counterexample(
   const exprt &templ,
   c_valuest &c_values,
   fine_timet &conversion_time,
   fine_timet &solver_time)
{
  satcheckt::resultt result;

  satcheckt solver;
  bv_pointerst converter(ns, solver);   

  solver.set_message_handler(get_message_handler());
  solver.set_verbosity(verbosity);
  converter.set_message_handler(get_message_handler());
  converter.set_verbosity(verbosity);

  show_coefficients(c_values);

  fine_timet before = current_time();
  converter.set_to_true(templ);

  for(c_valuest::const_iterator it=c_values.begin();
      it!=c_values.end();
      it++)
  {
    equal_exprt eq;

    if(it->first.get("identifier")=="termination::constant$C")
    {
      mp_integer cval;
      if(to_integer(largest_constant, cval))
        throw "number conversion failed";

      mp_integer b=cval * it->second;

      eq=equal_exprt(it->first,
                        from_integer(b, it->first.type()));
    }
    else
      eq=equal_exprt(it->first, from_integer(it->second, it->first.type()));

    converter.set_to_true(eq);
  }

  conversion_time+=current_time()-before;

  before = current_time();
  result=solver.prop_solve();
  solver_time+=current_time()-before;
  solver_calls++;

  std::string output;
  
  if(result==satcheckt::P_SATISFIABLE)    
    show_counterexample(converter);
  else if(result==satcheckt::P_UNSATISFIABLE)
    output += " ... YES!\n";
  else
    output += "ERROR\n";
  
  debug(output);

  return result;
}
示例#19
0
cbmc_solverst::solvert* cbmc_solverst::get_smt2(smt2_dect::solvert solver)
{
  no_beautification();

  const std::string &filename=options.get_option("outfile");

  if(filename=="")
  {
    if(solver==smt2_dect::solvert::GENERIC)
    {
      error() << "please use --outfile" << eom;
      throw 0;
    }

    smt2_dect *smt2_dec=
      new smt2_dect(
        ns,
        "cbmc",
        "Generated by CBMC " CBMC_VERSION,
        "QF_AUFBV",
        solver);

    if(options.get_bool_option("fpa"))
      smt2_dec->use_FPA_theory=true;

    return new solvert(smt2_dec);
  }
  else if(filename=="-")
  {
    smt2_convt *smt2_conv=
      new smt2_convt(
        ns,
        "cbmc",
        "Generated by CBMC " CBMC_VERSION,
        "QF_AUFBV",
        solver,
        std::cout);

    if(options.get_bool_option("fpa"))
      smt2_conv->use_FPA_theory=true;

    smt2_conv->set_message_handler(get_message_handler());

    return new solvert(smt2_conv);
  }
  else
  {
    #ifdef _MSC_VER
    std::ofstream *out=new std::ofstream(widen(filename));
    #else
    std::ofstream *out=new std::ofstream(filename);
    #endif

    if(!*out)
    {
      error() << "failed to open " << filename << eom;
      throw 0;
    }

    smt2_convt *smt2_conv=
      new smt2_convt(
        ns,
        "cbmc",
        "Generated by CBMC " CBMC_VERSION,
        "QF_AUFBV",
        solver,
        *out);

    if(options.get_bool_option("fpa"))
      smt2_conv->use_FPA_theory=true;

    smt2_conv->set_message_handler(get_message_handler());

    return new solvert(smt2_conv, out);
  }
}
示例#20
0
void java_bytecode_convert_classt::convert(const classt &c)
{
  class_typet class_type;

  class_type.set_tag(c.name);
  class_type.set(ID_base_name, c.name);
  if(c.is_enum)
    class_type.set(
      ID_java_enum_static_unwind,
      std::to_string(c.enum_elements+1));

  if(!c.extends.empty())
  {
    symbol_typet base("java::"+id2string(c.extends));
    class_type.add_base(base);
    class_typet::componentt base_class_field;
    base_class_field.type()=base;
    base_class_field.set_name("@"+id2string(c.extends));
    base_class_field.set_base_name("@"+id2string(c.extends));
    base_class_field.set_pretty_name("@"+id2string(c.extends));
    class_type.components().push_back(base_class_field);
  }

  // interfaces are recorded as bases
  for(const auto &interface : c.implements)
  {
    symbol_typet base("java::"+id2string(interface));
    class_type.add_base(base);
  }

  // produce class symbol
  symbolt new_symbol;
  new_symbol.base_name=c.name;
  new_symbol.pretty_name=c.name;
  new_symbol.name="java::"+id2string(c.name);
  class_type.set(ID_name, new_symbol.name);
  new_symbol.type=class_type;
  new_symbol.mode=ID_java;
  new_symbol.is_type=true;

  symbolt *class_symbol;

  // add before we do members
  if(symbol_table.move(new_symbol, class_symbol))
  {
    error() << "failed to add class symbol " << new_symbol.name << eom;
    throw 0;
  }

  // now do fields
  for(const auto &field : c.fields)
    convert(*class_symbol, field);

  // now do methods
  for(const auto &method : c.methods)
    java_bytecode_convert_method(
      *class_symbol,
      method,
      symbol_table,
      get_message_handler(),
      disable_runtime_checks,
      max_array_length);

  // is this a root class?
  if(c.extends.empty())
    java_root_class(*class_symbol);
}
示例#21
0
bool cbmc_parseoptionst::get_goto_program(
  const optionst &options,
  bmct &bmc,
  goto_functionst &goto_functions)
{
  if(cmdline.args.size()==0)
  {
    error("Please provide a program to verify");
    return true;
  }

  try
  {
    if(cmdline.args.size()==1 &&
       is_goto_binary(cmdline.args[0]))
    {
      status("Reading GOTO program from file");

      if(read_goto_binary(cmdline.args[0],
           context, goto_functions, get_message_handler()))
        return true;
        
      config.ansi_c.set_from_context(context);

      if(cmdline.isset("show-symbol-table"))
      {
        show_symbol_table();
        return true;
      }
      
      if(context.symbols.find(ID_main)==context.symbols.end())
      {
        error("The goto binary has no entry point; please complete linking");
        return true;
      }
    }
    else
    {
      if(parse()) return true;
      if(typecheck()) return true;
      if(get_modules(bmc)) return true;    
      if(final()) return true;

      // we no longer need any parse trees or language files
      clear_parse();

      if(cmdline.isset("show-symbol-table"))
      {
        show_symbol_table();
        return true;
      }

      if(context.symbols.find(ID_main)==context.symbols.end())
      {
        error("No entry point; please provide a main function");
        return true;
      }

      status("Generating GOTO Program");

      goto_convert(
        context, options, goto_functions,
        ui_message_handler);
    }

    // finally add the library
    status("Adding CPROVER library");      
    link_to_library(
      context, goto_functions, options, ui_message_handler);

    if(process_goto_program(options, goto_functions))
      return true;
  }

  catch(const char *e)
  {
    error(e);
    return true;
  }

  catch(const std::string e)
  {
    error(e);
    return true;
  }
  
  catch(int)
  {
    return true;
  }
  
  catch(std::bad_alloc)
  {
    error("Out of memory");
    return true;
  }
  
  return false;
}
示例#22
0
int symex_parseoptionst::doit()
{
  if(cmdline.isset("version"))
  {
    std::cout << CBMC_VERSION << std::endl;
    return 0;
  }

  register_language(new_ansi_c_language);
  register_language(new_cpp_language);

  //
  // command line options
  //

  optionst options;
  get_command_line_options(options);

  eval_verbosity();

  goto_functionst goto_functions;

  if(get_goto_program(options, goto_functions))
    return 6;
    
  label_properties(goto_functions);

  if(cmdline.isset("show-properties"))
  {
    const namespacet ns(symbol_table);
    show_properties(ns, get_ui(), goto_functions);
    return 0;
  }

  if(set_properties(goto_functions))
    return 7;
    
  if(cmdline.isset("show-locs"))
  {
    const namespacet ns(symbol_table);
    locst locs(ns);
    locs.build(goto_functions);
    locs.output(std::cout);    
    return 0;
  }

  // do actual Symex

  try
  {
    const namespacet ns(symbol_table);
    path_searcht path_search(ns);
    
    path_search.set_message_handler(get_message_handler());

    if(cmdline.isset("depth"))
      path_search.set_depth_limit(unsafe_string2unsigned(cmdline.get_value("depth")));

    if(cmdline.isset("context-bound"))
      path_search.set_context_bound(unsafe_string2unsigned(cmdline.get_value("context-bound")));

    if(cmdline.isset("unwind"))
      path_search.set_unwind_limit(unsafe_string2unsigned(cmdline.get_value("unwind")));

    if(cmdline.isset("show-vcc"))
    {
      path_search.show_vcc=true;
      path_search(goto_functions);
      return 0;
    }

    // do actual symex
    switch(path_search(goto_functions))
    {
    case safety_checkert::SAFE:
      report_properties(path_search.property_map);
      report_success();
      return 0;
    
    case safety_checkert::UNSAFE:
      report_properties(path_search.property_map);
      report_failure();
      return 10;
    
    default:
      return 8;
    }
  }
  
  catch(const std::string error_msg)
  {
    error() << error_msg << messaget::eom;
    return 8;
  }

  catch(const char *error_msg)
  {
    error() << error_msg << messaget::eom;
    return 8;
  }

  #if 0                                         
  // let's log some more statistics
  debug() << "Memory consumption:" << messaget::endl;
  memory_info(debug());
  debug() << eom;
  #endif
}
示例#23
0
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();
}
示例#24
0
bool symex_parseoptionst::get_goto_program(
  const optionst &options,
  goto_functionst &goto_functions)
{
  if(cmdline.args.size()==0)
  {
    error() << "Please provide a program to verify" << eom;
    return true;
  }

  try
  {
    if(cmdline.args.size()==1 &&
       is_goto_binary(cmdline.args[0]))
    {
      status() << "Reading GOTO program from file" << eom;

      if(read_goto_binary(cmdline.args[0],
           symbol_table, goto_functions, get_message_handler()))
        return true;
        
      config.ansi_c.set_from_symbol_table(symbol_table);

      if(cmdline.isset("show-symbol-table"))
      {
        show_symbol_table();
        return true;
      }
      
      irep_idt entry_point=goto_functions.entry_point();
      
      if(symbol_table.symbols.find(entry_point)==symbol_table.symbols.end())
      {
        error() << "The goto binary has no entry point; please complete linking" << eom;
        return true;
      }
    }
    else if(cmdline.isset("show-parse-tree"))
    {
      if(cmdline.args.size()!=1)
      {
        error() << "Please give one source file only" << eom;
        return true;
      }
      
      std::string filename=cmdline.args[0];
      
      #ifdef _MSC_VER
      std::ifstream infile(widen(filename).c_str());
      #else
      std::ifstream infile(filename.c_str());
      #endif
                
      if(!infile)
      {
        error() << "failed to open input file `" << filename << "'" << eom;
        return true;
      }
                              
      languaget *language=get_language_from_filename(filename);
                                                
      if(language==NULL)
      {
        error() << "failed to figure out type of file `" <<  filename << "'" << eom;
        return true;
      }
      
      language->set_message_handler(get_message_handler());
                                                                
      status("Parsing", filename);
  
      if(language->parse(infile, filename))
      {
        error() << "PARSING ERROR" << eom;
        return true;
      }
      
      language->show_parse(std::cout);
      return true;
    }
    else
    {
    
      if(parse()) return true;
      if(typecheck()) return true;
      if(final()) return true;

      // we no longer need any parse trees or language files
      clear_parse();

      if(cmdline.isset("show-symbol-table"))
      {
        show_symbol_table();
        return true;
      }

      irep_idt entry_point=goto_functions.entry_point();
      
      if(symbol_table.symbols.find(entry_point)==symbol_table.symbols.end())
      {
        error() << "No entry point; please provide a main function" << eom;
        return true;
      }

      status() << "Generating GOTO Program" << eom;

      goto_convert(symbol_table, goto_functions, ui_message_handler);
    }

    // finally add the library
    status() << "Adding CPROVER library" << eom;
    link_to_library(symbol_table, goto_functions, ui_message_handler);

    if(process_goto_program(options, goto_functions))
      return true;
  }

  catch(const char *e)
  {
    error() << e << eom;
    return true;
  }

  catch(const std::string e)
  {
    error() << e << eom;
    return true;
  }
  
  catch(int)
  {
    return true;
  }
  
  catch(std::bad_alloc)
  {
    error() << "Out of memory" << eom;
    return true;
  }
  
  return false;
}
示例#25
0
RedClient::RedClient(Application& application)
    : RedChannel(*this, SPICE_CHANNEL_MAIN, 0, new MainChannelLoop(*this))
    , _application (application)
    , _port (-1)
    , _sport (-1)
    , _protocol (0)
    , _connection_id (0)
    , _mouse_mode (SPICE_MOUSE_MODE_SERVER)
    , _notify_disconnect (false)
    , _auto_display_res (false)
    , _agent_reply_wait_type (VD_AGENT_END_MESSAGE)
    , _aborting (false)
    , _msg_attach_channels_sent(false)
    , _agent_connected (false)
    , _agent_mon_config_sent (false)
    , _agent_disp_config_sent (false)
    , _agent_msg (new VDAgentMessage)
    , _agent_msg_data (NULL)
    , _agent_msg_pos (0)
    , _agent_out_msg (NULL)
    , _agent_out_msg_size (0)
    , _agent_out_msg_pos (0)
    , _agent_tokens (0)
    , _agent_timer (new AgentTimer(this))
    , _agent_caps_size(0)
    , _agent_caps(NULL)
    , _migrate (*this)
    , _glz_window (_glz_debug)
    , _during_migration (false)
{
    Platform::set_clipboard_listener(this);
    MainChannelLoop* message_loop = static_cast<MainChannelLoop*>(get_message_handler());
    uint32_t default_caps_size = SPICE_N_ELEMENTS(default_agent_caps);

    _agent_caps_size = VD_AGENT_CAPS_SIZE;
    ASSERT(VD_AGENT_CAPS_SIZE >= default_caps_size);
    _agent_caps = new uint32_t[_agent_caps_size];
    memcpy(_agent_caps, default_agent_caps, default_caps_size);
    message_loop->set_handler(SPICE_MSG_MIGRATE, &RedClient::handle_migrate);
    message_loop->set_handler(SPICE_MSG_SET_ACK, &RedClient::handle_set_ack);
    message_loop->set_handler(SPICE_MSG_PING, &RedClient::handle_ping);
    message_loop->set_handler(SPICE_MSG_WAIT_FOR_CHANNELS, &RedClient::handle_wait_for_channels);
    message_loop->set_handler(SPICE_MSG_DISCONNECTING, &RedClient::handle_disconnect);
    message_loop->set_handler(SPICE_MSG_NOTIFY, &RedClient::handle_notify);

    message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_BEGIN, &RedClient::handle_migrate_begin);
    message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_CANCEL, &RedClient::handle_migrate_cancel);
    message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_END, &RedClient::handle_migrate_end);
    message_loop->set_handler(SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST,
                              &RedClient::handle_migrate_switch_host);
    message_loop->set_handler(SPICE_MSG_MAIN_INIT, &RedClient::handle_init);
    message_loop->set_handler(SPICE_MSG_MAIN_CHANNELS_LIST, &RedClient::handle_channels);
    message_loop->set_handler(SPICE_MSG_MAIN_MOUSE_MODE, &RedClient::handle_mouse_mode);
    message_loop->set_handler(SPICE_MSG_MAIN_MULTI_MEDIA_TIME, &RedClient::handle_mm_time);

    message_loop->set_handler(SPICE_MSG_MAIN_AGENT_CONNECTED, &RedClient::handle_agent_connected);
    message_loop->set_handler(SPICE_MSG_MAIN_AGENT_DISCONNECTED, &RedClient::handle_agent_disconnected);
    message_loop->set_handler(SPICE_MSG_MAIN_AGENT_DATA, &RedClient::handle_agent_data);
    message_loop->set_handler(SPICE_MSG_MAIN_AGENT_TOKEN, &RedClient::handle_agent_tokens);

    set_capability(SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE);
    start();
}
示例#26
0
void goto_fence_inserter_parse_optionst::instrument_goto_program(
  goto_functionst &goto_functions)
{
  optionst options;

  // unwind loops
  if(cmdline.isset("unwind"))
  {
    status() << "Unwinding loops" << eom;
    options.set_option("unwind", cmdline.get_value("unwind"));
  }

  // we add the library, as some analyses benefit

  status() << "Adding CPROVER library" << eom;
  link_to_library(symbol_table, goto_functions, ui_message_handler);

  namespacet ns(symbol_table);

  if( cmdline.isset("mm")
      || cmdline.isset("all-shared")
      || cmdline.isset("volatile")
      || cmdline.isset("pensieve")
      || cmdline.isset("naive")
      || cmdline.isset("all-shared-aeg") )
  {
    if(cmdline.isset("remove-function-pointers"))
    {
      status() << "remove soundly function pointers" << eom;
      remove_function_pointers(symbol_table, goto_functions,
        cmdline.isset("pointer-check"));
    }

    if(cmdline.isset("async"))
    {
      status() << "Replace pthread_creates by __CPROVER_ASYNC_0:" << eom;
      replace_async(ns, goto_functions);
      goto_functions.update();
    }

    // do partial inlining
    status() << "Partial Inlining" << eom;
    goto_partial_inline(goto_functions, ns, ui_message_handler);

    if(cmdline.isset("const-function-pointer-propagation"))
    {
      /* propagate const pointers to functions */
      status() << "Propagate Constant Function Pointers" << eom;
      propagate_const_function_pointers(symbol_table, goto_functions,
        get_message_handler());
    }

    // goto_functions.output(ns, std::cout);
    // return;
#if 0
    status() << "Function Pointer Removal" << eom;
    remove_function_pointers(symbol_table, goto_functions,
      cmdline.isset("pointer-check"));
#endif

#if 0
    // do partial inlining
    status() << "Partial Inlining" << eom;
    goto_partial_inline(goto_functions, ns, ui_message_handler);
#endif

    status() << "Pointer Analysis" << eom;
#ifdef POINTER_ANALYSIS_FI
    value_set_analysis_fit value_set_analysis(ns);
#else
    value_set_analysist value_set_analysis(ns);
#endif

#ifndef LOCAL_MAY
    value_set_analysis(goto_functions);
#endif

    status() << "Removing asm code" << eom;
    remove_asm(symbol_table, goto_functions);
    goto_functions.update();

    if(cmdline.isset("all-shared"))
    {
      status() << "Shared variables accesses detection" << eom;
      fence_all_shared(get_message_handler(), value_set_analysis, symbol_table,
        goto_functions);
      // simple analysis, coupled with script to insert;
      // does not transform the goto-binary
      return;
    }
    if(cmdline.isset("all-shared-aeg"))
    {
      status() << "Shared variables accesses detection (CF)" << eom;
      fence_all_shared_aeg(get_message_handler(), value_set_analysis,
        symbol_table, goto_functions);
      // simple analysis, coupled with script to insert;
      // does not transform the goto-binary
      return;
    }
    else if(cmdline.isset("volatile"))
    {
      status() << "Detection of variables declared volatile" << eom;

      fence_volatile(get_message_handler(), value_set_analysis, symbol_table,
        goto_functions);
      // simple analysis, coupled with script to insert;
      // does not transform the goto-binary
      return;
    }
    else if(cmdline.isset("pensieve") || cmdline.isset("naive"))
    {
      status() << "Delay-set analysis" << eom;

      const unsigned unwind_loops=
        cmdline.isset("unwind") ?
        unsafe_string2unsigned(cmdline.get_value("unwind")) : 0;

      const unsigned max_po_trans=
        cmdline.isset("max-po-trans") ?
        unsafe_string2unsigned(cmdline.get_value("max-po-trans")) : 0;

      fence_pensieve(
        value_set_analysis,
        symbol_table,
        goto_functions,
        unwind_loops,
        max_po_trans,
        !cmdline.isset("no-po-rendering"),
        cmdline.isset("render-cluster-file"),
        cmdline.isset("render-cluster-function"),
        cmdline.isset("naive"),
        get_message_handler());
        // simple analysis, coupled with script to insert;
        // does not transform the goto-binary
        return;
    }
    else if(cmdline.isset("mm"))
    {
      std::string mm=cmdline.get_value("mm");
      memory_modelt model;

      status() << "Fence detection for " << mm
        << " via critical cycles and ILP" << eom;

      // strategy of instrumentation
      instrumentation_strategyt inst_strategy;
      if(cmdline.isset("one-event-per-cycle"))
        inst_strategy=one_event_per_cycle;
      else if(cmdline.isset("minimum-interference"))
        inst_strategy=min_interference;
      else if(cmdline.isset("read-first"))
        inst_strategy=read_first;
      else if(cmdline.isset("write-first"))
        inst_strategy=write_first;
      else if(cmdline.isset("my-events"))
        inst_strategy=my_events;
      else
        /* default: instruments all unsafe pairs */
        inst_strategy=all;

      const unsigned unwind_loops =
        cmdline.isset("unwind") ?
        unsafe_string2unsigned(cmdline.get_value("unwind")) : 0;

      const unsigned max_var =
        cmdline.isset("max-var") ?
        unsafe_string2unsigned(cmdline.get_value("max-var")) : 0;

      const unsigned max_po_trans =
        cmdline.isset("max-po-trans") ?
        unsafe_string2unsigned(cmdline.get_value("max-po-trans")) : 0;

      if(mm=="tso")
      {
        status() << "Adding weak memory (TSO) Instrumentation" << eom;
        model=TSO;
      }
      else if(mm=="pso")
      {
        status() << "Adding weak memory (PSO) Instrumentation" << eom;
        model=PSO;
      }
      else if(mm=="rmo")
      {
        status() << "Adding weak memory (RMO) Instrumentation" << eom;
        model=RMO;
      }
      else if(mm=="power")
      {
        status() << "Adding weak memory (Power) Instrumentation" << eom;
        model=Power;
      }
      else
      {
        status/*error*/() << "Unknown weak memory model" << eom;
        model=Unknown;
      }

      /* inference mode */
      infer_modet infer_mode=INFER;

      if(cmdline.isset("userdef"))
        infer_mode=USER_DEF;

      loop_strategyt loops=arrays_only;

      if(cmdline.isset("force-loop-duplication"))
        loops=all_loops;
      if(cmdline.isset("no-loop-duplication"))
        loops=no_loop;

      /*if(model!=Unknown)*/
        fence_weak_memory(
          model,
          value_set_analysis,
          symbol_table,
          goto_functions,
          cmdline.isset("scc"),
          inst_strategy,
          unwind_loops,
          !cmdline.isset("cfg-kill"),
          cmdline.isset("no-dependencies"),
          loops,
          max_var,
          max_po_trans,
          !cmdline.isset("no-po-rendering"),
          cmdline.isset("render-cluster-file"),
          cmdline.isset("render-cluster-function"),
          cmdline.isset("cav11"),
          cmdline.isset("hide-internals"),
          cmdline.isset("print-graph"),
          infer_mode,
          get_message_handler(),
          cmdline.isset("ignore-arrays"));
    }
  }

  // add failed symbols
  add_failed_symbols(symbol_table);

  // recalculate numbers, etc.
  goto_functions.update();

  // add loop ids
  goto_functions.compute_loop_numbers();

  // label the assertions
  label_properties(goto_functions);
}