CBMC
jbmc_parse_options.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: JBMC Command Line Option Processing
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include "jbmc_parse_options.h"
13 
14 #include <util/config.h>
15 #include <util/exit_codes.h>
16 #include <util/help_formatter.h>
17 #include <util/invariant.h>
18 #include <util/version.h>
19 #include <util/xml.h>
20 
25 #include <goto-programs/loop_ids.h>
34 
35 #include <ansi-c/ansi_c_language.h>
57 #include <langapi/language.h>
58 #include <langapi/mode.h>
61 
62 #include <cstdlib> // exit()
63 #include <iostream>
64 #include <memory>
65 
66 jbmc_parse_optionst::jbmc_parse_optionst(int argc, const char **argv)
69  argc,
70  argv,
71  std::string("JBMC ") + CBMC_VERSION)
72 {
75 }
76 
78  int argc,
79  const char **argv,
80  const std::string &extra_options)
82  JBMC_OPTIONS + extra_options,
83  argc,
84  argv,
85  std::string("JBMC ") + CBMC_VERSION)
86 {
89 }
90 
92 {
93  // Default true
94  options.set_option("assertions", true);
95  options.set_option("assumptions", true);
96  options.set_option("built-in-assertions", true);
97  options.set_option("propagation", true);
98  options.set_option("refine-strings", true);
99  options.set_option("simple-slice", true);
100  options.set_option("simplify", true);
101  options.set_option("show-goto-symex-steps", false);
102 
103  // Other default
104  options.set_option("arrays-uf", "auto");
105  options.set_option("depth", UINT32_MAX);
106 }
107 
109 {
110  if(config.set(cmdline))
111  {
112  usage_error();
113  exit(1); // should contemplate EX_USAGE from sysexits.h
114  }
115 
117 
118  if(cmdline.isset("function"))
119  options.set_option("function", cmdline.get_value("function"));
120 
123 
124  if(cmdline.isset("max-field-sensitivity-array-size"))
125  {
126  options.set_option(
127  "max-field-sensitivity-array-size",
128  cmdline.get_value("max-field-sensitivity-array-size"));
129  }
130 
131  if(cmdline.isset("no-array-field-sensitivity"))
132  {
133  if(cmdline.isset("max-field-sensitivity-array-size"))
134  {
135  log.error()
136  << "--no-array-field-sensitivity and --max-field-sensitivity-array-size"
137  << " must not be given together" << messaget::eom;
139  }
140  options.set_option("no-array-field-sensitivity", true);
141  }
142 
143  if(cmdline.isset("show-symex-strategies"))
144  {
147  }
148 
150 
151  if(cmdline.isset("program-only"))
152  options.set_option("program-only", true);
153 
154  if(cmdline.isset("show-vcc"))
155  options.set_option("show-vcc", true);
156 
157  if(cmdline.isset("nondet-static"))
158  options.set_option("nondet-static", true);
159 
160  if(cmdline.isset("no-simplify"))
161  options.set_option("simplify", false);
162 
163  if(cmdline.isset("stop-on-fail") ||
164  cmdline.isset("dimacs") ||
165  cmdline.isset("outfile"))
166  options.set_option("stop-on-fail", true);
167 
168  if(
169  cmdline.isset("trace") || cmdline.isset("compact-trace") ||
170  cmdline.isset("stack-trace") || cmdline.isset("stop-on-fail") ||
172  !cmdline.isset("cover")))
173  {
174  options.set_option("trace", true);
175  }
176 
177  if(cmdline.isset("validate-trace"))
178  {
179  options.set_option("validate-trace", true);
180  options.set_option("trace", true);
181  }
182 
183  if(cmdline.isset("localize-faults"))
184  options.set_option("localize-faults", true);
185 
186  if(cmdline.isset("symex-complexity-limit"))
187  {
188  options.set_option(
189  "symex-complexity-limit", cmdline.get_value("symex-complexity-limit"));
190  log.warning() << "**** WARNING: Complexity-limited analysis may yield "
191  "unsound verification results"
192  << messaget::eom;
193  }
194 
195  if(cmdline.isset("symex-complexity-failed-child-loops-limit"))
196  {
197  options.set_option(
198  "symex-complexity-failed-child-loops-limit",
199  cmdline.get_value("symex-complexity-failed-child-loops-limit"));
200  if(!cmdline.isset("symex-complexity-limit"))
201  {
202  log.warning() << "**** WARNING: Complexity-limited analysis may yield "
203  "unsound verification results"
204  << messaget::eom;
205  }
206  }
207 
208  if(cmdline.isset("unwind"))
209  {
210  options.set_option("unwind", cmdline.get_value("unwind"));
211  if(!cmdline.isset("unwinding-assertions"))
212  {
213  log.warning() << "**** WARNING: Use --unwinding-assertions to obtain "
214  "sound verification results"
215  << messaget::eom;
216  }
217  }
218 
219  if(cmdline.isset("depth"))
220  {
221  options.set_option("depth", cmdline.get_value("depth"));
222  log.warning()
223  << "**** WARNING: Depth-bounded analysis may yield unsound verification "
224  "results"
225  << messaget::eom;
226  }
227 
228  if(cmdline.isset("unwindset"))
229  {
230  options.set_option(
231  "unwindset", cmdline.get_comma_separated_values("unwindset"));
232  if(!cmdline.isset("unwinding-assertions"))
233  {
234  log.warning() << "**** WARNING: Use --unwinding-assertions to obtain "
235  "sound verification results"
236  << messaget::eom;
237  }
238  }
239 
240  // constant propagation
241  if(cmdline.isset("no-propagation"))
242  options.set_option("propagation", false);
243 
244  // transform self loops to assumptions
245  options.set_option(
246  "self-loops-to-assumptions",
247  !cmdline.isset("no-self-loops-to-assumptions"));
248 
249  // unwind loops in java enum static initialization
250  if(cmdline.isset("java-unwind-enum-static"))
251  options.set_option("java-unwind-enum-static", true);
252 
253  // check assertions
254  if(cmdline.isset("no-assertions"))
255  options.set_option("assertions", false);
256 
257  // use assumptions
258  if(cmdline.isset("no-assumptions"))
259  options.set_option("assumptions", false);
260 
261  // generate unwinding assertions
262  if(cmdline.isset("unwinding-assertions"))
263  options.set_option("unwinding-assertions", true);
264 
265  // generate unwinding assumptions otherwise
266  if(cmdline.isset("partial-loops"))
267  {
268  options.set_option("partial-loops", true);
269  log.warning()
270  << "**** WARNING: --partial-loops may yield unsound verification results"
271  << messaget::eom;
272  }
273 
274  // remove unused equations
275  options.set_option(
276  "slice-formula",
277  cmdline.isset("slice-formula"));
278 
279  if(cmdline.isset("arrays-uf-always"))
280  options.set_option("arrays-uf", "always");
281  else if(cmdline.isset("arrays-uf-never"))
282  options.set_option("arrays-uf", "never");
283 
284  if(cmdline.isset("no-refine-strings"))
285  options.set_option("refine-strings", false);
286 
287  if(cmdline.isset("string-printable") && cmdline.isset("no-refine-strings"))
288  {
290  "cannot use --string-printable with --no-refine-strings",
291  "--string-printable");
292  }
293 
294  if(cmdline.isset("string-input-value") && cmdline.isset("no-refine-strings"))
295  {
297  "cannot use --string-input-value with --no-refine-strings",
298  "--string-input-value");
299  }
300 
301  if(
302  cmdline.isset("no-refine-strings") &&
303  cmdline.isset("max-nondet-string-length"))
304  {
306  "cannot use --max-nondet-string-length with --no-refine-strings",
307  "--max-nondet-string-length");
308  }
309 
310  if(cmdline.isset("graphml-witness"))
311  {
312  options.set_option("graphml-witness", cmdline.get_value("graphml-witness"));
313  options.set_option("stop-on-fail", true);
314  options.set_option("trace", true);
315  }
316 
317  if(cmdline.isset("symex-coverage-report"))
318  options.set_option(
319  "symex-coverage-report",
320  cmdline.get_value("symex-coverage-report"));
321 
322  if(cmdline.isset("validate-ssa-equation"))
323  {
324  options.set_option("validate-ssa-equation", true);
325  }
326 
327  if(cmdline.isset("validate-goto-model"))
328  {
329  options.set_option("validate-goto-model", true);
330  }
331 
332  options.set_option(
333  "symex-cache-dereferences", cmdline.isset("symex-cache-dereferences"));
334 
336 
337  if(cmdline.isset("symex-driven-lazy-loading"))
338  {
339  options.set_option("symex-driven-lazy-loading", true);
340  for(const char *opt :
341  { "nondet-static",
342  "full-slice",
343  "reachability-slice",
344  "reachability-slice-fb" })
345  {
346  if(cmdline.isset(opt))
347  {
348  throw std::string("Option ") + opt +
349  " can't be used with --symex-driven-lazy-loading";
350  }
351  }
352  }
353 
354  // The 'allow-pointer-unsoundness' option prevents symex from throwing an
355  // exception when it encounters pointers that are shared across threads.
356  // This is unsound but given that pointers are ubiquitous in java this check
357  // must be disabled in order to support the analysis of multithreaded java
358  // code.
359  if(cmdline.isset("java-threading"))
360  options.set_option("allow-pointer-unsoundness", true);
361 
362  if(cmdline.isset("show-goto-symex-steps"))
363  options.set_option("show-goto-symex-steps", true);
364 
365  if(cmdline.isset("smt1"))
366  {
367  log.error() << "--smt1 is no longer supported" << messaget::eom;
369  }
370 
371  parse_solver_options(cmdline, options);
372 }
373 
376 {
377  if(cmdline.isset("version"))
378  {
379  std::cout << CBMC_VERSION << '\n';
380  return CPROVER_EXIT_SUCCESS;
381  }
382 
385 
386  //
387  // command line options
388  //
389 
390  optionst options;
391  get_command_line_options(options);
392 
394 
395  // output the options
396  switch(ui_message_handler.get_ui())
397  {
400  log.debug(), [&options](messaget::mstreamt &debug_stream) {
401  debug_stream << "\nOptions: \n";
402  options.output(debug_stream);
403  debug_stream << messaget::eom;
404  });
405  break;
407  {
408  json_objectt json_options{{"options", options.to_json()}};
409  log.debug() << json_options;
410  break;
411  }
413  log.debug() << options.to_xml();
414  break;
415  }
416 
419 
420  if(!((cmdline.isset("jar") && cmdline.args.empty()) ||
421  (cmdline.isset("gb") && cmdline.args.empty()) ||
422  (!cmdline.isset("jar") && !cmdline.isset("gb") &&
423  (cmdline.args.size() == 1))))
424  {
425  log.error() << "Please give exactly one class name, "
426  << "and/or use -jar jarfile or --gb goto-binary"
427  << messaget::eom;
429  }
430 
431  if((cmdline.args.size() == 1) && !cmdline.isset("show-parse-tree"))
432  {
433  std::string main_class = cmdline.args[0];
434  // `java` accepts slashes and dots as package separators
435  std::replace(main_class.begin(), main_class.end(), '/', '.');
436  config.java.main_class = main_class;
437  cmdline.args.pop_back();
438  }
439 
440  if(cmdline.isset("jar"))
441  {
442  cmdline.args.push_back(cmdline.get_value("jar"));
443  }
444 
445  if(cmdline.isset("gb"))
446  {
447  cmdline.args.push_back(cmdline.get_value("gb"));
448  }
449 
450  // Shows the parse tree of the main class
451  if(cmdline.isset("show-parse-tree"))
452  {
453  std::unique_ptr<languaget> language = get_language_from_mode(ID_java);
454  CHECK_RETURN(language != nullptr);
455  language->set_language_options(options, ui_message_handler);
456 
457  log.status() << "Parsing ..." << messaget::eom;
458 
459  if(static_cast<java_bytecode_languaget *>(language.get())
461  {
462  log.error() << "PARSING ERROR" << messaget::eom;
464  }
465 
466  language->show_parse(std::cout, ui_message_handler);
467  return CPROVER_EXIT_SUCCESS;
468  }
469 
470  object_factory_params.set(options);
471 
473  options.get_bool_option("java-assume-inputs-non-null");
474 
475  std::unique_ptr<abstract_goto_modelt> goto_model_ptr;
476  int get_goto_program_ret = get_goto_program(goto_model_ptr, options);
477  if(get_goto_program_ret != -1)
478  return get_goto_program_ret;
479 
480  if(
481  options.get_bool_option("program-only") ||
482  options.get_bool_option("show-vcc") ||
483  (options.get_bool_option("symex-driven-lazy-loading") &&
484  (cmdline.isset("show-symbol-table") || cmdline.isset("list-symbols") ||
485  cmdline.isset("show-goto-functions") ||
486  cmdline.isset("list-goto-functions") ||
487  cmdline.isset("show-properties") || cmdline.isset("show-loops"))))
488  {
489  if(options.get_bool_option("paths"))
490  {
492  options, ui_message_handler, *goto_model_ptr);
493  (void)verifier();
494  }
495  else
496  {
498  options, ui_message_handler, *goto_model_ptr);
499  (void)verifier();
500  }
501 
502  if(options.get_bool_option("symex-driven-lazy-loading"))
503  {
504  // We can only output these after goto-symex has run.
505  (void)show_loaded_symbols(*goto_model_ptr);
506  (void)show_loaded_functions(*goto_model_ptr);
507  }
508 
509  return CPROVER_EXIT_SUCCESS;
510  }
511 
512  if(
513  options.get_bool_option("dimacs") || !options.get_option("outfile").empty())
514  {
515  if(options.get_bool_option("paths"))
516  {
518  options, ui_message_handler, *goto_model_ptr);
519  (void)verifier();
520  }
521  else
522  {
524  options, ui_message_handler, *goto_model_ptr);
525  (void)verifier();
526  }
527 
528  return CPROVER_EXIT_SUCCESS;
529  }
530 
531  std::unique_ptr<goto_verifiert> verifier = nullptr;
532 
533  if(
534  options.get_bool_option("stop-on-fail") && options.get_bool_option("paths"))
535  {
536  verifier =
537  std::make_unique<stop_on_fail_verifiert<java_single_path_symex_checkert>>(
538  options, ui_message_handler, *goto_model_ptr);
539  }
540  else if(
541  options.get_bool_option("stop-on-fail") &&
542  !options.get_bool_option("paths"))
543  {
544  if(options.get_bool_option("localize-faults"))
545  {
546  verifier =
549  options, ui_message_handler, *goto_model_ptr);
550  }
551  else
552  {
553  verifier = std::make_unique<
555  options, ui_message_handler, *goto_model_ptr);
556  }
557  }
558  else if(
559  !options.get_bool_option("stop-on-fail") &&
560  options.get_bool_option("paths"))
561  {
562  verifier = std::make_unique<all_properties_verifier_with_trace_storaget<
564  options, ui_message_handler, *goto_model_ptr);
565  }
566  else if(
567  !options.get_bool_option("stop-on-fail") &&
568  !options.get_bool_option("paths"))
569  {
570  if(options.get_bool_option("localize-faults"))
571  {
572  verifier =
575  options, ui_message_handler, *goto_model_ptr);
576  }
577  else
578  {
579  verifier = std::make_unique<all_properties_verifier_with_trace_storaget<
581  options, ui_message_handler, *goto_model_ptr);
582  }
583  }
584  else
585  {
586  UNREACHABLE;
587  }
588 
589  const resultt result = (*verifier)();
590  verifier->report();
591  return result_to_exit_code(result);
592 }
593 
595  std::unique_ptr<abstract_goto_modelt> &goto_model_ptr,
596  const optionst &options)
597 {
598  if(options.is_set("context-include") || options.is_set("context-exclude"))
599  method_context = get_context(options);
600  lazy_goto_modelt lazy_goto_model =
602  lazy_goto_model.initialize(cmdline.args, options);
603 
605  std::make_unique<class_hierarchyt>(lazy_goto_model.symbol_table);
606 
607  // Show the class hierarchy
608  if(cmdline.isset("show-class-hierarchy"))
609  {
611  return CPROVER_EXIT_SUCCESS;
612  }
613 
614  // Add failed symbols for any symbol created prior to loading any
615  // particular function:
616  add_failed_symbols(lazy_goto_model.symbol_table);
617 
618  if(!options.get_bool_option("symex-driven-lazy-loading"))
619  {
620  log.status() << "Generating GOTO Program" << messaget::eom;
621  lazy_goto_model.load_all_functions();
622 
623  // show symbol table or list symbols
624  if(show_loaded_symbols(lazy_goto_model))
625  return CPROVER_EXIT_SUCCESS;
626 
627  // Move the model out of the local lazy_goto_model
628  // and into the caller's goto_model
630  std::move(lazy_goto_model));
631  if(goto_model_ptr == nullptr)
633 
634  goto_modelt &goto_model = dynamic_cast<goto_modelt &>(*goto_model_ptr);
635 
636  if(cmdline.isset("validate-goto-model"))
637  {
638  goto_model.validate();
639  }
640 
641  if(show_loaded_functions(goto_model))
642  return CPROVER_EXIT_SUCCESS;
643 
644  if(cmdline.isset("property"))
645  ::set_properties(goto_model, cmdline.get_values("property"));
646  }
647  else
648  {
649  // The precise wording of this error matches goto-symex's complaint when no
650  // __CPROVER_start exists (if we just go ahead and run it anyway it will
651  // trip an invariant when it tries to load it)
653  {
654  log.error() << "the program has no entry point" << messaget::eom;
656  }
657 
658  if(cmdline.isset("validate-goto-model"))
659  {
660  lazy_goto_model.validate();
661  }
662 
663  goto_model_ptr =
664  std::make_unique<lazy_goto_modelt>(std::move(lazy_goto_model));
665  }
666 
668 
669  return -1; // no error, continue
670 }
671 
673  goto_model_functiont &function,
674  const abstract_goto_modelt &model,
675  const optionst &options)
676 {
677  journalling_symbol_tablet &symbol_table = function.get_symbol_table();
678  namespacet ns(symbol_table);
679  goto_functionst::goto_functiont &goto_function = function.get_goto_function();
680 
681  bool using_symex_driven_loading =
682  options.get_bool_option("symex-driven-lazy-loading");
683 
684  // Removal of RTTI inspection:
686  function.get_function_id(),
687  goto_function,
688  symbol_table,
691  // Java virtual functions -> explicit dispatch tables:
693 
694  auto function_is_stub = [&symbol_table, &model](const irep_idt &id) {
695  return symbol_table.lookup_ref(id).value.is_nil() &&
696  !model.can_produce_function(id);
697  };
698 
699  remove_returns(function, function_is_stub);
700 
701  replace_java_nondet(function);
702 
703  // Similar removal of java nondet statements:
705 
706  if(using_symex_driven_loading)
707  {
708  // remove exceptions
709  // If using symex-driven function loading we need to do this now so that
710  // symex doesn't have to cope with exception-handling constructs; however
711  // the results are slightly worse than running it in whole-program mode
712  // (e.g. dead catch sites will be retained)
714  function.get_function_id(),
715  goto_function.body,
716  symbol_table,
717  *class_hierarchy.get(),
719  }
720 
721  transform_assertions_assumptions(options, function.get_goto_function().body);
722 
723  // Replace Java new side effects
725  function.get_function_id(),
726  goto_function,
727  symbol_table,
729 
730  // checks don't know about adjusted float expressions
731  adjust_float_expressions(goto_function, ns);
732 
733  // add failed symbols for anything created relating to this particular
734  // function (note this means subsequent passes mustn't create more!):
736  symbol_table.get_inserted();
737  for(const irep_idt &new_symbol_name : new_symbols)
738  {
740  symbol_table.lookup_ref(new_symbol_name), symbol_table);
741  }
742 
743  // If using symex-driven function loading we must label the assertions
744  // now so symex sees its targets; otherwise we leave this until
745  // process_goto_functions, as we haven't run remove_exceptions yet, and that
746  // pass alters the CFG.
747  if(using_symex_driven_loading)
748  {
749  // label the assertions
750  label_properties(function.get_function_id(), goto_function.body);
751 
752  goto_function.body.update();
753  function.compute_location_numbers();
754  goto_function.body.compute_loop_numbers();
755  }
756 }
757 
759  const abstract_goto_modelt &goto_model)
760 {
761  if(cmdline.isset("show-symbol-table"))
762  {
764  return true;
765  }
766  else if(cmdline.isset("list-symbols"))
767  {
769  return true;
770  }
771 
772  return false;
773 }
774 
776  const abstract_goto_modelt &goto_model)
777 {
778  if(cmdline.isset("show-loops"))
779  {
781  return true;
782  }
783 
784  if(
785  cmdline.isset("show-goto-functions") ||
786  cmdline.isset("list-goto-functions"))
787  {
788  namespacet ns(goto_model.get_symbol_table());
790  ns,
792  goto_model.get_goto_functions(),
793  cmdline.isset("list-goto-functions"));
794  return true;
795  }
796 
797  if(cmdline.isset("show-properties"))
798  {
799  namespacet ns(goto_model.get_symbol_table());
801  return true;
802  }
803 
804  return false;
805 }
806 
808  goto_modelt &goto_model,
809  const optionst &options)
810 {
811  log.status() << "Running GOTO functions transformation passes"
812  << messaget::eom;
813 
814  bool using_symex_driven_loading =
815  options.get_bool_option("symex-driven-lazy-loading");
816 
817  // When using symex-driven lazy loading, *all* relevant processing is done
818  // during process_goto_function, so we have nothing to do here.
819  if(using_symex_driven_loading)
820  return false;
821 
822  // remove catch and throw
824 
825  // instrument library preconditions
826  instrument_preconditions(goto_model);
827 
828  // ignore default/user-specified initialization
829  // of variables with static lifetime
830  if(cmdline.isset("nondet-static"))
831  {
832  log.status() << "Adding nondeterministic initialization "
833  "of static/global variables"
834  << messaget::eom;
835  nondet_static(goto_model);
836  }
837 
838  // recalculate numbers, etc.
839  goto_model.goto_functions.update();
840 
841  if(cmdline.isset("drop-unused-functions"))
842  {
843  // Entry point will have been set before and function pointers removed
844  log.status() << "Removing unused functions" << messaget::eom;
846  }
847 
848  // remove skips such that trivial GOTOs are deleted
849  remove_skip(goto_model);
850 
851  // label the assertions
852  // This must be done after adding assertions and
853  // before using the argument of the "property" option.
854  // Do not re-label after using the property slicer because
855  // this would cause the property identifiers to change.
856  label_properties(goto_model);
857 
858  // reachability slice?
859  if(cmdline.isset("reachability-slice-fb"))
860  {
861  if(cmdline.isset("reachability-slice"))
862  {
863  log.error() << "--reachability-slice and --reachability-slice-fb "
864  << "must not be given together" << messaget::eom;
865  return true;
866  }
867 
868  log.status() << "Performing a forwards-backwards reachability slice"
869  << messaget::eom;
870  if(cmdline.isset("property"))
871  {
873  goto_model, cmdline.get_values("property"), true, ui_message_handler);
874  }
875  else
876  reachability_slicer(goto_model, true, ui_message_handler);
877  }
878 
879  if(cmdline.isset("reachability-slice"))
880  {
881  log.status() << "Performing a reachability slice" << messaget::eom;
882  if(cmdline.isset("property"))
883  {
885  goto_model, cmdline.get_values("property"), ui_message_handler);
886  }
887  else
889  }
890 
891  // full slice?
892  if(cmdline.isset("full-slice"))
893  {
894  log.warning() << "**** WARNING: Experimental option --full-slice, "
895  << "analysis results may be unsound. See "
896  << "https://github.com/diffblue/cbmc/issues/260"
897  << messaget::eom;
898  log.status() << "Performing a full slice" << messaget::eom;
899  if(cmdline.isset("property"))
901  goto_model, cmdline.get_values("property"), ui_message_handler);
902  else
903  full_slicer(goto_model, ui_message_handler);
904  }
905 
906  // remove any skips introduced
907  remove_skip(goto_model);
908 
909  return false;
910 }
911 
913 {
914  static const irep_idt initialize_id = INITIALIZE_FUNCTION;
915 
916  return name != goto_functionst::entry_point() && name != initialize_id;
917 }
918 
920  const irep_idt &function_name,
921  symbol_table_baset &symbol_table,
922  goto_functiont &function,
923  bool body_available)
924 {
925  // Provide a simple stub implementation for any function we don't have a
926  // bytecode implementation for:
927 
928  if(
929  body_available &&
930  (!method_context || (*method_context)(id2string(function_name))))
931  return false;
932 
933  if(!can_generate_function_body(function_name))
934  return false;
935 
936  if(symbol_table.lookup_ref(function_name).mode == ID_java)
937  {
939  function_name,
940  symbol_table,
944 
945  goto_convert_functionst converter(symbol_table, ui_message_handler);
946  converter.convert_function(function_name, function);
947 
948  return true;
949  }
950  else
951  {
952  return false;
953  }
954 }
955 
958 {
959  // clang-format off
960  std::cout << '\n' << banner_string("JBMC", CBMC_VERSION) << '\n'
961  << align_center_with_border("Copyright (C) 2001-2018") << '\n'
962  << align_center_with_border("Daniel Kroening, Edmund Clarke") << '\n' // NOLINT(*)
963  << align_center_with_border("Carnegie Mellon University, Computer Science Department") << '\n' // NOLINT(*)
964  << align_center_with_border("kroening@kroening.com") << '\n';
965 
966  std::cout << help_formatter(
967  "\n"
968  "Usage: \tPurpose:\n"
969  "\n"
970  " {bjbmc} [{y-?}] [{y-h}] [{y--help}] \t show this help\n"
971  " {bjbmc}\n"
973  " {bjbmc}\n"
975  " {bjbmc}\n"
977  " {bjbmc}\n"
979  "\n"
982  "\n"
983  "Analysis options:\n"
985  " {y--symex-coverage-report} {uf} \t generate a Cobertura XML coverage"
986  " report in {uf}\n"
987  " {y--property} {uid} \t only check one specific property\n"
988  " {y--trace} \t give a counterexample trace for failed properties\n"
989  " {y--stop-on-fail} \t stop analysis once a failed property is detected"
990  " (implies {y--trace})\n"
991  " {y--localize-faults} \t localize faults (experimental)\n"
993  "\n"
994  "Platform options:\n"
996  "\n"
997  "Program representations:\n"
998  " {y--show-parse-tree} \t show parse tree\n"
999  " {y--show-symbol-table} \t show loaded symbol table\n"
1000  " {y--list-symbols} \t list symbols with type information\n"
1002  " {y--drop-unused-functions} \t drop functions trivially unreachable"
1003  " from main function\n"
1005  "\n"
1006  "Program instrumentation options:\n"
1007  " {y--no-assertions} \t ignore user assertions\n"
1008  " {y--no-assumptions} \t ignore user assumptions\n"
1009  " {y--mm} {uMM} \t memory consistency model for concurrent programs\n"
1011  " {y--full-slice} \t run full slicer (experimental)\n"
1012  "\n"
1013  "Java Bytecode frontend options:\n"
1015  // This one is handled by jbmc_parse_options not by the Java frontend,
1016  // hence its presence here:
1017  " {y--java-threading} \t enable java multi-threading support"
1018  " (experimental)\n"
1019  " {y--java-unwind-enum-static} \t unwind loops in static initialization of"
1020  " enums\n"
1021  " {y--symex-driven-lazy-loading} \t only load functions when first entered"
1022  " by symbolic execution. Note that {y--show-symbol-table},"
1023  " {y--show-goto-functions}, {y--show-properties} output will be restricted"
1024  " to loaded methods in this case, and only output after the symex phase.\n"
1025  "\n"
1026  "Semantic transformations:\n"
1027  " {y--nondet-static} \t add nondeterministic initialization of variables"
1028  " with static lifetime\n"
1029  "\n"
1030  "BMC options:\n"
1031  HELP_BMC
1032  "\n"
1033  "Backend options:\n"
1035  HELP_SOLVER
1037  " {y--arrays-uf-never} \t never turn arrays into uninterpreted functions\n"
1038  " {y--arrays-uf-always} \t always turn arrays into uninterpreted"
1039  " functions\n"
1040  "\n"
1041  "Other options:\n"
1042  " {y--version} \t show version and exit\n"
1047  HELP_FLUSH
1048  " {y--verbosity} {u#} \t verbosity level\n"
1050  "\n");
1051  // clang-format on
1052 }
void add_failed_symbol_if_needed(const symbolt &symbol, symbol_table_baset &symbol_table)
Create a failed-dereference symbol for the given base symbol if it is pointer-typed,...
void add_failed_symbols(symbol_table_baset &symbol_table)
Create a failed-dereference symbol for all symbols in the given table that need one (i....
Pointer Dereferencing.
void adjust_float_expressions(exprt &expr, const exprt &rounding_mode)
Replaces arithmetic operations and typecasts involving floating point numbers with their equivalent f...
Symbolic Execution.
Goto Verifier for Verifying all Properties.
Goto verifier for verifying all properties that stores traces and localizes faults.
Goto verifier for verifying all properties that stores traces.
std::unique_ptr< languaget > new_ansi_c_language()
configt config
Definition: config.cpp:25
#define HELP_BMC
Definition: bmc_util.h:197
unsigned char opt
Definition: cegis.c:20
void show_class_hierarchy(const class_hierarchyt &hierarchy, ui_message_handlert &message_handler, bool children_only)
Output the class hierarchy.
#define HELP_SHOW_CLASS_HIERARCHY
Abstract interface to eager or lazy GOTO models.
virtual bool can_produce_function(const irep_idt &id) const =0
Determines if this model can produce a body for the given function.
virtual const symbol_tablet & get_symbol_table() const =0
Accessor to get the symbol table.
virtual const goto_functionst & get_goto_functions() const =0
Accessor to get a raw goto_functionst.
Requires an incremental goto checker that is a goto_trace_providert and fault_localization_providert.
std::string get_value(char option) const
Definition: cmdline.cpp:48
virtual bool isset(char option) const
Definition: cmdline.cpp:30
std::list< std::string > get_comma_separated_values(const char *option) const
Collect all occurrences of option option and split their values on each comma, merging them into a si...
Definition: cmdline.cpp:121
argst args
Definition: cmdline.h:151
const std::list< std::string > & get_values(const std::string &option) const
Definition: cmdline.cpp:109
bool set(const cmdlinet &cmdline)
Definition: config.cpp:798
std::string object_bits_info()
Definition: config.cpp:1350
struct configt::javat java
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
void convert_function(const irep_idt &identifier, goto_functionst::goto_functiont &result)
::goto_functiont goto_functiont
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
Definition: goto_function.h:24
Interface providing access to a single function in a GOTO model, plus its associated symbol table.
Definition: goto_model.h:190
void validate(const validation_modet vm=validation_modet::INVARIANT, const goto_model_validation_optionst &goto_model_validation_options=goto_model_validation_optionst{}) const override
Check that the goto model is well-formed.
Definition: goto_model.h:105
goto_functionst goto_functions
GOTO functions.
Definition: goto_model.h:34
Thrown when users pass incorrect command line arguments, for example passing no files to analysis or ...
bool is_nil() const
Definition: irep.h:364
virtual bool parse(message_handlert &)
We set the main class (i.e. class to start the class loading analysis, see java_class_loadert) when w...
bool show_loaded_functions(const abstract_goto_modelt &goto_model)
void get_command_line_options(optionst &)
bool can_generate_function_body(const irep_idt &name)
std::unique_ptr< class_hierarchyt > class_hierarchy
bool show_loaded_symbols(const abstract_goto_modelt &goto_model)
virtual int doit() override
invoke main modules
std::optional< prefix_filtert > method_context
See java_bytecode_languaget::method_context.
virtual void help() override
display command line help
void process_goto_function(goto_model_functiont &function, const abstract_goto_modelt &, const optionst &)
java_object_factory_parameterst object_factory_params
bool process_goto_functions(goto_modelt &goto_model, const optionst &options)
int get_goto_program(std::unique_ptr< abstract_goto_modelt > &goto_model, const optionst &)
jbmc_parse_optionst(int argc, const char **argv)
bool generate_function_body(const irep_idt &function_name, symbol_table_baset &symbol_table, goto_functiont &function, bool body_available)
static void set_default_options(optionst &)
Set the options that have default values.
A symbol table wrapper that records which entries have been updated/removedA caller can pass a journa...
virtual const symbol_tablet & get_symbol_table() const override
std::unordered_set< irep_idt > changesett
const changesett & get_inserted() const
A GOTO model that produces function bodies on demand.
void load_all_functions() const
Eagerly loads all functions from the symbol table.
void validate(const validation_modet vm=validation_modet::INVARIANT, const goto_model_validation_optionst &goto_model_validation_options=goto_model_validation_optionst{}) const override
Check that the goto model is well-formed.
static lazy_goto_modelt from_handler_object(THandler &handler, const optionst &options, message_handlert &message_handler)
Create a lazy_goto_modelt from a object that defines function/module pass handlers.
void initialize(const std::vector< std::string > &files, const optionst &options)
Performs initial symbol table and language_filest initialization from a given commandline and parsed ...
symbol_tablet & symbol_table
Reference to symbol_table in the internal goto_model.
static std::unique_ptr< goto_modelt > process_whole_model_and_freeze(lazy_goto_modelt &&model)
The model returned here has access to the functions we've already loaded but is frozen in the sense t...
static unsigned eval_verbosity(const std::string &user_input, const message_levelt default_verbosity, message_handlert &dest)
Parse a (user-)provided string as a verbosity level and set it as the verbosity of dest.
Definition: message.cpp:105
mstreamt & error() const
Definition: message.h:399
mstreamt & warning() const
Definition: message.h:404
mstreamt & status() const
Definition: message.h:414
void conditional_output(mstreamt &mstream, const std::function< void(mstreamt &)> &output_generator) const
Generate output to message_stream using output_generator if the configured verbosity is at least as h...
Definition: message.cpp:139
mstreamt & debug() const
Definition: message.h:429
@ M_STATISTICS
Definition: message.h:171
static eomt eom
Definition: message.h:297
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
bool is_set(const std::string &option) const
N.B. opts.is_set("foo") does not imply opts.get_bool_option("foo")
Definition: options.cpp:62
json_objectt to_json() const
Returns the options as JSON key value pairs.
Definition: options.cpp:93
bool get_bool_option(const std::string &option) const
Definition: options.cpp:44
void set_option(const std::string &option, const bool value)
Definition: options.cpp:28
const std::string get_option(const std::string &option) const
Definition: options.cpp:67
xmlt to_xml() const
Returns the options in XML format.
Definition: options.cpp:104
virtual void usage_error()
void log_version_and_architecture(const std::string &front_end)
Write version and system architecture to log.status().
ui_message_handlert ui_message_handler
Definition: parse_options.h:45
Stops when the first failing property is found and localizes the fault Requires an incremental goto c...
Stops when the first failing property is found.
The symbol table base class interface.
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
exprt value
Initial value of symbol.
Definition: symbol.h:34
irep_idt mode
Language mode.
Definition: symbol.h:49
virtual uit get_ui() const
Definition: ui_message.h:33
#define HELP_CONFIG_PLATFORM
Definition: config.h:96
#define HELP_CONFIG_BACKEND
Definition: config.h:126
void convert_nondet(const irep_idt &function_identifier, goto_programt &goto_program, symbol_table_baset &symbol_table, message_handlert &message_handler, const java_object_factory_parameterst &user_object_factory_parameters, const irep_idt &mode)
For each instruction in the goto program, checks if it is an assignment from nondet and replaces it w...
Convert side_effect_expr_nondett expressions using java_object_factory.
static void show_goto_functions(const goto_modelt &goto_model)
Document and give macros for the exit codes of CPROVER binaries.
#define CPROVER_EXIT_INTERNAL_ERROR
An error has been encountered during processing the requested analysis.
Definition: exit_codes.h:45
#define CPROVER_EXIT_INCORRECT_TASK
The command line is correctly structured but cannot be carried out due to missing files,...
Definition: exit_codes.h:49
#define CPROVER_EXIT_PARSE_ERROR
An error during parsing of the input program.
Definition: exit_codes.h:37
#define CPROVER_EXIT_USAGE_ERROR
A usage error is returned when the command line is invalid or conflicting.
Definition: exit_codes.h:33
#define CPROVER_EXIT_SUCCESS
Success indicates the required analysis has been performed without error.
Definition: exit_codes.h:16
void property_slicer(goto_functionst &goto_functions, const namespacet &ns, const std::list< std::string > &properties, message_handlert &message_handler)
void full_slicer(goto_functionst &goto_functions, const namespacet &ns, const slicing_criteriont &criterion, message_handlert &message_handler)
static void transform_assertions_assumptions(goto_programt &goto_program, bool enable_assertions, bool enable_built_in_assertions, bool enable_assumptions)
Definition: goto_check.cpp:19
Checks for Errors in C and Java Programs.
Goto Programs with Functions.
#define PARSE_OPTIONS_GOTO_TRACE(cmdline, options)
Definition: goto_trace.h:287
#define HELP_GOTO_TRACE
Definition: goto_trace.h:279
Help Formatter.
static help_formattert help_formatter(const std::string &s)
void instrument_preconditions(const goto_modelt &goto_model, goto_programt &goto_program)
const std::string & id2string(const irep_idt &d)
Definition: irep.h:40
void parse_java_language_options(const cmdlinet &cmd, optionst &options)
Parse options that are java bytecode specific.
prefix_filtert get_context(const optionst &options)
std::unique_ptr< languaget > new_java_bytecode_language()
#define HELP_JAVA_METHOD_NAME
#define JAVA_BYTECODE_LANGUAGE_OPTIONS_HELP
#define HELP_JAVA_GOTO_BINARY
#define HELP_JAVA_CLASSPATH
#define HELP_JAVA_JAR
#define HELP_JAVA_CLASS_NAME
Goto Checker using Bounded Model Checking for Java.
Goto Checker using Bounded Model Checking for Java.
void parse_java_object_factory_options(const cmdlinet &cmdline, optionst &options)
Parse the java object factory parameters from a given command line.
Goto Checker using Single Path Symbolic Execution for Java.
Goto Checker using Single Path Symbolic Execution for Java.
#define HELP_JAVA_TRACE_VALIDATION
JBMC Command Line Option Processing.
#define JBMC_OPTIONS
void json_interface(cmdlinet &cmdline, message_handlert &message_handler)
Parses the JSON-formatted command line from stdin.
#define HELP_JSON_INTERFACE
Abstract interface to support a programming language.
#define HELP_FUNCTIONS
Definition: language.h:34
Author: Diffblue Ltd.
void show_loop_ids(ui_message_handlert::uit ui, const goto_modelt &goto_model)
Definition: loop_ids.cpp:21
Loop IDs.
void register_language(language_factoryt factory)
Register a language Note: registering a language is required for using the functions in language_util...
Definition: mode.cpp:39
std::unique_ptr< languaget > get_language_from_mode(const irep_idt &mode)
Get the language corresponding to the given mode.
Definition: mode.cpp:51
static void nondet_static(const namespacet &ns, goto_functionst &goto_functions, const irep_idt &fct_name)
Nondeterministically initializes global scope variables in a goto-function.
Nondeterministically initializes global scope variables, except for constants (such as string literal...
std::string align_center_with_border(const std::string &text)
Utility for displaying help centered messages borderered by "* *".
std::string banner_string(const std::string &front_end, const std::string &version)
void parse_path_strategy_options(const cmdlinet &cmdline, optionst &options, message_handlert &message_handler)
add paths and exploration-strategy option, suitable to be invoked from front-ends.
std::string show_path_strategies()
suitable for displaying as a front-end help message
Storage of symbolic execution paths to resume.
int result_to_exit_code(resultt result)
Definition: properties.cpp:147
resultt
The result of goto verifying.
Definition: properties.h:45
void reachability_slicer(goto_modelt &goto_model, const bool include_forward_reachability, message_handlert &message_handler)
Perform reachability slicing on goto_model, with respect to the criterion given by all properties.
#define HELP_REACHABILITY_SLICER
void remove_exceptions(symbol_table_baset &symbol_table, goto_functionst &goto_functions, const class_hierarchyt &class_hierarchy, message_handlert &message_handler)
removes throws/CATCH-POP/CATCH-PUSH
Remove function exceptional returns.
void remove_instanceof(const irep_idt &function_identifier, goto_programt::targett target, goto_programt &goto_program, symbol_table_baset &symbol_table, const class_hierarchyt &class_hierarchy, message_handlert &message_handler)
Replace an instanceof in the expression or guard of the passed instruction of the given function body...
Remove Instance-of Operators.
void remove_java_new(const irep_idt &function_identifier, goto_programt::targett target, goto_programt &goto_program, symbol_table_baset &symbol_table, message_handlert &message_handler)
Replace every java_new or java_new_array by a malloc side-effect and zero initialization.
Remove Java New Operators.
void remove_returns(symbol_table_baset &symbol_table, goto_functionst &goto_functions)
removes returns
Replace function returns by assignments to global variables.
void remove_skip(goto_programt &goto_program, goto_programt::targett begin, goto_programt::targett end)
remove unnecessary skip statements
Definition: remove_skip.cpp:87
Program Transformation.
void remove_unused_functions(goto_modelt &goto_model, message_handlert &message_handler)
Unused function removal.
void remove_virtual_functions(symbol_table_baset &symbol_table, goto_functionst &goto_functions)
Remove virtual function calls from all functions in the specified list and replace them with their mo...
Functions for replacing virtual function call with a static function calls in functions,...
static void replace_java_nondet(goto_programt &goto_program)
Checks each instruction in the goto program to see whether it is a method returning nondet.
Replace Java Nondet expressions.
void set_properties(goto_programt &goto_program, std::unordered_set< irep_idt > &property_set)
void label_properties(goto_modelt &goto_model)
Set the properties to check.
Show the goto functions.
#define HELP_SHOW_GOTO_FUNCTIONS
void show_properties(const namespacet &ns, const irep_idt &identifier, message_handlert &message_handler, ui_message_handlert::uit ui, const goto_programt &goto_program)
Show the properties.
#define HELP_SHOW_PROPERTIES
void show_symbol_table(const symbol_table_baset &symbol_table, ui_message_handlert &ui)
void show_symbol_table_brief(const symbol_table_baset &symbol_table, ui_message_handlert &ui)
Show the symbol table.
void java_generate_simple_method_stub(const irep_idt &function_name, symbol_table_baset &symbol_table, bool assume_non_null, const java_object_factory_parameterst &object_factory_parameters, message_handlert &message_handler)
Java simple opaque stub generation.
void parse_solver_options(const cmdlinet &cmdline, optionst &options)
Parse solver-related command-line parameters in cmdline and set corresponding values in options.
#define HELP_SOLVER
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:525
#define INITIALIZE_FUNCTION
void exit(int status)
Definition: stdlib.c:102
Goto Verifier for stopping at the first failing property.
Goto Verifier for stopping at the first failing property and localizing the fault.
void replace(const union_find_replacet &replace_map, string_not_contains_constraintt &constraint)
#define HELP_STRING_REFINEMENT
irep_idt main_class
Definition: config.h:343
void set(const optionst &)
Assigns the parameters from given options.
#define HELP_TIMESTAMP
Definition: timestamper.h:14
#define HELP_FLUSH
Definition: ui_message.h:108
#define HELP_VALIDATE
const char * CBMC_VERSION
void xml_interface(cmdlinet &cmdline, message_handlert &message_handler)
Parse XML-formatted commandline options from stdin.
#define HELP_XML_INTERFACE
Definition: xml_interface.h:39