CBMC
goto_instrument_parse_options.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Main Module
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
13 
14 #include <util/exception_utils.h>
15 #include <util/exit_codes.h>
16 #include <util/help_formatter.h>
17 #include <util/json.h>
18 #include <util/options.h>
19 #include <util/string2int.h>
20 #include <util/string_utils.h>
21 #include <util/unicode.h>
22 #include <util/version.h>
23 
31 #include <goto-programs/loop_ids.h>
32 #include <goto-programs/mm_io.h>
50 
51 #include <analyses/call_graph.h>
57 #include <analyses/guard.h>
60 #include <analyses/is_threaded.h>
61 #include <analyses/lexical_loops.h>
64 #include <analyses/natural_loops.h>
66 #include <analyses/sese_regions.h>
67 #include <ansi-c/ansi_c_language.h>
69 #include <ansi-c/cprover_library.h>
70 #include <ansi-c/gcc_version.h>
71 #include <assembler/remove_asm.h>
72 #include <cpp/cprover_library.h>
76 
77 #include "alignment_checks.h"
78 #include "branch.h"
79 #include "call_sequences.h"
80 #include "concurrency.h"
81 #include "dot.h"
82 #include "full_slicer.h"
83 #include "function.h"
84 #include "havoc_loops.h"
85 #include "horn_encoding.h"
87 #include "interrupt.h"
88 #include "k_induction.h"
89 #include "mmio.h"
90 #include "model_argc_argv.h"
91 #include "nondet_static.h"
92 #include "nondet_volatile.h"
93 #include "points_to.h"
94 #include "race_check.h"
95 #include "remove_function.h"
96 #include "rw_set.h"
97 #include "show_locations.h"
98 #include "skip_loops.h"
99 #include "splice_call.h"
100 #include "stack_depth.h"
101 #include "thread_instrumentation.h"
102 #include "undefined_functions.h"
103 #include "unwind.h"
104 #include "value_set_fi_fp_removal.h"
105 
106 #include <fstream> // IWYU pragma: keep
107 #include <iostream>
108 #include <memory>
109 
110 #include "accelerate/accelerate.h"
111 
114 {
115  if(cmdline.isset("version"))
116  {
117  std::cout << CBMC_VERSION << '\n';
118  return CPROVER_EXIT_SUCCESS;
119  }
120 
121  if(cmdline.args.size()!=1 && cmdline.args.size()!=2)
122  {
123  help();
125  }
126 
129 
130  {
132 
134 
135  // configure gcc, if required -- get_goto_program will have set the config
137  {
138  gcc_versiont gcc_version;
139  gcc_version.get("gcc");
140  configure_gcc(gcc_version);
141  }
142 
143  {
144  const bool validate_only = cmdline.isset("validate-goto-binary");
145 
146  if(validate_only || cmdline.isset("validate-goto-model"))
147  {
149 
150  if(validate_only)
151  {
152  return CPROVER_EXIT_SUCCESS;
153  }
154  }
155  }
156 
157  // ignore default/user-specified initialization
158  // of matching variables with static lifetime
159  if(cmdline.isset("nondet-static-matching"))
160  {
161  log.status() << "Adding nondeterministic initialization "
162  "of matching static/global variables"
163  << messaget::eom;
165  goto_model, cmdline.get_value("nondet-static-matching"));
166  }
167 
169 
170  if(cmdline.isset("validate-goto-model"))
171  {
173  }
174 
175  {
176  bool unwind_given=cmdline.isset("unwind");
177  bool unwindset_given=cmdline.isset("unwindset");
178  bool unwindset_file_given=cmdline.isset("unwindset-file");
179 
180  if(unwindset_given && unwindset_file_given)
181  throw "only one of --unwindset and --unwindset-file supported at a "
182  "time";
183 
184  if(unwind_given || unwindset_given || unwindset_file_given)
185  {
186  unwindsett unwindset{goto_model};
187 
188  if(unwind_given)
189  unwindset.parse_unwind(cmdline.get_value("unwind"));
190 
191  if(unwindset_file_given)
192  {
193  unwindset.parse_unwindset_file(
194  cmdline.get_value("unwindset-file"), ui_message_handler);
195  }
196 
197  if(unwindset_given)
198  {
199  unwindset.parse_unwindset(
200  cmdline.get_comma_separated_values("unwindset"),
202  }
203 
204  bool unwinding_assertions=cmdline.isset("unwinding-assertions");
205  bool partial_loops=cmdline.isset("partial-loops");
206  bool continue_as_loops=cmdline.isset("continue-as-loops");
207  if(continue_as_loops)
208  {
209  if(unwinding_assertions)
210  {
211  throw "unwinding assertions cannot be used with "
212  "--continue-as-loops";
213  }
214  else if(partial_loops)
215  throw "partial loops cannot be used with --continue-as-loops";
216  }
217 
218  goto_unwindt::unwind_strategyt unwind_strategy=
220 
221  if(unwinding_assertions)
222  {
223  if(partial_loops)
225  else
227  }
228  else if(partial_loops)
229  {
231  }
232  else if(continue_as_loops)
233  {
235  }
236 
237  goto_unwindt goto_unwind;
238  goto_unwind(goto_model, unwindset, unwind_strategy);
239 
240  if(cmdline.isset("log"))
241  {
242  std::string filename=cmdline.get_value("log");
243  bool have_file=!filename.empty() && filename!="-";
244 
245  jsont result=goto_unwind.output_log_json();
246 
247  if(have_file)
248  {
249  std::ofstream of(widen_if_needed(filename));
250 
251  if(!of)
252  throw "failed to open file "+filename;
253 
254  of << result;
255  of.close();
256  }
257  else
258  {
259  std::cout << result << '\n';
260  }
261  }
262 
263  // goto_unwind holds references to instructions, only do remove_skip
264  // after having generated the log above
266  }
267  }
268 
269  if(cmdline.isset("show-threaded"))
270  {
272 
273  is_threadedt is_threaded(goto_model);
274 
275  for(const auto &gf_entry : goto_model.goto_functions.function_map)
276  {
277  std::cout << "////\n";
278  std::cout << "//// Function: " << gf_entry.first << '\n';
279  std::cout << "////\n\n";
280 
281  const goto_programt &goto_program = gf_entry.second.body;
282 
283  forall_goto_program_instructions(i_it, goto_program)
284  {
285  i_it->output(std::cout);
286  std::cout << "Is threaded: " << (is_threaded(i_it)?"True":"False")
287  << "\n\n";
288  }
289  }
290 
291  return CPROVER_EXIT_SUCCESS;
292  }
293 
294  if(cmdline.isset("insert-final-assert-false"))
295  {
296  log.status() << "Inserting final assert false" << messaget::eom;
297  bool fail = insert_final_assert_false(
298  goto_model,
299  cmdline.get_value("insert-final-assert-false"),
301  if(fail)
302  {
304  }
305  // otherwise, fall-through to write new binary
306  }
307 
308  if(cmdline.isset("show-value-sets"))
309  {
311 
312  // recalculate numbers, etc.
314 
315  log.status() << "Pointer Analysis" << messaget::eom;
317  value_set_analysist value_set_analysis(ns);
318  value_set_analysis(goto_model);
320  ui_message_handler.get_ui(), goto_model, value_set_analysis);
321  return CPROVER_EXIT_SUCCESS;
322  }
323 
324  if(cmdline.isset("show-global-may-alias"))
325  {
329 
330  // recalculate numbers, etc.
332 
333  global_may_alias_analysist global_may_alias_analysis;
334  global_may_alias_analysis(goto_model);
335  global_may_alias_analysis.output(goto_model, std::cout);
336 
337  return CPROVER_EXIT_SUCCESS;
338  }
339 
340  if(cmdline.isset("show-local-bitvector-analysis"))
341  {
344 
345  // recalculate numbers, etc.
347 
349 
350  for(const auto &gf_entry : goto_model.goto_functions.function_map)
351  {
352  local_bitvector_analysist local_bitvector_analysis(gf_entry.second, ns);
353  std::cout << ">>>>\n";
354  std::cout << ">>>> " << gf_entry.first << '\n';
355  std::cout << ">>>>\n";
356  local_bitvector_analysis.output(std::cout, gf_entry.second, ns);
357  std::cout << '\n';
358  }
359 
360  return CPROVER_EXIT_SUCCESS;
361  }
362 
363  if(cmdline.isset("show-local-safe-pointers") ||
364  cmdline.isset("show-safe-dereferences"))
365  {
366  // Ensure location numbering is unique:
368 
370 
371  for(const auto &gf_entry : goto_model.goto_functions.function_map)
372  {
373  local_safe_pointerst local_safe_pointers;
374  local_safe_pointers(gf_entry.second.body);
375  std::cout << ">>>>\n";
376  std::cout << ">>>> " << gf_entry.first << '\n';
377  std::cout << ">>>>\n";
378  if(cmdline.isset("show-local-safe-pointers"))
379  local_safe_pointers.output(std::cout, gf_entry.second.body, ns);
380  else
381  {
382  local_safe_pointers.output_safe_dereferences(
383  std::cout, gf_entry.second.body, ns);
384  }
385  std::cout << '\n';
386  }
387 
388  return CPROVER_EXIT_SUCCESS;
389  }
390 
391  if(cmdline.isset("show-sese-regions"))
392  {
393  // Ensure location numbering is unique:
395 
397 
398  for(const auto &gf_entry : goto_model.goto_functions.function_map)
399  {
400  sese_region_analysist sese_region_analysis;
401  sese_region_analysis(gf_entry.second.body);
402  std::cout << ">>>>\n";
403  std::cout << ">>>> " << gf_entry.first << '\n';
404  std::cout << ">>>>\n";
405  sese_region_analysis.output(std::cout, gf_entry.second.body, ns);
406  std::cout << '\n';
407  }
408 
409  return CPROVER_EXIT_SUCCESS;
410  }
411 
412  if(cmdline.isset("show-custom-bitvector-analysis"))
413  {
417 
419 
420  if(!cmdline.isset("inline"))
421  {
424  }
425 
426  // recalculate numbers, etc.
428 
429  custom_bitvector_analysist custom_bitvector_analysis;
430  custom_bitvector_analysis(goto_model);
431  custom_bitvector_analysis.output(goto_model, std::cout);
432 
433  return CPROVER_EXIT_SUCCESS;
434  }
435 
436  if(cmdline.isset("show-escape-analysis"))
437  {
441 
442  // recalculate numbers, etc.
444 
445  escape_analysist escape_analysis;
446  escape_analysis(goto_model);
447  escape_analysis.output(goto_model, std::cout);
448 
449  return CPROVER_EXIT_SUCCESS;
450  }
451 
452  if(cmdline.isset("custom-bitvector-analysis"))
453  {
457 
459 
460  if(!cmdline.isset("inline"))
461  {
464  }
465 
466  // recalculate numbers, etc.
468 
470 
471  custom_bitvector_analysist custom_bitvector_analysis;
472  custom_bitvector_analysis(goto_model);
473  custom_bitvector_analysis.check(
474  goto_model,
475  cmdline.isset("xml-ui"),
476  std::cout);
477 
478  return CPROVER_EXIT_SUCCESS;
479  }
480 
481  if(cmdline.isset("show-points-to"))
482  {
484 
485  // recalculate numbers, etc.
487 
489 
490  log.status() << "Pointer Analysis" << messaget::eom;
491  points_tot points_to;
492  points_to(goto_model);
493  points_to.output(std::cout);
494  return CPROVER_EXIT_SUCCESS;
495  }
496 
497  if(cmdline.isset("show-intervals"))
498  {
500 
501  // recalculate numbers, etc.
503 
504  log.status() << "Interval Analysis" << messaget::eom;
508  interval_analysis.output(goto_model, std::cout);
509  return CPROVER_EXIT_SUCCESS;
510  }
511 
512  if(cmdline.isset("show-call-sequences"))
513  {
516  return CPROVER_EXIT_SUCCESS;
517  }
518 
519  if(cmdline.isset("check-call-sequence"))
520  {
523  return CPROVER_EXIT_SUCCESS;
524  }
525 
526  if(cmdline.isset("list-calls-args"))
527  {
529 
531 
532  return CPROVER_EXIT_SUCCESS;
533  }
534 
535  if(cmdline.isset("show-rw-set"))
536  {
538 
539  if(!cmdline.isset("inline"))
540  {
542 
543  // recalculate numbers, etc.
545  }
546 
547  log.status() << "Pointer Analysis" << messaget::eom;
548  value_set_analysist value_set_analysis(ns);
549  value_set_analysis(goto_model);
550 
551  const symbolt &symbol=ns.lookup(ID_main);
552  symbol_exprt main(symbol.name, symbol.type);
553 
554  std::cout << rw_set_functiont(
555  value_set_analysis, goto_model, main, ui_message_handler);
556  return CPROVER_EXIT_SUCCESS;
557  }
558 
559  if(cmdline.isset("show-symbol-table"))
560  {
562  return CPROVER_EXIT_SUCCESS;
563  }
564 
565  if(cmdline.isset("show-reaching-definitions"))
566  {
569 
572  rd_analysis(goto_model);
573  rd_analysis.output(goto_model, std::cout);
574 
575  return CPROVER_EXIT_SUCCESS;
576  }
577 
578  if(cmdline.isset("show-dependence-graph"))
579  {
582 
584  dependence_grapht dependence_graph(ns, ui_message_handler);
585  dependence_graph(goto_model);
586  dependence_graph.output(goto_model, std::cout);
587  dependence_graph.output_dot(std::cout);
588 
589  return CPROVER_EXIT_SUCCESS;
590  }
591 
592  if(cmdline.isset("count-eloc"))
593  {
595  return CPROVER_EXIT_SUCCESS;
596  }
597 
598  if(cmdline.isset("list-eloc"))
599  {
601  return CPROVER_EXIT_SUCCESS;
602  }
603 
604  if(cmdline.isset("print-path-lengths"))
605  {
607  return CPROVER_EXIT_SUCCESS;
608  }
609 
610  if(cmdline.isset("print-global-state-size"))
611  {
613  return CPROVER_EXIT_SUCCESS;
614  }
615 
616  if(cmdline.isset("list-symbols"))
617  {
619  return CPROVER_EXIT_SUCCESS;
620  }
621 
622  if(cmdline.isset("show-uninitialized"))
623  {
624  show_uninitialized(goto_model, std::cout);
625  return CPROVER_EXIT_SUCCESS;
626  }
627 
628  if(cmdline.isset("interpreter"))
629  {
632 
633  log.status() << "Starting interpreter" << messaget::eom;
635  return CPROVER_EXIT_SUCCESS;
636  }
637 
638  if(cmdline.isset("show-claims") ||
639  cmdline.isset("show-properties"))
640  {
643  return CPROVER_EXIT_SUCCESS;
644  }
645 
646  if(cmdline.isset("document-claims-html") ||
647  cmdline.isset("document-properties-html"))
648  {
650  return CPROVER_EXIT_SUCCESS;
651  }
652 
653  if(cmdline.isset("document-claims-latex") ||
654  cmdline.isset("document-properties-latex"))
655  {
657  return CPROVER_EXIT_SUCCESS;
658  }
659 
660  if(cmdline.isset("show-loops"))
661  {
663  return CPROVER_EXIT_SUCCESS;
664  }
665 
666  if(cmdline.isset("show-natural-loops"))
667  {
668  show_natural_loops(goto_model, std::cout);
669  return CPROVER_EXIT_SUCCESS;
670  }
671 
672  if(cmdline.isset("show-lexical-loops"))
673  {
674  show_lexical_loops(goto_model, std::cout);
675  return CPROVER_EXIT_SUCCESS;
676  }
677 
678  if(cmdline.isset("print-internal-representation"))
679  {
680  for(auto const &pair : goto_model.goto_functions.function_map)
681  for(auto const &ins : pair.second.body.instructions)
682  {
683  if(ins.code().is_not_nil())
684  log.status() << ins.code().pretty() << messaget::eom;
685  if(ins.has_condition())
686  {
687  log.status() << "[guard] " << ins.condition().pretty()
688  << messaget::eom;
689  }
690  }
691  return CPROVER_EXIT_SUCCESS;
692  }
693 
694  if(
695  cmdline.isset("show-goto-functions") ||
696  cmdline.isset("list-goto-functions"))
697  {
699  goto_model, ui_message_handler, cmdline.isset("list-goto-functions"));
700  return CPROVER_EXIT_SUCCESS;
701  }
702 
703  if(cmdline.isset("list-undefined-functions"))
704  {
706  return CPROVER_EXIT_SUCCESS;
707  }
708 
709  // experimental: print structs
710  if(cmdline.isset("show-struct-alignment"))
711  {
713  return CPROVER_EXIT_SUCCESS;
714  }
715 
716  if(cmdline.isset("show-locations"))
717  {
719  return CPROVER_EXIT_SUCCESS;
720  }
721 
722  if(
723  cmdline.isset("dump-c") || cmdline.isset("dump-cpp") ||
724  cmdline.isset("dump-c-type-header"))
725  {
726  const bool is_cpp=cmdline.isset("dump-cpp");
727  const bool is_header = cmdline.isset("dump-c-type-header");
728  const bool h_libc=!cmdline.isset("no-system-headers");
729  const bool h_all=cmdline.isset("use-all-headers");
730  const bool harness=cmdline.isset("harness");
732 
733  // restore RETURN instructions in case remove_returns had been
734  // applied
736 
737  // dump_c (actually goto_program2code) requires valid instruction
738  // location numbers:
740 
741  if(cmdline.args.size()==2)
742  {
743  std::ofstream out(widen_if_needed(cmdline.args[1]));
744 
745  if(!out)
746  {
747  log.error() << "failed to write to '" << cmdline.args[1] << "'";
749  }
750  if(is_header)
751  {
754  h_libc,
755  h_all,
756  harness,
757  ns,
758  cmdline.get_value("dump-c-type-header"),
759  out);
760  }
761  else
762  {
763  (is_cpp ? dump_cpp : dump_c)(
764  goto_model.goto_functions, h_libc, h_all, harness, ns, out);
765  }
766  }
767  else
768  {
769  if(is_header)
770  {
773  h_libc,
774  h_all,
775  harness,
776  ns,
777  cmdline.get_value("dump-c-type-header"),
778  std::cout);
779  }
780  else
781  {
782  (is_cpp ? dump_cpp : dump_c)(
783  goto_model.goto_functions, h_libc, h_all, harness, ns, std::cout);
784  }
785  }
786 
787  return CPROVER_EXIT_SUCCESS;
788  }
789 
790  if(cmdline.isset("call-graph"))
791  {
793  call_grapht call_graph(goto_model);
794 
795  if(cmdline.isset("xml"))
796  call_graph.output_xml(std::cout);
797  else if(cmdline.isset("dot"))
798  call_graph.output_dot(std::cout);
799  else
800  call_graph.output(std::cout);
801 
802  return CPROVER_EXIT_SUCCESS;
803  }
804 
805  if(cmdline.isset("reachable-call-graph"))
806  {
808  call_grapht call_graph =
811  if(cmdline.isset("xml"))
812  call_graph.output_xml(std::cout);
813  else if(cmdline.isset("dot"))
814  call_graph.output_dot(std::cout);
815  else
816  call_graph.output(std::cout);
817 
818  return 0;
819  }
820 
821  if(cmdline.isset("show-class-hierarchy"))
822  {
823  class_hierarchyt hierarchy;
824  hierarchy(goto_model.symbol_table);
825  if(cmdline.isset("dot"))
826  hierarchy.output_dot(std::cout);
827  else
829 
830  return CPROVER_EXIT_SUCCESS;
831  }
832 
833  if(cmdline.isset("dot"))
834  {
836 
837  if(cmdline.args.size()==2)
838  {
839  std::ofstream out(widen_if_needed(cmdline.args[1]));
840 
841  if(!out)
842  {
843  log.error() << "failed to write to " << cmdline.args[1] << "'";
845  }
846 
847  dot(goto_model, out);
848  }
849  else
850  dot(goto_model, std::cout);
851 
852  return CPROVER_EXIT_SUCCESS;
853  }
854 
855  if(cmdline.isset("accelerate"))
856  {
858 
860 
861  log.status() << "Performing full inlining" << messaget::eom;
863 
864  log.status() << "Removing calls to functions without a body"
865  << messaget::eom;
866  remove_calls_no_bodyt remove_calls_no_body;
867  remove_calls_no_body(goto_model.goto_functions, ui_message_handler);
868 
869  log.status() << "Accelerating" << messaget::eom;
870  guard_managert guard_manager;
872  goto_model, ui_message_handler, cmdline.isset("z3"), guard_manager);
874  }
875 
876  if(cmdline.isset("horn"))
877  {
878  log.status() << "Horn-clause encoding" << messaget::eom;
880 
881  if(cmdline.args.size()==2)
882  {
883  std::ofstream out(widen_if_needed(cmdline.args[1]));
884 
885  if(!out)
886  {
887  log.error() << "Failed to open output file " << cmdline.args[1]
888  << messaget::eom;
890  }
891 
893  }
894  else
895  horn_encoding(goto_model, std::cout);
896 
897  return CPROVER_EXIT_SUCCESS;
898  }
899 
900  if(cmdline.isset("drop-unused-functions"))
901  {
904 
905  log.status() << "Removing unused functions" << messaget::eom;
907  }
908 
909  if(cmdline.isset("undefined-function-is-assume-false"))
910  {
913  }
914 
915  // write new binary?
916  if(cmdline.args.size()==2)
917  {
918  log.status() << "Writing GOTO program to '" << cmdline.args[1] << "'"
919  << messaget::eom;
920 
923  else
924  return CPROVER_EXIT_SUCCESS;
925  }
926  else if(cmdline.args.size() < 2)
927  {
929  "Invalid number of positional arguments passed",
930  "[in] [out]",
931  "goto-instrument needs one input and one output file, aside from other "
932  "flags");
933  }
934 
935  help();
937  }
938 // NOLINTNEXTLINE(readability/fn_size)
939 }
940 
942  bool force)
943 {
944  if(function_pointer_removal_done && !force)
945  return;
946 
948 
949  log.status() << "Function Pointer Removal" << messaget::eom;
951  log.status() << "Virtual function removal" << messaget::eom;
953  log.status() << "Cleaning inline assembler statements" << messaget::eom;
955 }
956 
961 {
962  // Don't bother if we've already done a full function pointer
963  // removal.
965  {
966  return;
967  }
968 
969  log.status() << "Removing const function pointers only" << messaget::eom;
972  goto_model,
973  true); // abort if we can't resolve via const pointers
974 }
975 
977 {
979  return;
980 
982 
983  if(!cmdline.isset("inline"))
984  {
985  log.status() << "Partial Inlining" << messaget::eom;
987  }
988 }
989 
991 {
993  return;
994 
995  remove_returns_done=true;
996 
997  log.status() << "Removing returns" << messaget::eom;
999 }
1000 
1002 {
1003  log.status() << "Reading GOTO program from '" << cmdline.args[0] << "'"
1004  << messaget::eom;
1005 
1006  config.set(cmdline);
1007 
1008  auto result = read_goto_binary(cmdline.args[0], ui_message_handler);
1009 
1010  if(!result.has_value())
1011  throw 0;
1012 
1013  goto_model = std::move(result.value());
1014 
1016 }
1017 
1019 {
1020  optionst options;
1021 
1023 
1024  // disable simplify when adding various checks?
1025  if(cmdline.isset("no-simplify"))
1026  options.set_option("simplify", false);
1027  else
1028  options.set_option("simplify", true);
1029 
1030  // all checks supported by goto_check
1032 
1033  // initialize argv with valid pointers
1034  if(cmdline.isset("model-argc-argv"))
1035  {
1036  unsigned max_argc=
1037  safe_string2unsigned(cmdline.get_value("model-argc-argv"));
1038 
1039  log.status() << "Adding up to " << max_argc << " command line arguments"
1040  << messaget::eom;
1042  throw 0;
1043  }
1044 
1045  if(cmdline.isset("remove-function-body"))
1046  {
1048  goto_model,
1049  cmdline.get_values("remove-function-body"),
1051  }
1052 
1053  // we add the library in some cases, as some analyses benefit
1054 
1055  if(
1056  cmdline.isset("add-library") || cmdline.isset("mm") ||
1057  cmdline.isset("reachability-slice") ||
1058  cmdline.isset("reachability-slice-fb") ||
1059  cmdline.isset("fp-reachability-slice"))
1060  {
1061  if(cmdline.isset("show-custom-bitvector-analysis") ||
1062  cmdline.isset("custom-bitvector-analysis"))
1063  {
1064  config.ansi_c.defines.push_back(
1065  std::string(CPROVER_PREFIX) + "CUSTOM_BITVECTOR_ANALYSIS");
1066  }
1067 
1068  // remove inline assembler as that may yield further library function calls
1069  // that need to be resolved
1071 
1072  // add the library
1073  log.status() << "Adding CPROVER library (" << config.ansi_c.arch << ")"
1074  << messaget::eom;
1078  // library functions may introduce inline assembler
1079  while(has_asm(goto_model))
1080  {
1086  }
1087  }
1088 
1089  {
1091 
1092  if(
1096  {
1098 
1100  }
1101  }
1102 
1103  // skip over selected loops
1104  if(cmdline.isset("skip-loops"))
1105  {
1106  log.status() << "Adding gotos to skip loops" << messaget::eom;
1107  if(skip_loops(
1109  {
1110  throw 0;
1111  }
1112  }
1113 
1114  // now do full inlining, if requested
1115  if(cmdline.isset("inline"))
1116  {
1118 
1119  if(cmdline.isset("show-custom-bitvector-analysis") ||
1120  cmdline.isset("custom-bitvector-analysis"))
1121  {
1125  }
1126 
1127  log.status() << "Performing full inlining" << messaget::eom;
1129  }
1130 
1131  if(cmdline.isset("show-custom-bitvector-analysis") ||
1132  cmdline.isset("custom-bitvector-analysis"))
1133  {
1134  log.status() << "Propagating Constants" << messaget::eom;
1135  constant_propagator_ait constant_propagator_ai(goto_model);
1137  }
1138 
1139  if(cmdline.isset("escape-analysis"))
1140  {
1144 
1145  // recalculate numbers, etc.
1147 
1148  log.status() << "Escape Analysis" << messaget::eom;
1149  escape_analysist escape_analysis;
1150  escape_analysis(goto_model);
1151  escape_analysis.instrument(goto_model);
1152 
1153  // inline added functions, they are often small
1155 
1156  // recalculate numbers, etc.
1158  }
1159 
1160  if(cmdline.isset("loop-contracts-file"))
1161  {
1162  const auto file_name = cmdline.get_value("loop-contracts-file");
1163  contracts_wranglert contracts_wrangler(
1164  goto_model, file_name, ui_message_handler);
1165  }
1166 
1167  bool use_dfcc = cmdline.isset(FLAG_DFCC);
1168  if(use_dfcc)
1169  {
1170  if(cmdline.get_values(FLAG_DFCC).size() != 1)
1171  {
1173  "Redundant options detected",
1174  "--" FLAG_DFCC,
1175  "Use a single " FLAG_DFCC " option");
1176  }
1177 
1179  log.status() << "Trying to force one backedge per target" << messaget::eom;
1181 
1182  const irep_idt harness_id(cmdline.get_value(FLAG_DFCC));
1183 
1184  std::set<irep_idt> to_replace(
1187 
1188  if(
1191  {
1193  "Mutually exclusive options detected",
1195  "Use either --" FLAG_ENFORCE_CONTRACT
1196  " or --" FLAG_ENFORCE_CONTRACT_REC);
1197  }
1198 
1199  auto &to_enforce = !cmdline.get_values(FLAG_ENFORCE_CONTRACT_REC).empty()
1202 
1203  bool allow_recursive_calls =
1205 
1206  std::set<std::string> to_exclude_from_nondet_static(
1207  cmdline.get_values("nondet-static-exclude").begin(),
1208  cmdline.get_values("nondet-static-exclude").end());
1209 
1210  if(
1213  {
1214  // When the model is produced by Kani, we must not automatically unwind
1215  // the backjump introduced by the loop transformation.
1216  // Automatic unwinding duplicates assertions found in the loop body, and
1217  // since Kani expects property identifiers to remain unique. Having
1218  // duplicate instances of the assertions makes Kani fail to handle the
1219  // analysis results.
1220  log.warning() << "**** WARNING: transformed loops will not be unwound "
1221  << "after applying loop contracts. Remember to unwind "
1222  << "them at least twice to pass unwinding-assertions."
1223  << messaget::eom;
1224  }
1225 
1226  dfcc(
1227  options,
1228  goto_model,
1229  harness_id,
1230  to_enforce.empty() ? std::optional<irep_idt>{}
1231  : std::optional<irep_idt>{to_enforce.front()},
1232  allow_recursive_calls,
1233  to_replace,
1236  to_exclude_from_nondet_static,
1238  }
1239  else if((cmdline.isset(FLAG_LOOP_CONTRACTS) ||
1242  {
1244  log.status() << "Trying to force one backedge per target" << messaget::eom;
1246  code_contractst contracts(goto_model, log);
1247 
1248  std::set<std::string> to_replace(
1251 
1252  std::set<std::string> to_enforce(
1255 
1256  std::set<std::string> to_exclude_from_nondet_static(
1257  cmdline.get_values("nondet-static-exclude").begin(),
1258  cmdline.get_values("nondet-static-exclude").end());
1259 
1260  // It's important to keep the order of contracts instrumentation, i.e.,
1261  // first replacement then enforcement. We rely on contract replacement
1262  // and inlining of sub-function calls to properly annotate all
1263  // assignments.
1264  contracts.replace_calls(to_replace);
1265  contracts.enforce_contracts(to_enforce, to_exclude_from_nondet_static);
1266 
1268  {
1270  {
1271  contracts.unwind_transformed_loops = false;
1272  // When the model is produced by Kani, we must not automatically unwind
1273  // the backjump introduced by the loop transformation.
1274  // Automatic unwinding duplicates assertions found in the loop body, and
1275  // since Kani expects property identifiers to remain unique. Having
1276  // duplicate instances of the assertions makes Kani fail to handle the
1277  // analysis results.
1278  log.warning() << "**** WARNING: transformed loops will not be unwound "
1279  << "after applying loop contracts. Remember to unwind "
1280  << "them at least twice to pass unwinding-assertions."
1281  << messaget::eom;
1282  }
1283  contracts.apply_loop_contracts(to_exclude_from_nondet_static);
1284  }
1285  }
1286 
1287  if(cmdline.isset("value-set-fi-fp-removal"))
1288  {
1291  }
1292 
1293  // replace function pointers, if explicitly requested
1294  if(cmdline.isset("remove-function-pointers"))
1295  {
1297  }
1298  else if(cmdline.isset("remove-const-function-pointers"))
1299  {
1301  }
1302 
1303  if(cmdline.isset("replace-calls"))
1304  {
1306 
1307  replace_callst replace_calls;
1308  replace_calls(goto_model, cmdline.get_values("replace-calls"));
1309  }
1310 
1311  if(cmdline.isset("function-inline"))
1312  {
1313  std::string function=cmdline.get_value("function-inline");
1314  PRECONDITION(!function.empty());
1315 
1316  bool caching=!cmdline.isset("no-caching");
1317 
1319 
1320  log.status() << "Inlining calls of function '" << function << "'"
1321  << messaget::eom;
1322 
1323  if(!cmdline.isset("log"))
1324  {
1326  goto_model, function, ui_message_handler, true, caching);
1327  }
1328  else
1329  {
1330  std::string filename=cmdline.get_value("log");
1331  bool have_file=!filename.empty() && filename!="-";
1332 
1334  goto_model, function, ui_message_handler, true, caching);
1335 
1336  if(have_file)
1337  {
1338  std::ofstream of(widen_if_needed(filename));
1339 
1340  if(!of)
1341  throw "failed to open file "+filename;
1342 
1343  of << result;
1344  of.close();
1345  }
1346  else
1347  {
1348  std::cout << result << '\n';
1349  }
1350  }
1351 
1354  }
1355 
1356  if(cmdline.isset("partial-inline"))
1357  {
1359 
1360  log.status() << "Partial inlining" << messaget::eom;
1362 
1365  }
1366 
1367  if(cmdline.isset("remove-calls-no-body"))
1368  {
1369  log.status() << "Removing calls to functions without a body"
1370  << messaget::eom;
1371 
1372  remove_calls_no_bodyt remove_calls_no_body;
1373  remove_calls_no_body(goto_model.goto_functions, ui_message_handler);
1374 
1377  }
1378 
1379  if(cmdline.isset("constant-propagator"))
1380  {
1383 
1384  log.status() << "Propagating Constants" << messaget::eom;
1385  log.warning() << "**** WARNING: Constant propagation as performed by "
1386  "goto-instrument is not expected to be sound. Do not use "
1387  "--constant-propagator if soundness is important for your "
1388  "use case."
1389  << messaget::eom;
1390 
1391  constant_propagator_ait constant_propagator_ai(goto_model);
1393  }
1394 
1395  if(cmdline.isset("generate-function-body"))
1396  {
1397  optionst c_object_factory_options;
1398  parse_c_object_factory_options(cmdline, c_object_factory_options);
1399  c_object_factory_parameterst object_factory_parameters(
1400  c_object_factory_options);
1401 
1402  auto generate_implementation = generate_function_bodies_factory(
1403  cmdline.get_value("generate-function-body-options"),
1404  object_factory_parameters,
1408  std::regex(cmdline.get_value("generate-function-body")),
1409  *generate_implementation,
1410  goto_model,
1412  }
1413 
1414  if(cmdline.isset("generate-havocing-body"))
1415  {
1416  optionst c_object_factory_options;
1417  parse_c_object_factory_options(cmdline, c_object_factory_options);
1418  c_object_factory_parameterst object_factory_parameters(
1419  c_object_factory_options);
1420 
1421  auto options_split =
1422  split_string(cmdline.get_value("generate-havocing-body"), ',');
1423  if(options_split.size() < 2)
1425  "not enough arguments for this option", "--generate-havocing-body"};
1426 
1427  if(options_split.size() == 2)
1428  {
1429  auto generate_implementation = generate_function_bodies_factory(
1430  std::string{"havoc,"} + options_split.back(),
1431  object_factory_parameters,
1435  std::regex(options_split[0]),
1436  *generate_implementation,
1437  goto_model,
1439  }
1440  else
1441  {
1442  CHECK_RETURN(options_split.size() % 2 == 1);
1443  for(size_t i = 1; i + 1 < options_split.size(); i += 2)
1444  {
1445  auto generate_implementation = generate_function_bodies_factory(
1446  std::string{"havoc,"} + options_split[i + 1],
1447  object_factory_parameters,
1451  options_split[0],
1452  options_split[i],
1453  *generate_implementation,
1454  goto_model,
1456  }
1457  }
1458  }
1459 
1460  // add generic checks, if needed
1463 
1464  // check for uninitalized local variables
1465  if(cmdline.isset("uninitialized-check"))
1466  {
1467  log.status() << "Adding checks for uninitialized local variables"
1468  << messaget::eom;
1470  }
1471 
1472  // check for maximum call stack size
1473  if(cmdline.isset("stack-depth"))
1474  {
1475  log.status() << "Adding check for maximum call stack size" << messaget::eom;
1476  stack_depth(
1477  goto_model,
1478  safe_string2size_t(cmdline.get_value("stack-depth")),
1480  }
1481 
1482  // ignore default/user-specified initialization of variables with static
1483  // lifetime
1484  if(cmdline.isset("nondet-static-exclude"))
1485  {
1486  log.status() << "Adding nondeterministic initialization "
1487  "of static/global variables except for "
1488  "the specified ones."
1489  << messaget::eom;
1490  std::set<std::string> to_exclude(
1491  cmdline.get_values("nondet-static-exclude").begin(),
1492  cmdline.get_values("nondet-static-exclude").end());
1493  nondet_static(goto_model, to_exclude);
1494  }
1495  else if(cmdline.isset("nondet-static"))
1496  {
1497  log.status() << "Adding nondeterministic initialization "
1498  "of static/global variables"
1499  << messaget::eom;
1501  }
1502 
1503  if(cmdline.isset("slice-global-inits"))
1504  {
1506 
1507  log.status() << "Slicing away initializations of unused global variables"
1508  << messaget::eom;
1510  }
1511 
1512  if(cmdline.isset("string-abstraction"))
1513  {
1516 
1517  log.status() << "String Abstraction" << messaget::eom;
1519  }
1520 
1521  // some analyses require function pointer removal and partial inlining
1522 
1523  if(cmdline.isset("remove-pointers") ||
1524  cmdline.isset("race-check") ||
1525  cmdline.isset("mm") ||
1526  cmdline.isset("isr") ||
1527  cmdline.isset("concurrency"))
1528  {
1530 
1531  log.status() << "Pointer Analysis" << messaget::eom;
1533  value_set_analysist value_set_analysis(ns);
1534  value_set_analysis(goto_model);
1535 
1536  if(cmdline.isset("remove-pointers"))
1537  {
1538  // removing pointers
1539  log.status() << "Removing Pointers" << messaget::eom;
1540  remove_pointers(goto_model, value_set_analysis, ui_message_handler);
1541  }
1542 
1543  if(cmdline.isset("race-check"))
1544  {
1545  log.status() << "Adding Race Checks" << messaget::eom;
1546  race_check(value_set_analysis, goto_model, ui_message_handler);
1547  }
1548 
1549  if(cmdline.isset("mm"))
1550  {
1551  std::string mm=cmdline.get_value("mm");
1552  memory_modelt model;
1553 
1554  // strategy of instrumentation
1555  instrumentation_strategyt inst_strategy;
1556  if(cmdline.isset("one-event-per-cycle"))
1557  inst_strategy=one_event_per_cycle;
1558  else if(cmdline.isset("minimum-interference"))
1559  inst_strategy=min_interference;
1560  else if(cmdline.isset("read-first"))
1561  inst_strategy=read_first;
1562  else if(cmdline.isset("write-first"))
1563  inst_strategy=write_first;
1564  else if(cmdline.isset("my-events"))
1565  inst_strategy=my_events;
1566  else
1567  /* default: instruments all unsafe pairs */
1568  inst_strategy=all;
1569 
1570  const unsigned max_var=
1571  cmdline.isset("max-var")?
1573  const unsigned max_po_trans=
1574  cmdline.isset("max-po-trans")?
1575  unsafe_string2unsigned(cmdline.get_value("max-po-trans")):0;
1576 
1577  if(mm=="tso")
1578  {
1579  log.status() << "Adding weak memory (TSO) Instrumentation"
1580  << messaget::eom;
1581  model=TSO;
1582  }
1583  else if(mm=="pso")
1584  {
1585  log.status() << "Adding weak memory (PSO) Instrumentation"
1586  << messaget::eom;
1587  model=PSO;
1588  }
1589  else if(mm=="rmo")
1590  {
1591  log.status() << "Adding weak memory (RMO) Instrumentation"
1592  << messaget::eom;
1593  model=RMO;
1594  }
1595  else if(mm=="power")
1596  {
1597  log.status() << "Adding weak memory (Power) Instrumentation"
1598  << messaget::eom;
1599  model=Power;
1600  }
1601  else
1602  {
1603  log.error() << "Unknown weak memory model '" << mm << "'"
1604  << messaget::eom;
1605  model=Unknown;
1606  }
1607 
1609 
1610  if(cmdline.isset("force-loop-duplication"))
1611  loops=all_loops;
1612  if(cmdline.isset("no-loop-duplication"))
1613  loops=no_loop;
1614 
1615  if(model!=Unknown)
1616  weak_memory(
1617  model,
1618  value_set_analysis,
1619  goto_model,
1620  cmdline.isset("scc"),
1621  inst_strategy,
1622  !cmdline.isset("cfg-kill"),
1623  cmdline.isset("no-dependencies"),
1624  loops,
1625  max_var,
1626  max_po_trans,
1627  !cmdline.isset("no-po-rendering"),
1628  cmdline.isset("render-cluster-file"),
1629  cmdline.isset("render-cluster-function"),
1630  cmdline.isset("cav11"),
1631  cmdline.isset("hide-internals"),
1633  cmdline.isset("ignore-arrays"));
1634  }
1635 
1636  // Interrupt handler
1637  if(cmdline.isset("isr"))
1638  {
1639  log.status() << "Instrumenting interrupt handler" << messaget::eom;
1640  interrupt(
1641  value_set_analysis,
1642  goto_model,
1643  cmdline.get_value("isr"),
1645  }
1646 
1647  // Memory-mapped I/O
1648  if(cmdline.isset("mmio"))
1649  {
1650  log.status() << "Instrumenting memory-mapped I/O" << messaget::eom;
1651  mmio(value_set_analysis, goto_model, ui_message_handler);
1652  }
1653 
1654  if(cmdline.isset("concurrency"))
1655  {
1656  log.status() << "Sequentializing concurrency" << messaget::eom;
1657  concurrency(value_set_analysis, goto_model);
1658  }
1659  }
1660 
1661  if(cmdline.isset("interval-analysis"))
1662  {
1663  log.status() << "Interval analysis" << messaget::eom;
1665  }
1666 
1667  if(cmdline.isset("havoc-loops"))
1668  {
1669  log.status() << "Havocking loops" << messaget::eom;
1671  }
1672 
1673  if(cmdline.isset("k-induction"))
1674  {
1675  bool base_case=cmdline.isset("base-case");
1676  bool step_case=cmdline.isset("step-case");
1677 
1678  if(step_case && base_case)
1679  throw "please specify only one of --step-case and --base-case";
1680  else if(!step_case && !base_case)
1681  throw "please specify one of --step-case and --base-case";
1682 
1683  unsigned k=unsafe_string2unsigned(cmdline.get_value("k-induction"));
1684 
1685  if(k==0)
1686  throw "please give k>=1";
1687 
1688  log.status() << "Instrumenting k-induction for k=" << k << ", "
1689  << (base_case ? "base case" : "step case") << messaget::eom;
1690 
1691  k_induction(goto_model, base_case, step_case, k);
1692  }
1693 
1694  if(cmdline.isset("function-enter"))
1695  {
1696  log.status() << "Function enter instrumentation" << messaget::eom;
1698  goto_model,
1699  cmdline.get_value("function-enter"));
1700  }
1701 
1702  if(cmdline.isset("function-exit"))
1703  {
1704  log.status() << "Function exit instrumentation" << messaget::eom;
1705  function_exit(
1706  goto_model,
1707  cmdline.get_value("function-exit"));
1708  }
1709 
1710  if(cmdline.isset("branch"))
1711  {
1712  log.status() << "Branch instrumentation" << messaget::eom;
1713  branch(
1714  goto_model,
1715  cmdline.get_value("branch"));
1716  }
1717 
1718  // add failed symbols
1720 
1721  // recalculate numbers, etc.
1723 
1724  // add loop ids
1726 
1727  // label the assertions
1729 
1730  nondet_volatile(goto_model, options);
1731 
1732  // reachability slice?
1733  if(cmdline.isset("reachability-slice"))
1734  {
1736 
1737  log.status() << "Performing a reachability slice" << messaget::eom;
1738 
1739  // reachability_slicer requires that the model has unique location numbers:
1741 
1742  if(cmdline.isset("property"))
1743  {
1746  }
1747  else
1749  }
1750 
1751  if(cmdline.isset("fp-reachability-slice"))
1752  {
1754 
1755  log.status() << "Performing a function pointer reachability slice"
1756  << messaget::eom;
1758  goto_model,
1759  cmdline.get_comma_separated_values("fp-reachability-slice"),
1761  }
1762 
1763  // full slice?
1764  if(cmdline.isset("full-slice"))
1765  {
1769  // full_slicer requires that the model has unique location numbers:
1771 
1772  log.warning() << "**** WARNING: Experimental option --full-slice, "
1773  << "analysis results may be unsound. See "
1774  << "https://github.com/diffblue/cbmc/issues/260"
1775  << messaget::eom;
1776  log.status() << "Performing a full slice" << messaget::eom;
1777  if(cmdline.isset("property"))
1780  else
1781  {
1783  }
1784  }
1785 
1786  // splice option
1787  if(cmdline.isset("splice-call"))
1788  {
1789  log.status() << "Performing call splicing" << messaget::eom;
1790  std::string callercallee=cmdline.get_value("splice-call");
1791  if(splice_call(
1793  callercallee,
1796  throw 0;
1797  }
1798 
1799  // aggressive slicer
1800  if(cmdline.isset("aggressive-slice"))
1801  {
1803 
1804  // reachability_slicer requires that the model has unique location numbers:
1806 
1807  log.status() << "Slicing away initializations of unused global variables"
1808  << messaget::eom;
1810 
1811  log.status() << "Performing an aggressive slice" << messaget::eom;
1812  aggressive_slicert aggressive_slicer(goto_model, ui_message_handler);
1813 
1814  if(cmdline.isset("aggressive-slice-call-depth"))
1815  aggressive_slicer.call_depth =
1816  safe_string2unsigned(cmdline.get_value("aggressive-slice-call-depth"));
1817 
1818  if(cmdline.isset("aggressive-slice-preserve-function"))
1819  aggressive_slicer.preserve_functions(
1820  cmdline.get_values("aggressive-slice-preserve-function"));
1821 
1822  if(cmdline.isset("property"))
1823  aggressive_slicer.user_specified_properties =
1824  cmdline.get_values("property");
1825 
1826  if(cmdline.isset("aggressive-slice-preserve-functions-containing"))
1827  aggressive_slicer.name_snippets =
1828  cmdline.get_values("aggressive-slice-preserve-functions-containing");
1829 
1830  aggressive_slicer.preserve_all_direct_paths =
1831  cmdline.isset("aggressive-slice-preserve-all-direct-paths");
1832 
1833  aggressive_slicer.doit();
1834 
1836 
1837  log.status() << "Performing a reachability slice" << messaget::eom;
1838  if(cmdline.isset("property"))
1839  {
1842  }
1843  else
1845  }
1846 
1847  if(cmdline.isset("ensure-one-backedge-per-target"))
1848  {
1849  log.status() << "Trying to force one backedge per target" << messaget::eom;
1851  }
1852 
1853  // recalculate numbers, etc.
1855 }
1856 
1859 {
1860  std::cout << '\n'
1861  << banner_string("Goto-Instrument", CBMC_VERSION) << '\n'
1862  << align_center_with_border("Copyright (C) 2008-2013") << '\n'
1863  << align_center_with_border("Daniel Kroening") << '\n'
1864  << align_center_with_border("kroening@kroening.com") << '\n';
1865 
1866  // clang-format off
1867  std::cout << help_formatter(
1868  "\n"
1869  "Usage: \tPurpose:\n"
1870  "\n"
1871  " {bgoto-instrument} [{y-?}] [{y-h}] [{y--help}] \t show this help\n"
1872  " {bgoto-instrument} {y--version} \t show version and exit\n"
1873  " {bgoto-instrument} [options] {uin} [{uout}] \t perform analysis or"
1874  " instrumentation\n"
1875  "\n"
1876  "Dump Source:\n"
1877  HELP_DUMP_C
1878  " {y--horn} \t print program as constrained horn clauses\n"
1879  "\n"
1880  "Diagnosis:\n"
1883  " {y--show-symbol-table} \t show loaded symbol table\n"
1884  " {y--list-symbols} \t list symbols with type information\n"
1887  " {y--show-locations} \t show all source locations\n"
1888  " {y--dot} \t generate CFG graph in DOT format\n"
1889  " {y--print-internal-representation} \t show verbose internal"
1890  " representation of the program\n"
1891  " {y--list-undefined-functions} \t list functions without body\n"
1892  " {y--list-calls-args} \t list all function calls with their arguments\n"
1893  " {y--call-graph} \t show graph of function calls\n"
1894  " {y--reachable-call-graph} \t show graph of function calls potentially"
1895  " reachable from main function\n"
1898  " {y--validate-goto-binary} \t check the well-formedness of the passed in"
1899  " goto binary and then exit\n"
1900  " {y--interpreter} \t do concrete execution\n"
1901  "\n"
1902  "Data-flow analyses:\n"
1903  " {y--show-struct-alignment} \t show struct members that might be"
1904  " concurrently accessed\n"
1905  " {y--show-threaded} \t show instructions that may be executed by more than"
1906  " one thread\n"
1907  " {y--show-local-safe-pointers} \t show pointer expressions that are"
1908  " trivially dominated by a not-null check\n"
1909  " {y--show-safe-dereferences} \t show pointer expressions that are"
1910  " trivially dominated by a not-null check *and* used as a dereference"
1911  " operand\n"
1912  " {y--show-value-sets} \t show points-to information (using value sets)\n"
1913  " {y--show-global-may-alias} \t show may-alias information over globals\n"
1914  " {y--show-local-bitvector-analysis} \t show procedure-local pointer"
1915  " analysis\n"
1916  " {y--escape-analysis} \t perform escape analysis\n"
1917  " {y--show-escape-analysis} \t show results of escape analysis\n"
1918  " {y--custom-bitvector-analysis} \t perform configurable bitvector"
1919  " analysis\n"
1920  " {y--show-custom-bitvector-analysis} \t show results of configurable"
1921  " bitvector analysis\n"
1922  " {y--interval-analysis} \t perform interval analysis\n"
1923  " {y--show-intervals} \t show results of interval analysis\n"
1924  " {y--show-uninitialized} \t show maybe-uninitialized variables\n"
1925  " {y--show-points-to} \t show points-to information\n"
1926  " {y--show-rw-set} \t show read-write sets\n"
1927  " {y--show-call-sequences} \t show function call sequences\n"
1928  " {y--show-reaching-definitions} \t show reaching definitions\n"
1929  " {y--show-dependence-graph} \t show program-dependence graph\n"
1930  " {y--show-sese-regions} \t show single-entry-single-exit regions\n"
1931  "\n"
1932  "Safety checks:\n"
1933  " {y--no-assertions} \t ignore user assertions\n"
1936  " {y--stack-depth} {un} \t add check that call stack size of non-inlined"
1937  " functions never exceeds {un}\n"
1938  " {y--race-check} \t add floating-point data race checks\n"
1939  "\n"
1940  "Semantic transformations:\n"
1942  " {y--isr} {ufunction} \t instruments an interrupt service routine\n"
1943  " {y--mmio} \t instruments memory-mapped I/O\n"
1944  " {y--nondet-static} \t add nondeterministic initialization of variables"
1945  " with static lifetime\n"
1946  " {y--nondet-static-exclude} {ue} \t same as nondet-static except for the"
1947  " variable {ue} (use multiple times if required)\n"
1948  " {y--nondet-static-matching} {ur} \t add nondeterministic initialization"
1949  " of variables with static lifetime matching regex {ur}\n"
1950  " {y--function-enter} {uf}, {y--function-exit} {uf}, {y--branch} {uf} \t"
1951  " instruments a call to {uf} at the beginning, the exit, or a branch point,"
1952  " respectively\n"
1953  " {y--splice-call} {ucaller},{ucallee} \t prepends a call to {ucallee} in"
1954  " the body of {ucaller}\n"
1955  " {y--check-call-sequence} {useq} \t instruments checks to assert that all"
1956  " call sequences match {useq}\n"
1957  " {y--undefined-function-is-assume-false} \t convert each call to an"
1958  " undefined function to assume(false)\n"
1963  " {y--add-library} \t add models of C library functions\n"
1965  " {y--model-argc-argv} {un} \t model up to {un} command line arguments\n"
1966  " {y--remove-function-body} {uf} remove the implementation of function {uf}"
1967  " (may be repeated)\n"
1970  "\n"
1971  "Semantics-preserving transformations:\n"
1972  " {y--ensure-one-backedge-per-target} \t transform loop bodies such that"
1973  " there is a single edge back to the loop head\n"
1974  " {y--drop-unused-functions} \t drop functions trivially unreachable from"
1975  " main function\n"
1977  " {y--constant-propagator} \t propagate constants and simplify"
1978  " expressions\n"
1979  " {y--inline} \t perform full inlining\n"
1980  " {y--partial-inline} \t perform partial inlining\n"
1981  " {y--function-inline} {ufunction} \t transitively inline all calls"
1982  " {ufunction} makes\n"
1983  " {y--no-caching} \t disable caching of intermediate results during"
1984  " transitive function inlining\n"
1985  " {y--log} {ufile} \t log in JSON format which code segments were inlined,"
1986  " use with {y--function-inline}\n"
1987  " {y--remove-function-pointers} \t replace function pointers by case"
1988  " statement over function calls\n"
1990  " {y--value-set-fi-fp-removal} \t build flow-insensitive value set and"
1991  " replace function pointers by a case statement over the possible"
1992  " assignments. If the set of possible assignments is empty the function"
1993  " pointer is removed using the standard remove-function-pointers pass.\n"
1994  "\n"
1995  "Loop information and transformations:\n"
1997  " {y--unwindset-file_<file>} \t read unwindset from file\n"
1998  " {y--partial-loops} \t permit paths with partial loops\n"
1999  " {y--unwinding-assertions} \t generate unwinding assertions\n"
2000  " {y--continue-as-loops} \t add loop for remaining iterations after"
2001  " unwound part\n"
2002  " {y--k-induction} {uk} \t check loops with k-induction\n"
2003  " {y--step-case} \t k-induction: do step-case\n"
2004  " {y--base-case} \t k-induction: do base-case\n"
2005  " {y--havoc-loops} \t over-approximate all loops\n"
2006  " {y--accelerate} \t add loop accelerators\n"
2007  " {y--z3} \t use Z3 when computing loop accelerators\n"
2008  " {y--skip-loops {uloop-ids} \t add gotos to skip selected loops during"
2009  " execution\n"
2010  " {y--show-lexical-loops} \t show single-entry-single-back-edge loops\n"
2011  " {y--show-natural-loops} \t show natural loop heads\n"
2012  "\n"
2013  "Memory model instrumentations:\n"
2015  "\n"
2016  "Slicing:\n"
2019  " {y--full-slice} \t slice away instructions that don't affect assertions\n"
2020  " {y--property} {uid} \t slice with respect to specific property only\n"
2021  " {y--slice-global-inits} \t slice away initializations of unused global"
2022  " variables\n"
2023  " {y--aggressive-slice} \t remove bodies of any functions not on the"
2024  " shortest path between the start function and the function containing the"
2025  " property/properties\n"
2026  " {y--aggressive-slice-call-depth} {un} \t used with aggressive-slice,"
2027  " preserves all functions within {un} function calls of the functions on"
2028  " the shortest path\n"
2029  " {y--aggressive-slice-preserve-function} {uf} \t force the aggressive"
2030  " slicer to preserve function {uf}\n"
2031  " {y--aggressive-slice-preserve-functions-containing} {uf} \t force the"
2032  " aggressive slicer to preserve all functions with names containing {uf}\n"
2033  " {y--aggressive-slice-preserve-all-direct-paths} \t force aggressive"
2034  " slicer to preserve all direct paths\n"
2035  "\n"
2036  "Code contracts:\n"
2037  HELP_DFCC
2044  "\n"
2045  "User-interface options:\n"
2046  HELP_FLUSH
2047  " {y--xml} \t output files in XML where supported\n"
2048  " {y--xml-ui} \t use XML-formatted output\n"
2049  " {y--json-ui} \t use JSON-formatted output\n"
2050  " {y--verbosity} {u#} \t verbosity level\n"
2052  "\n");
2053  // clang-format on
2054 }
void accelerate_functions(goto_modelt &goto_model, message_handlert &message_handler, bool use_z3, guard_managert &guard_manager)
Definition: accelerate.cpp:635
Loop Acceleration.
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 print_struct_alignment_problems(const symbol_table_baset &symbol_table, std::ostream &out)
Alignment Checks.
void cprover_c_library_factory(const std::set< irep_idt > &functions, const symbol_table_baset &symbol_table, symbol_table_baset &dest_symbol_table, message_handlert &message_handler)
#define HELP_ANSI_C_LANGUAGE
configt config
Definition: config.cpp:25
void branch(goto_modelt &goto_model, const irep_idt &id)
Definition: branch.cpp:21
Branch Instrumentation.
void parse_c_object_factory_options(const cmdlinet &cmdline, optionst &options)
Parse the c object factory parameters from a given command line.
Function Call Graphs.
static void list_calls_and_arguments(const namespacet &ns, const goto_programt &goto_program)
void check_call_sequence(const goto_modelt &goto_model)
void show_call_sequences(const irep_idt &caller, const goto_programt &goto_program)
Memory-mapped I/O Instrumentation for Goto Programs.
void show_class_hierarchy(const class_hierarchyt &hierarchy, ui_message_handlert &message_handler, bool children_only)
Output the class hierarchy.
Class Hierarchy.
#define HELP_SHOW_CLASS_HIERARCHY
The aggressive slicer removes the body of all the functions except those on the shortest path,...
std::list< std::string > user_specified_properties
void doit()
Removes the body of all functions except those on the shortest path or functions that are reachable f...
std::list< std::string > name_snippets
void preserve_functions(const std::list< std::string > &function_list)
Adds a list of functions to the set of functions for the aggressive slicer to preserve.
virtual void output(const namespacet &ns, const irep_idt &function_id, const goto_programt &goto_program, std::ostream &out) const
Output the abstract states for a single function.
Definition: ai.cpp:39
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition: ai.h:562
A call graph (https://en.wikipedia.org/wiki/Call_graph) for a GOTO model or GOTO functions collection...
Definition: call_graph.h:44
void output_dot(std::ostream &out) const
Definition: call_graph.cpp:255
void output(std::ostream &out) const
Definition: call_graph.cpp:272
static call_grapht create_from_root_function(const goto_modelt &model, const irep_idt &root, bool collect_callsites)
Definition: call_graph.h:53
void output_xml(std::ostream &out) const
Definition: call_graph.cpp:282
Non-graph-based representation of the class hierarchy.
void output_dot(std::ostream &) const
Output class hierarchy in Graphviz DOT format.
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
void apply_loop_contracts(const std::set< std::string > &to_exclude_from_nondet_init={})
Applies loop contract transformations.
Definition: contracts.cpp:1472
void enforce_contracts(const std::set< std::string > &to_enforce, const std::set< std::string > &to_exclude_from_nondet_init={})
Turn requires & ensures into assumptions and assertions for each of the named functions.
Definition: contracts.cpp:1553
void replace_calls(const std::set< std::string > &to_replace)
Replace all calls to each function in the to_replace set with that function's contract.
Definition: contracts.cpp:1432
bool unwind_transformed_loops
Definition: contracts.h:145
bool set(const cmdlinet &cmdline)
Definition: config.cpp:798
void set_from_symbol_table(const symbol_table_baset &)
Definition: config.cpp:1266
struct configt::ansi_ct ansi_c
void check(const goto_modelt &, bool xml, std::ostream &)
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
bool empty() const
Definition: dstring.h:89
void instrument(goto_modelt &)
void get(const std::string &executable)
Definition: gcc_version.cpp:18
This is a may analysis (i.e.
void compute_loop_numbers()
function_mapt function_map
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
void help() override
display command line help
void do_indirect_call_and_rtti_removal(bool force=false)
void do_remove_const_function_pointers_only()
Remove function pointers that can be resolved by analysing const variables (i.e.
int doit() override
invoke main modules
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
symbol_tablet symbol_table
Symbol table.
Definition: goto_model.h:31
goto_functionst goto_functions
GOTO functions.
Definition: goto_model.h:34
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:73
unwind_strategyt
Definition: unwind.h:25
jsont output_log_json() const
Definition: unwind.h:77
void output_dot(std::ostream &out) const
Definition: graph.h:990
Thrown when users pass incorrect command line arguments, for example passing no files to analysis or ...
Definition: json.h:27
void output(std::ostream &out, const goto_functiont &goto_function, const namespacet &ns) const
A very simple, cheap analysis to determine when dereference operations are trivially guarded by a che...
void output_safe_dereferences(std::ostream &stream, const goto_programt &program, const namespacet &ns)
Output safely dereferenced expressions per instruction in human-readable format.
void output(std::ostream &stream, const goto_programt &program, const namespacet &ns)
Output non-null expressions per instruction in human-readable format.
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
message_handlert & get_message_handler()
Definition: message.h:184
@ 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 lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:148
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
void set_option(const std::string &option, const bool value)
Definition: options.cpp:28
virtual int main()
ui_message_handlert ui_message_handler
Definition: parse_options.h:45
void output(std::ostream &out) const
Definition: points_to.cpp:33
void output(std::ostream &out, const goto_programt &goto_program, const namespacet &ns) const
Expression to hold a symbol (variable)
Definition: std_expr.h:131
Symbol table entry.
Definition: symbol.h:28
typet type
Type of symbol.
Definition: symbol.h:31
irep_idt name
The unique identifier.
Definition: symbol.h:40
virtual uit get_ui() const
Definition: ui_message.h:33
This template class implements a data-flow analysis which keeps track of what values different variab...
void concurrency(value_setst &value_sets, goto_modelt &goto_model)
Encoding for Threaded Goto Programs.
#define HELP_CONFIG_LIBRARY
Definition: config.h:77
Constant propagation.
#define HELP_REPLACE_CALL
Definition: contracts.h:46
#define FLAG_REPLACE_CALL
Definition: contracts.h:45
#define FLAG_ENFORCE_CONTRACT
Definition: contracts.h:50
#define HELP_LOOP_CONTRACTS
Definition: contracts.h:33
#define FLAG_LOOP_CONTRACTS
Definition: contracts.h:32
#define HELP_LOOP_CONTRACTS_NO_UNWIND
Definition: contracts.h:37
#define HELP_ENFORCE_CONTRACT
Definition: contracts.h:51
#define HELP_LOOP_CONTRACTS_FILE
Definition: contracts.h:41
#define FLAG_LOOP_CONTRACTS_NO_UNWIND
Definition: contracts.h:36
void count_eloc(const goto_modelt &goto_model)
Definition: count_eloc.cpp:54
void print_global_state_size(const goto_modelt &goto_model)
Definition: count_eloc.cpp:159
void print_path_lengths(const goto_modelt &goto_model)
Definition: count_eloc.cpp:86
void list_eloc(const goto_modelt &goto_model)
Definition: count_eloc.cpp:68
#define HELP_GOTO_PROGRAM_STATS
Definition: count_eloc.h:30
void cprover_cpp_library_factory(const std::set< irep_idt > &functions, const symbol_table_baset &symbol_table, symbol_table_baset &dest_symbol_table, message_handlert &message_handler)
static void show_goto_functions(const goto_modelt &goto_model)
#define CPROVER_PREFIX
Field-insensitive, location-sensitive bitvector analysis.
Field-Sensitive Program Dependence Analysis, Litvak et al., FSE 2010.
#define FLAG_ENFORCE_CONTRACT_REC
Definition: dfcc.h:63
#define FLAG_DFCC
Definition: dfcc.h:55
#define HELP_DFCC
Definition: dfcc.h:58
#define HELP_ENFORCE_CONTRACT_REC
Definition: dfcc.h:65
void document_properties_latex(const goto_modelt &goto_model, std::ostream &out)
void document_properties_html(const goto_modelt &goto_model, std::ostream &out)
#define HELP_DOCUMENT_PROPERTIES
void dot(const goto_modelt &src, std::ostream &out)
Definition: dot.cpp:359
Dump Goto-Program as DOT Graph.
void dump_cpp(const goto_functionst &src, const bool use_system_headers, const bool use_all_headers, const bool include_harness, const namespacet &ns, std::ostream &out)
Definition: dump_c.cpp:1681
void dump_c(const goto_functionst &src, const bool use_system_headers, const bool use_all_headers, const bool include_harness, const namespacet &ns, std::ostream &out)
Definition: dump_c.cpp:1668
void dump_c_type_header(const goto_functionst &src, const bool use_system_headers, const bool use_all_headers, const bool include_harness, const namespacet &ns, const std::string module, std::ostream &out)
Definition: dump_c.cpp:1703
#define HELP_DUMP_C
Definition: dump_c.h:51
bool ensure_one_backedge_per_target(goto_programt::targett &it, goto_programt &goto_program)
Ensure one backedge per target.
Field-insensitive, location-sensitive, over-approximative escape analysis.
Document and give macros for the exit codes of CPROVER binaries.
#define CPROVER_EXIT_CONVERSION_FAILED
Failure to convert / write to another format.
Definition: exit_codes.h:62
#define CPROVER_EXIT_INTERNAL_ERROR
An error has been encountered during processing the requested analysis.
Definition: exit_codes.h:45
#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)
void function_exit(goto_modelt &goto_model, const irep_idt &id)
Definition: function.cpp:102
void function_enter(goto_modelt &goto_model, const irep_idt &id)
Definition: function.cpp:77
Function Entering and Exiting.
void configure_gcc(const gcc_versiont &gcc_version)
std::unique_ptr< generate_function_bodiest > generate_function_bodies_factory(const std::string &options, const c_object_factory_parameterst &object_factory_parameters, const symbol_tablet &symbol_table, message_handlert &message_handler)
Create the type that actually generates the functions.
void generate_function_bodies(const std::regex &functions_regex, const generate_function_bodiest &generate_function_body, goto_modelt &model, message_handlert &message_handler)
Generate function bodies with some default behavior: assert-false, assume-false, assert-false-assume-...
#define HELP_REPLACE_FUNCTION_BODY
Field-insensitive, location-sensitive, over-approximative escape analysis.
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.
void goto_check_c(const irep_idt &function_identifier, goto_functionst::goto_functiont &goto_function, const namespacet &ns, const optionst &options, message_handlert &message_handler)
#define PARSE_OPTIONS_GOTO_CHECK(cmdline, options)
Definition: goto_check_c.h:109
#define HELP_GOTO_CHECK
Definition: goto_check_c.h:57
void goto_inline(goto_modelt &goto_model, message_handlert &message_handler, bool adjust_function)
Inline every function call into the entry_point() function.
Definition: goto_inline.cpp:26
void goto_function_inline(goto_modelt &goto_model, const irep_idt function, message_handlert &message_handler, bool adjust_function, bool caching)
Transitively inline all function calls made from a particular function.
void goto_partial_inline(goto_modelt &goto_model, message_handlert &message_handler, unsigned smallfunc_limit, bool adjust_function)
Inline all function calls to functions either marked as "inlined" or smaller than smallfunc_limit (by...
jsont goto_function_inline_and_log(goto_modelt &goto_model, const irep_idt function, message_handlert &message_handler, bool adjust_function, bool caching)
Function Inlining This gives a number of different interfaces to the function inlining functionality ...
Command Line Parsing.
#define forall_goto_program_instructions(it, program)
void remove_pointers(goto_modelt &goto_model, value_setst &value_sets, message_handlert &message_handler)
Remove dereferences in all expressions contained in the program goto_model.
#define HELP_REMOVE_POINTERS
void dfcc(const optionst &options, goto_modelt &goto_model, const irep_idt &harness_id, const std::optional< irep_idt > &to_check, const bool allow_recursive_calls, const std::set< irep_idt > &to_replace, const bool apply_loop_contracts, const bool unwind_transformed_loops, const std::set< std::string > &to_exclude_from_nondet_static, message_handlert &message_handler)
Applies function contracts transformation to GOTO model, using the dynamic frame condition checking a...
Definition: dfcc.cpp:115
Guard Data Structure.
void havoc_loops(goto_modelt &goto_model)
Havoc Loops.
Help Formatter.
static help_formattert help_formatter(const std::string &s)
void horn_encoding(const goto_modelt &goto_model, std::ostream &out)
Horn-clause Encoding.
bool insert_final_assert_false(goto_modelt &goto_model, const std::string &function_to_instrument, message_handlert &message_handler)
Transform a goto program by inserting assert(false) at the end of a given function function_to_instru...
Insert final assert false into a function.
#define HELP_INSERT_FINAL_ASSERT_FALSE
void interpreter(const goto_modelt &goto_model, message_handlert &message_handler)
Interpreter for GOTO Programs.
static void interrupt(value_setst &value_sets, const symbol_tablet &symbol_table, const irep_idt &function_id, goto_programt &goto_program, const symbol_exprt &interrupt_handler, const rw_set_baset &isr_rw_set, message_handlert &message_handler)
Definition: interrupt.cpp:58
Interrupt Instrumentation for Goto Programs.
void interval_analysis(goto_modelt &goto_model)
Initialises the abstract interpretation over interval domain and instruments instructions using inter...
Interval Analysis.
Interval Domain.
Over-approximate Concurrency for Threaded Goto Programs.
void k_induction(goto_modelt &goto_model, bool base_case, bool step_case, unsigned k)
k-induction
void label_function_pointer_call_sites(goto_modelt &goto_model)
This ensures that call instructions can be only one of two things:
Label function pointer call sites across a goto model.
Compute lexical loops in a goto_function.
void show_lexical_loops(const goto_modelt &goto_model, std::ostream &out)
Field-insensitive, location-sensitive bitvector analysis.
Local safe pointer analysis.
void show_loop_ids(ui_message_handlert::uit ui, const goto_modelt &goto_model)
Definition: loop_ids.cpp:21
Loop IDs.
void mm_io(symbol_tablet &symbol_table, goto_functionst &goto_functions, message_handlert &message_handler)
Definition: mm_io.cpp:155
Perform Memory-mapped I/O instrumentation.
static void mmio(value_setst &value_sets, const symbol_tablet &symbol_table, const irep_idt &function_id, goto_programt &goto_program, message_handlert &message_handler)
Definition: mmio.cpp:24
Memory-mapped I/O Instrumentation for Goto Programs.
bool model_argc_argv(goto_modelt &goto_model, unsigned max_argc, message_handlert &message_handler)
Set up argv with up to max_argc pointers into an array of 4096 bytes.
Initialize command line arguments.
Compute natural loops in a goto_function.
void show_natural_loops(const goto_modelt &goto_model, std::ostream &out)
Definition: natural_loops.h:97
void nondet_static_matching(goto_modelt &goto_model, const std::string &regex)
Nondeterministically initializes global scope variables that match the given regex.
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...
void parse_nondet_volatile_options(const cmdlinet &cmdline, optionst &options)
void nondet_volatile(goto_modelt &goto_model, const optionst &options)
Havoc reads from volatile expressions, if enabled in the options.
Volatile Variables.
#define HELP_NONDET_VOLATILE
Options.
void parameter_assignments(symbol_table_baset &symbol_table, goto_functionst &goto_functions)
removes returns
Add parameter assignments.
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)
Field-sensitive, location-insensitive points-to analysis.
static void race_check(value_setst &value_sets, symbol_table_baset &symbol_table, const irep_idt &function_id, goto_programt &goto_program, w_guardst &w_guards, message_handlert &message_handler)
Definition: race_check.cpp:160
Race Detection for Threaded Goto Programs.
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.
void function_path_reachability_slicer(goto_modelt &goto_model, const std::list< std::string > &functions_list, message_handlert &message_handler)
Perform reachability slicing on goto_model for selected functions.
#define HELP_FP_REACHABILITY_SLICER
#define HELP_REACHABILITY_SLICER
Range-based reaching definitions analysis (following Field- Sensitive Program Dependence Analysis,...
static bool read_goto_binary(const std::string &filename, symbol_tablet &, goto_functionst &, message_handlert &)
Read a goto binary from a file, but do not update config.
Read Goto Programs.
void remove_asm(goto_functionst &goto_functions, symbol_tablet &symbol_table, message_handlert &message_handler)
Replaces inline assembly instructions in the goto program (i.e., instructions of kind OTHER with a co...
Definition: remove_asm.cpp:575
bool has_asm(const goto_functionst &goto_functions)
returns true iff the given goto functions use asm instructions
Definition: remove_asm.cpp:598
Remove 'asm' statements by compiling them into suitable standard goto program instructions.
Remove calls to functions without a body.
#define HELP_REMOVE_CALLS_NO_BODY
#define HELP_REMOVE_CONST_FUNCTION_POINTERS
void remove_functions(goto_modelt &goto_model, const std::list< std::string > &names, message_handlert &message_handler)
Remove the body of all functions listed in "names" such that an analysis will treat it as a side-effe...
Remove function definition.
void remove_function_pointers(message_handlert &_message_handler, goto_modelt &goto_model, bool only_remove_const_fps)
Remove Indirect Function Calls.
void restore_returns(goto_modelt &goto_model)
restores return statements
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,...
#define HELP_REPLACE_CALLS
Definition: replace_calls.h:58
void parse_function_pointer_restriction_options_from_cmdline(const cmdlinet &cmdline, optionst &options)
void restrict_function_pointers(message_handlert &message_handler, goto_modelt &goto_model, const optionst &options)
Apply function pointer restrictions to a goto_model.
Given goto functions and a list of function parameters or globals that are function pointers with lis...
#define RESTRICT_FUNCTION_POINTER_OPT
#define RESTRICT_FUNCTION_POINTER_FROM_FILE_OPT
#define HELP_RESTRICT_FUNCTION_POINTER
#define RESTRICT_FUNCTION_POINTER_BY_NAME_OPT
static std::optional< exprt > rewrite_rw_ok(exprt expr, const namespacet &ns)
Rewrite r/w/rw_ok expressions to ones including prophecy variables recording the state.
void rewrite_union(exprt &expr)
We rewrite u.c for unions u into byte_extract(u, 0), and { .c = v } into byte_update(NIL,...
Symbolic Execution.
Race Detection for Threaded Goto Programs.
Single-entry, single-exit region analysis.
void label_properties(goto_modelt &goto_model)
Set the properties to check.
#define HELP_SHOW_GOTO_FUNCTIONS
void show_locations(ui_message_handlert::uit ui, const irep_idt function_id, const goto_programt &goto_program)
Show program locations.
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 show_value_sets(ui_message_handlert::uit ui, const goto_modelt &goto_model, const value_set_analysist &value_set_analysis)
Show Value Sets.
static bool skip_loops(goto_programt &goto_program, const loop_idst &loop_ids, messaget &message)
Definition: skip_loops.cpp:24
Skip over selected loops by adding gotos.
void slice_global_inits(goto_modelt &goto_model, message_handlert &message_handler)
Remove initialization of global variables that are not used in any function reachable from the entry ...
Remove initializations of unused global variables.
bool splice_call(goto_functionst &goto_functions, const std::string &callercallee, const symbol_table_baset &symbol_table, message_handlert &message_handler)
Definition: splice_call.cpp:35
Harnessing for goto functions.
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
static void stack_depth(goto_programt &goto_program, const symbol_exprt &symbol, const std::size_t i_depth, const exprt &max_depth)
Definition: stack_depth.cpp:49
Stack depth checks.
unsigned safe_string2unsigned(const std::string &str, int base)
Definition: string2int.cpp:16
unsigned unsafe_string2unsigned(const std::string &str, int base)
Definition: string2int.cpp:35
std::size_t safe_string2size_t(const std::string &str, int base)
Definition: string2int.cpp:23
void string_abstraction(goto_modelt &goto_model, message_handlert &message_handler)
String Abstraction.
void split_string(const std::string &s, char delim, std::vector< std::string > &result, bool strip, bool remove_empty)
irep_idt arch
Definition: config.h:221
std::list< std::string > defines
Definition: config.h:265
preprocessort preprocessor
Definition: config.h:263
This is unused by this implementation of guards, but can be used by other implementations of the same...
Definition: guard_expr.h:20
void thread_exit_instrumentation(goto_programt &goto_program)
void mutex_init_instrumentation(const symbol_tablet &symbol_table, goto_programt &goto_program, typet lock_type)
#define HELP_TIMESTAMP
Definition: timestamper.h:14
#define HELP_FLUSH
Definition: ui_message.h:108
void list_undefined_functions(const goto_modelt &goto_model, std::ostream &os)
void undefined_function_abort_path(goto_modelt &goto_model)
Handling of functions without body.
#define widen_if_needed(s)
Definition: unicode.h:28
void add_uninitialized_locals_assertions(goto_modelt &goto_model)
void show_uninitialized(const goto_modelt &goto_model, std::ostream &out)
#define HELP_UNINITIALIZED_CHECK
Definition: uninitialized.h:29
Loop unwinding.
#define HELP_UNWINDSET
Definition: unwindset.h:79
#define HELP_VALIDATE
Value Set Propagation.
void value_set_fi_fp_removal(goto_modelt &goto_model, message_handlert &message_handler)
Builds the flow-insensitive value set for all function pointers and replaces function pointers with a...
flow insensitive value set function pointer removal
const char * CBMC_VERSION
void weak_memory(memory_modelt model, value_setst &value_sets, goto_modelt &goto_model, bool SCC, instrumentation_strategyt event_strategy, bool no_cfg_kill, bool no_dependencies, loop_strategyt duplicate_body, unsigned input_max_var, unsigned input_max_po_trans, bool render_po, bool render_file, bool render_function, bool cav11_option, bool hide_internals, message_handlert &message_handler, bool ignore_arrays)
#define HELP_WMM_FULL
Definition: weak_memory.h:92
memory_modelt
Definition: wmm.h:18
@ Unknown
Definition: wmm.h:19
@ TSO
Definition: wmm.h:20
@ RMO
Definition: wmm.h:22
@ PSO
Definition: wmm.h:21
@ Power
Definition: wmm.h:23
loop_strategyt
Definition: wmm.h:37
@ all_loops
Definition: wmm.h:39
@ arrays_only
Definition: wmm.h:38
@ no_loop
Definition: wmm.h:40
instrumentation_strategyt
Definition: wmm.h:27
@ my_events
Definition: wmm.h:32
@ one_event_per_cycle
Definition: wmm.h:33
@ min_interference
Definition: wmm.h:29
@ read_first
Definition: wmm.h:30
@ all
Definition: wmm.h:28
@ write_first
Definition: wmm.h:31
static void write_goto_binary(std::ostream &out, const symbol_table_baset &symbol_table, const goto_functionst &goto_functions, irep_serializationt &irepconverter)
Writes a goto program to disc, using goto binary format.
Write GOTO binaries.