void show_goto_functions(
  const namespacet &ns,
  ui_message_handlert::uit ui,
  const goto_functionst &goto_functions)
{
  switch(ui)
  {
  case ui_message_handlert::XML_UI:
  {
    show_goto_functions_xmlt xml_show_functions(ns);
    xml_show_functions(goto_functions, std::cout);
  }
  break;

  case ui_message_handlert::JSON_UI:
  {
    show_goto_functions_jsont json_show_functions(ns);
    json_show_functions(goto_functions, std::cout);
  }
  break;

  case ui_message_handlert::PLAIN:
    goto_functions.output(ns, std::cout);
    break;
  }
}
Beispiel #2
0
void stack_depth(
  symbol_tablet &symbol_table,
  goto_functionst &goto_functions,
  const int depth)
{
  const symbol_exprt sym=add_stack_depth_symbol(symbol_table);
  const exprt depth_expr(from_integer(depth, sym.type()));

  Forall_goto_functions(f_it, goto_functions)
    if(f_it->second.body_available &&
        f_it->first!=CPROVER_PREFIX "initialize" &&
        f_it->first!=ID_main)
      stack_depth(f_it->second.body, sym, depth, depth_expr);

  // initialize depth to 0
  goto_functionst::function_mapt::iterator
    i_it=goto_functions.function_map.find(CPROVER_PREFIX "initialize");
  assert(i_it!=goto_functions.function_map.end());

  goto_programt &init=i_it->second.body;
  goto_programt::targett first=init.instructions.begin();
  goto_programt::targett it=init.insert_before(first);
  it->make_assignment();
  it->code=code_assignt(sym, from_integer(0, sym.type()));
  it->location=first->location;
  it->function=first->function;

  // update counters etc.
  goto_functions.update();
}
Beispiel #3
0
void add_cegis_library(symbol_tablet &st, goto_functionst &gf,
    message_handlert &msg, const size_t num_vars, const size_t num_consts,
    const size_t max_solution_size, const std::string &func_name)
{
  add_execute_placeholder(st, func_name, cegis_execute_type());
  std::set<irep_idt> functions;
  functions.insert(func_name);
  const std::string library_src(
      get_cegis_library_text(num_vars, num_consts, max_solution_size,
          func_name));

  add_library(library_src, st, msg);
  goto_convert(func_name, st, gf, msg);
  gf.compute_loop_numbers();
  gf.update();
  set_init_values(st, gf);
}
Beispiel #4
0
void nondet_static(
  const namespacet &ns,
  goto_functionst &goto_functions)
{
  nondet_static(ns, goto_functions, CPROVER_PREFIX "initialize");

  // update counters etc.
  goto_functions.update();
}
void remove_virtual_functionst::operator()(goto_functionst &functions)
{
  bool did_something=false;

  for(goto_functionst::function_mapt::iterator f_it=
      functions.function_map.begin();
      f_it!=functions.function_map.end();
      f_it++)
  {
    goto_programt &goto_program=f_it->second.body;

    if(remove_virtual_functions(goto_program))
      did_something=true;
  }

  if(did_something)
    functions.compute_location_numbers();
}
Beispiel #6
0
bool skip_loops(
  goto_functionst &goto_functions,
  const std::string &loop_ids,
  message_handlert &message_handler)
{
  messaget message(message_handler);

  loop_mapt loop_map;
  if(parse_loop_ids(loop_ids, loop_map))
  {
    message.error() << "Failed to parse loop ids" << messaget::eom;
    return true;
  }

  loop_mapt::const_iterator it=loop_map.begin();
  Forall_goto_functions(f_it, goto_functions)
  {
    if(it==loop_map.end() || it->first<f_it->first)
      break; // possible error handled below
    else if(it->first==f_it->first)
    {
      if(skip_loops(f_it->second.body, it->second, message))
        return true;
      ++it;
    }
  }
  if(it!=loop_map.end())
  {
    message.error() << "No function " << it->first << " in goto program"
                    << messaget::eom;
    return true;
  }

  // update counters etc.
  goto_functions.update();

  return false;
}
Beispiel #7
0
bool symex_parseoptionst::process_goto_program(
  const optionst &options,
  goto_functionst &goto_functions)
{
  try
  {
    namespacet ns(symbol_table);

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

    // add generic checks
    status() << "Generic Property Instrumentation" << eom;
    goto_check(ns, options, goto_functions);

    // 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_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);
    return true;
  }

  catch(const std::string e)
  {
    error(e);
    return true;
  }

  catch(int)
  {
    return true;
  }

  catch(std::bad_alloc)
  {
    error() << "Out of memory" << eom;
    return true;
  }

  return false;
}
Beispiel #8
0
bool symex_parseoptionst::get_goto_program(
  const optionst &options,
  goto_functionst &goto_functions)
{
  if(cmdline.args.empty())
  {
    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;
      }

      status("Parsing", filename);

      if(language->parse(infile, filename, get_message_handler()))
      {
        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);
    return true;
  }

  catch(const std::string e)
  {
    error(e);
    return true;
  }

  catch(int)
  {
    return true;
  }

  catch(std::bad_alloc)
  {
    error() << "Out of memory" << eom;
    return true;
  }

  return false;
}
bool read_bin_goto_object_v3(
  std::istream &in,
  const std::string &filename,
  symbol_tablet &symbol_table,
  goto_functionst &functions,
  message_handlert &message_handler,
  irep_serializationt &irepconverter)
{
  std::size_t count = irepconverter.read_gb_word(in); // # of symbols

  for(std::size_t i=0; i<count; i++)
  {
    symbolt sym;

    irepconverter.reference_convert(in, sym.type);
    irepconverter.reference_convert(in, sym.value);
    irepconverter.reference_convert(in, sym.location);

    sym.name = irepconverter.read_string_ref(in);
    sym.module = irepconverter.read_string_ref(in);
    sym.base_name = irepconverter.read_string_ref(in);
    sym.mode = irepconverter.read_string_ref(in);
    sym.pretty_name = irepconverter.read_string_ref(in);

    // obsolete: symordering
    irepconverter.read_gb_word(in);

    std::size_t flags=irepconverter.read_gb_word(in);

    sym.is_weak = (flags &(1 << 16))!=0;
    sym.is_type = (flags &(1 << 15))!=0;
    sym.is_property = (flags &(1 << 14))!=0;
    sym.is_macro = (flags &(1 << 13))!=0;
    sym.is_exported = (flags &(1 << 12))!=0;
    sym.is_input = (flags &(1 << 11))!=0;
    sym.is_output = (flags &(1 << 10))!=0;
    sym.is_state_var = (flags &(1 << 9))!=0;
    sym.is_parameter = (flags &(1 << 8))!=0;
    sym.is_auxiliary = (flags &(1 << 7))!=0;
    // sym.binding = (flags &(1 << 6))!=0;
    sym.is_lvalue = (flags &(1 << 5))!=0;
    sym.is_static_lifetime = (flags &(1 << 4))!=0;
    sym.is_thread_local = (flags &(1 << 3))!=0;
    sym.is_file_local = (flags &(1 << 2))!=0;
    sym.is_extern = (flags &(1 << 1))!=0;
    sym.is_volatile = (flags &1)!=0;

    if(!sym.is_type && sym.type.id()==ID_code)
    {
      // makes sure there is an empty function
      // for every function symbol and fixes
      // the function types.
      functions.function_map[sym.name].type=to_code_type(sym.type);
    }

    symbol_table.add(sym);
  }

  count=irepconverter.read_gb_word(in); // # of functions

  for(std::size_t i=0; i<count; i++)
  {
    irep_idt fname=irepconverter.read_gb_string(in);
    goto_functionst::goto_functiont &f = functions.function_map[fname];

    typedef std::map<goto_programt::targett, std::list<unsigned> > target_mapt;
    target_mapt target_map;
    typedef std::map<unsigned, goto_programt::targett> rev_target_mapt;
    rev_target_mapt rev_target_map;

    bool hidden=false;

    std::size_t ins_count = irepconverter.read_gb_word(in); // # of instructions
    for(std::size_t i=0; i<ins_count; i++)
    {
      goto_programt::targett itarget = f.body.add_instruction();
      goto_programt::instructiont &instruction=*itarget;

      irepconverter.reference_convert(in, instruction.code);
      instruction.function = irepconverter.read_string_ref(in);
      irepconverter.reference_convert(in, instruction.source_location);
      instruction.type = (goto_program_instruction_typet)
                              irepconverter.read_gb_word(in);
      instruction.guard.make_nil();
      irepconverter.reference_convert(in, instruction.guard);
      irepconverter.read_string_ref(in); // former event
      instruction.target_number = irepconverter.read_gb_word(in);
      if(instruction.is_target() &&
         rev_target_map.insert(
           rev_target_map.end(),
           std::make_pair(instruction.target_number, itarget))->second!=itarget)
        assert(false);

      std::size_t t_count = irepconverter.read_gb_word(in); // # of targets
      for(std::size_t i=0; i<t_count; i++)
        // just save the target numbers
        target_map[itarget].push_back(irepconverter.read_gb_word(in));

      std::size_t l_count = irepconverter.read_gb_word(in); // # of labels

      for(std::size_t i=0; i<l_count; i++)
      {
        irep_idt label=irepconverter.read_string_ref(in);
        instruction.labels.push_back(label);
        if(label=="__CPROVER_HIDE")
          hidden=true;
        // The above info is normally in the type of the goto_functiont object,
        // which should likely be stored in the binary.
      }
    }

    // Resolve targets
    for(target_mapt::iterator tit = target_map.begin();
        tit!=target_map.end();
        tit++)
    {
      goto_programt::targett ins = tit->first;

      for(std::list<unsigned>::iterator nit = tit->second.begin();
          nit!=tit->second.end();
          nit++)
      {
        unsigned n=*nit;
        rev_target_mapt::const_iterator entry=rev_target_map.find(n);
        assert(entry!=rev_target_map.end());
        ins->targets.push_back(entry->second);
      }
    }

    f.body.update();

    if(hidden)
      f.make_hidden();
  }

  functions.compute_location_numbers();

  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;
}
Beispiel #11
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;
}
Beispiel #12
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);
}