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 
30 #include <goto-programs/loop_ids.h>
31 #include <goto-programs/mm_io.h>
49 
50 #include <analyses/call_graph.h>
56 #include <analyses/guard.h>
59 #include <analyses/is_threaded.h>
60 #include <analyses/lexical_loops.h>
63 #include <analyses/natural_loops.h>
65 #include <analyses/sese_regions.h>
66 #include <ansi-c/ansi_c_language.h>
68 #include <ansi-c/cprover_library.h>
69 #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 continue_as_loops=cmdline.isset("continue-as-loops");
205  bool partial_loops = cmdline.isset("partial-loops");
206  bool unwinding_assertions = cmdline.isset("unwinding-assertions") ||
207  (!continue_as_loops && !partial_loops &&
208  !cmdline.isset("no-unwinding-assertions"));
209  if(continue_as_loops)
210  {
211  if(unwinding_assertions)
212  {
213  throw "unwinding assertions cannot be used with "
214  "--continue-as-loops";
215  }
216  else if(partial_loops)
217  throw "partial loops cannot be used with --continue-as-loops";
218  }
219 
220  goto_unwindt::unwind_strategyt unwind_strategy=
222 
223  if(unwinding_assertions)
224  {
225  if(partial_loops)
227  else
229  }
230  else if(partial_loops)
231  {
233  }
234  else if(continue_as_loops)
235  {
237  }
238 
239  goto_unwindt goto_unwind;
240  goto_unwind(goto_model, unwindset, unwind_strategy);
241 
242  if(cmdline.isset("log"))
243  {
244  std::string filename=cmdline.get_value("log");
245  bool have_file=!filename.empty() && filename!="-";
246 
247  jsont result=goto_unwind.output_log_json();
248 
249  if(have_file)
250  {
251  std::ofstream of(widen_if_needed(filename));
252 
253  if(!of)
254  throw "failed to open file "+filename;
255 
256  of << result;
257  of.close();
258  }
259  else
260  {
261  std::cout << result << '\n';
262  }
263  }
264 
265  // goto_unwind holds references to instructions, only do remove_skip
266  // after having generated the log above
268  }
269  }
270 
271  if(cmdline.isset("show-threaded"))
272  {
274 
275  is_threadedt is_threaded(goto_model);
276 
277  for(const auto &gf_entry : goto_model.goto_functions.function_map)
278  {
279  std::cout << "////\n";
280  std::cout << "//// Function: " << gf_entry.first << '\n';
281  std::cout << "////\n\n";
282 
283  const goto_programt &goto_program = gf_entry.second.body;
284 
285  forall_goto_program_instructions(i_it, goto_program)
286  {
287  i_it->output(std::cout);
288  std::cout << "Is threaded: " << (is_threaded(i_it)?"True":"False")
289  << "\n\n";
290  }
291  }
292 
293  return CPROVER_EXIT_SUCCESS;
294  }
295 
296  if(cmdline.isset("insert-final-assert-false"))
297  {
298  log.status() << "Inserting final assert false" << messaget::eom;
299  bool fail = insert_final_assert_false(
300  goto_model,
301  cmdline.get_value("insert-final-assert-false"),
303  if(fail)
304  {
306  }
307  // otherwise, fall-through to write new binary
308  }
309 
310  if(cmdline.isset("show-value-sets"))
311  {
313 
314  // recalculate numbers, etc.
316 
317  log.status() << "Pointer Analysis" << messaget::eom;
319  value_set_analysist value_set_analysis(ns);
320  value_set_analysis(goto_model);
322  ui_message_handler.get_ui(), goto_model, value_set_analysis);
323  return CPROVER_EXIT_SUCCESS;
324  }
325 
326  if(cmdline.isset("show-global-may-alias"))
327  {
331 
332  // recalculate numbers, etc.
334 
335  global_may_alias_analysist global_may_alias_analysis;
336  global_may_alias_analysis(goto_model);
337  global_may_alias_analysis.output(goto_model, std::cout);
338 
339  return CPROVER_EXIT_SUCCESS;
340  }
341 
342  if(cmdline.isset("show-local-bitvector-analysis"))
343  {
346 
347  // recalculate numbers, etc.
349 
351 
352  for(const auto &gf_entry : goto_model.goto_functions.function_map)
353  {
354  local_bitvector_analysist local_bitvector_analysis(gf_entry.second, ns);
355  std::cout << ">>>>\n";
356  std::cout << ">>>> " << gf_entry.first << '\n';
357  std::cout << ">>>>\n";
358  local_bitvector_analysis.output(std::cout, gf_entry.second, ns);
359  std::cout << '\n';
360  }
361 
362  return CPROVER_EXIT_SUCCESS;
363  }
364 
365  if(cmdline.isset("show-local-safe-pointers") ||
366  cmdline.isset("show-safe-dereferences"))
367  {
368  // Ensure location numbering is unique:
370 
372 
373  for(const auto &gf_entry : goto_model.goto_functions.function_map)
374  {
375  local_safe_pointerst local_safe_pointers;
376  local_safe_pointers(gf_entry.second.body);
377  std::cout << ">>>>\n";
378  std::cout << ">>>> " << gf_entry.first << '\n';
379  std::cout << ">>>>\n";
380  if(cmdline.isset("show-local-safe-pointers"))
381  local_safe_pointers.output(std::cout, gf_entry.second.body, ns);
382  else
383  {
384  local_safe_pointers.output_safe_dereferences(
385  std::cout, gf_entry.second.body, ns);
386  }
387  std::cout << '\n';
388  }
389 
390  return CPROVER_EXIT_SUCCESS;
391  }
392 
393  if(cmdline.isset("show-sese-regions"))
394  {
395  // Ensure location numbering is unique:
397 
399 
400  for(const auto &gf_entry : goto_model.goto_functions.function_map)
401  {
402  sese_region_analysist sese_region_analysis;
403  sese_region_analysis(gf_entry.second.body);
404  std::cout << ">>>>\n";
405  std::cout << ">>>> " << gf_entry.first << '\n';
406  std::cout << ">>>>\n";
407  sese_region_analysis.output(std::cout, gf_entry.second.body, ns);
408  std::cout << '\n';
409  }
410 
411  return CPROVER_EXIT_SUCCESS;
412  }
413 
414  if(cmdline.isset("show-custom-bitvector-analysis"))
415  {
419 
421 
422  if(!cmdline.isset("inline"))
423  {
426  }
427 
428  // recalculate numbers, etc.
430 
431  custom_bitvector_analysist custom_bitvector_analysis;
432  custom_bitvector_analysis(goto_model);
433  custom_bitvector_analysis.output(goto_model, std::cout);
434 
435  return CPROVER_EXIT_SUCCESS;
436  }
437 
438  if(cmdline.isset("show-escape-analysis"))
439  {
443 
444  // recalculate numbers, etc.
446 
447  escape_analysist escape_analysis;
448  escape_analysis(goto_model);
449  escape_analysis.output(goto_model, std::cout);
450 
451  return CPROVER_EXIT_SUCCESS;
452  }
453 
454  if(cmdline.isset("custom-bitvector-analysis"))
455  {
459 
461 
462  if(!cmdline.isset("inline"))
463  {
466  }
467 
468  // recalculate numbers, etc.
470 
472 
473  custom_bitvector_analysist custom_bitvector_analysis;
474  custom_bitvector_analysis(goto_model);
475  custom_bitvector_analysis.check(
476  goto_model,
477  cmdline.isset("xml-ui"),
478  std::cout);
479 
480  return CPROVER_EXIT_SUCCESS;
481  }
482 
483  if(cmdline.isset("show-points-to"))
484  {
486 
487  // recalculate numbers, etc.
489 
491 
492  log.status() << "Pointer Analysis" << messaget::eom;
493  points_tot points_to;
494  points_to(goto_model);
495  points_to.output(std::cout);
496  return CPROVER_EXIT_SUCCESS;
497  }
498 
499  if(cmdline.isset("show-intervals"))
500  {
502 
503  // recalculate numbers, etc.
505 
506  log.status() << "Interval Analysis" << messaget::eom;
510  interval_analysis.output(goto_model, std::cout);
511  return CPROVER_EXIT_SUCCESS;
512  }
513 
514  if(cmdline.isset("show-call-sequences"))
515  {
518  return CPROVER_EXIT_SUCCESS;
519  }
520 
521  if(cmdline.isset("check-call-sequence"))
522  {
525  return CPROVER_EXIT_SUCCESS;
526  }
527 
528  if(cmdline.isset("list-calls-args"))
529  {
531 
533 
534  return CPROVER_EXIT_SUCCESS;
535  }
536 
537  if(cmdline.isset("show-rw-set"))
538  {
540 
541  if(!cmdline.isset("inline"))
542  {
544 
545  // recalculate numbers, etc.
547  }
548 
549  log.status() << "Pointer Analysis" << messaget::eom;
550  value_set_analysist value_set_analysis(ns);
551  value_set_analysis(goto_model);
552 
553  const symbolt &symbol=ns.lookup(ID_main);
554  symbol_exprt main(symbol.name, symbol.type);
555 
556  std::cout << rw_set_functiont(
557  value_set_analysis, goto_model, main, ui_message_handler);
558  return CPROVER_EXIT_SUCCESS;
559  }
560 
561  if(cmdline.isset("show-symbol-table"))
562  {
564  return CPROVER_EXIT_SUCCESS;
565  }
566 
567  if(cmdline.isset("show-reaching-definitions"))
568  {
571 
574  rd_analysis(goto_model);
575  rd_analysis.output(goto_model, std::cout);
576 
577  return CPROVER_EXIT_SUCCESS;
578  }
579 
580  if(cmdline.isset("show-dependence-graph"))
581  {
584 
586  dependence_grapht dependence_graph(ns, ui_message_handler);
587  dependence_graph(goto_model);
588  dependence_graph.output(goto_model, std::cout);
589  dependence_graph.output_dot(std::cout);
590 
591  return CPROVER_EXIT_SUCCESS;
592  }
593 
594  if(cmdline.isset("count-eloc"))
595  {
597  return CPROVER_EXIT_SUCCESS;
598  }
599 
600  if(cmdline.isset("list-eloc"))
601  {
603  return CPROVER_EXIT_SUCCESS;
604  }
605 
606  if(cmdline.isset("print-path-lengths"))
607  {
609  return CPROVER_EXIT_SUCCESS;
610  }
611 
612  if(cmdline.isset("print-global-state-size"))
613  {
615  return CPROVER_EXIT_SUCCESS;
616  }
617 
618  if(cmdline.isset("list-symbols"))
619  {
621  return CPROVER_EXIT_SUCCESS;
622  }
623 
624  if(cmdline.isset("show-uninitialized"))
625  {
626  show_uninitialized(goto_model, std::cout);
627  return CPROVER_EXIT_SUCCESS;
628  }
629 
630  if(cmdline.isset("interpreter"))
631  {
634 
635  log.status() << "Starting interpreter" << messaget::eom;
637  return CPROVER_EXIT_SUCCESS;
638  }
639 
640  if(cmdline.isset("show-claims") ||
641  cmdline.isset("show-properties"))
642  {
645  return CPROVER_EXIT_SUCCESS;
646  }
647 
648  if(cmdline.isset("document-claims-html") ||
649  cmdline.isset("document-properties-html"))
650  {
652  return CPROVER_EXIT_SUCCESS;
653  }
654 
655  if(cmdline.isset("document-claims-latex") ||
656  cmdline.isset("document-properties-latex"))
657  {
659  return CPROVER_EXIT_SUCCESS;
660  }
661 
662  if(cmdline.isset("show-loops"))
663  {
665  return CPROVER_EXIT_SUCCESS;
666  }
667 
668  if(cmdline.isset("show-natural-loops"))
669  {
670  show_natural_loops(goto_model, std::cout);
671  return CPROVER_EXIT_SUCCESS;
672  }
673 
674  if(cmdline.isset("show-lexical-loops"))
675  {
676  show_lexical_loops(goto_model, std::cout);
677  return CPROVER_EXIT_SUCCESS;
678  }
679 
680  if(cmdline.isset("print-internal-representation"))
681  {
682  for(auto const &pair : goto_model.goto_functions.function_map)
683  for(auto const &ins : pair.second.body.instructions)
684  {
685  if(ins.code().is_not_nil())
686  log.status() << ins.code().pretty() << messaget::eom;
687  if(ins.has_condition())
688  {
689  log.status() << "[guard] " << ins.condition().pretty()
690  << messaget::eom;
691  }
692  }
693  return CPROVER_EXIT_SUCCESS;
694  }
695 
696  if(
697  cmdline.isset("show-goto-functions") ||
698  cmdline.isset("list-goto-functions"))
699  {
701  goto_model, ui_message_handler, cmdline.isset("list-goto-functions"));
702  return CPROVER_EXIT_SUCCESS;
703  }
704 
705  if(cmdline.isset("list-undefined-functions"))
706  {
708  return CPROVER_EXIT_SUCCESS;
709  }
710 
711  // experimental: print structs
712  if(cmdline.isset("show-struct-alignment"))
713  {
715  return CPROVER_EXIT_SUCCESS;
716  }
717 
718  if(cmdline.isset("show-locations"))
719  {
721  return CPROVER_EXIT_SUCCESS;
722  }
723 
724  if(
725  cmdline.isset("dump-c") || cmdline.isset("dump-cpp") ||
726  cmdline.isset("dump-c-type-header"))
727  {
728  const bool is_cpp=cmdline.isset("dump-cpp");
729  const bool is_header = cmdline.isset("dump-c-type-header");
730  const bool h_libc=!cmdline.isset("no-system-headers");
731  const bool h_all=cmdline.isset("use-all-headers");
732  const bool harness=cmdline.isset("harness");
734 
735  // restore RETURN instructions in case remove_returns had been
736  // applied
738 
739  // dump_c (actually goto_program2code) requires valid instruction
740  // location numbers:
742 
743  if(cmdline.args.size()==2)
744  {
745  std::ofstream out(widen_if_needed(cmdline.args[1]));
746 
747  if(!out)
748  {
749  log.error() << "failed to write to '" << cmdline.args[1] << "'";
751  }
752  if(is_header)
753  {
756  h_libc,
757  h_all,
758  harness,
759  ns,
760  cmdline.get_value("dump-c-type-header"),
761  out);
762  }
763  else
764  {
765  (is_cpp ? dump_cpp : dump_c)(
766  goto_model.goto_functions, h_libc, h_all, harness, ns, out);
767  }
768  }
769  else
770  {
771  if(is_header)
772  {
775  h_libc,
776  h_all,
777  harness,
778  ns,
779  cmdline.get_value("dump-c-type-header"),
780  std::cout);
781  }
782  else
783  {
784  (is_cpp ? dump_cpp : dump_c)(
785  goto_model.goto_functions, h_libc, h_all, harness, ns, std::cout);
786  }
787  }
788 
789  return CPROVER_EXIT_SUCCESS;
790  }
791 
792  if(cmdline.isset("call-graph"))
793  {
795  call_grapht call_graph(goto_model);
796 
797  if(cmdline.isset("xml"))
798  call_graph.output_xml(std::cout);
799  else if(cmdline.isset("dot"))
800  call_graph.output_dot(std::cout);
801  else
802  call_graph.output(std::cout);
803 
804  return CPROVER_EXIT_SUCCESS;
805  }
806 
807  if(cmdline.isset("reachable-call-graph"))
808  {
810  call_grapht call_graph =
813  if(cmdline.isset("xml"))
814  call_graph.output_xml(std::cout);
815  else if(cmdline.isset("dot"))
816  call_graph.output_dot(std::cout);
817  else
818  call_graph.output(std::cout);
819 
820  return 0;
821  }
822 
823  if(cmdline.isset("show-class-hierarchy"))
824  {
825  class_hierarchyt hierarchy;
826  hierarchy(goto_model.symbol_table);
827  if(cmdline.isset("dot"))
828  hierarchy.output_dot(std::cout);
829  else
831 
832  return CPROVER_EXIT_SUCCESS;
833  }
834 
835  if(cmdline.isset("dot"))
836  {
838 
839  if(cmdline.args.size()==2)
840  {
841  std::ofstream out(widen_if_needed(cmdline.args[1]));
842 
843  if(!out)
844  {
845  log.error() << "failed to write to " << cmdline.args[1] << "'";
847  }
848 
849  dot(goto_model, out);
850  }
851  else
852  dot(goto_model, std::cout);
853 
854  return CPROVER_EXIT_SUCCESS;
855  }
856 
857  if(cmdline.isset("accelerate"))
858  {
860 
862 
863  log.status() << "Performing full inlining" << messaget::eom;
865 
866  log.status() << "Removing calls to functions without a body"
867  << messaget::eom;
868  remove_calls_no_bodyt remove_calls_no_body;
869  remove_calls_no_body(goto_model.goto_functions, ui_message_handler);
870 
871  log.status() << "Accelerating" << messaget::eom;
872  guard_managert guard_manager;
874  goto_model, ui_message_handler, cmdline.isset("z3"), guard_manager);
876  }
877 
878  if(cmdline.isset("horn"))
879  {
880  log.status() << "Horn-clause encoding" << messaget::eom;
882 
883  if(cmdline.args.size()==2)
884  {
885  std::ofstream out(widen_if_needed(cmdline.args[1]));
886 
887  if(!out)
888  {
889  log.error() << "Failed to open output file " << cmdline.args[1]
890  << messaget::eom;
892  }
893 
895  }
896  else
897  horn_encoding(goto_model, std::cout);
898 
899  return CPROVER_EXIT_SUCCESS;
900  }
901 
902  if(cmdline.isset("drop-unused-functions"))
903  {
906 
907  log.status() << "Removing unused functions" << messaget::eom;
909  }
910 
911  if(cmdline.isset("undefined-function-is-assume-false"))
912  {
915  }
916 
917  // write new binary?
918  if(cmdline.args.size()==2)
919  {
920  log.status() << "Writing GOTO program to '" << cmdline.args[1] << "'"
921  << messaget::eom;
922 
925  else
926  return CPROVER_EXIT_SUCCESS;
927  }
928  else if(cmdline.args.size() < 2)
929  {
931  "Invalid number of positional arguments passed",
932  "[in] [out]",
933  "goto-instrument needs one input and one output file, aside from other "
934  "flags");
935  }
936 
937  help();
939  }
940 // NOLINTNEXTLINE(readability/fn_size)
941 }
942 
944  bool force)
945 {
946  if(function_pointer_removal_done && !force)
947  return;
948 
950 
951  log.status() << "Function Pointer Removal" << messaget::eom;
953  log.status() << "Virtual function removal" << messaget::eom;
955  log.status() << "Cleaning inline assembler statements" << messaget::eom;
957 }
958 
963 {
964  // Don't bother if we've already done a full function pointer
965  // removal.
967  {
968  return;
969  }
970 
971  log.status() << "Removing const function pointers only" << messaget::eom;
974  goto_model,
975  true); // abort if we can't resolve via const pointers
976 }
977 
979 {
981  return;
982 
984 
985  if(!cmdline.isset("inline"))
986  {
987  log.status() << "Partial Inlining" << messaget::eom;
989  }
990 }
991 
993 {
995  return;
996 
997  remove_returns_done=true;
998 
999  log.status() << "Removing returns" << messaget::eom;
1001 }
1002 
1004 {
1005  log.status() << "Reading GOTO program from '" << cmdline.args[0] << "'"
1006  << messaget::eom;
1007 
1008  config.set(cmdline);
1009 
1010  auto result = read_goto_binary(cmdline.args[0], ui_message_handler);
1011 
1012  if(!result.has_value())
1013  throw 0;
1014 
1015  goto_model = std::move(result.value());
1016 
1018 }
1019 
1021 {
1022  optionst options;
1023 
1025 
1026  // disable simplify when adding various checks?
1027  if(cmdline.isset("no-simplify"))
1028  options.set_option("simplify", false);
1029  else
1030  options.set_option("simplify", true);
1031 
1032  // all checks supported by goto_check
1034 
1035  // initialize argv with valid pointers
1036  if(cmdline.isset("model-argc-argv"))
1037  {
1038  unsigned max_argc=
1039  safe_string2unsigned(cmdline.get_value("model-argc-argv"));
1040 
1041  log.status() << "Adding up to " << max_argc << " command line arguments"
1042  << messaget::eom;
1044  throw 0;
1045  }
1046 
1047  if(cmdline.isset("remove-function-body"))
1048  {
1050  goto_model,
1051  cmdline.get_values("remove-function-body"),
1053  }
1054 
1055  // we add the library in some cases, as some analyses benefit
1056 
1057  if(
1058  cmdline.isset("add-library") || cmdline.isset("mm") ||
1059  cmdline.isset("reachability-slice") ||
1060  cmdline.isset("reachability-slice-fb") ||
1061  cmdline.isset("fp-reachability-slice"))
1062  {
1063  if(cmdline.isset("show-custom-bitvector-analysis") ||
1064  cmdline.isset("custom-bitvector-analysis"))
1065  {
1066  config.ansi_c.defines.push_back(
1067  std::string(CPROVER_PREFIX) + "CUSTOM_BITVECTOR_ANALYSIS");
1068  }
1069 
1070  // remove inline assembler as that may yield further library function calls
1071  // that need to be resolved
1073 
1074  // add the library
1075  log.status() << "Adding CPROVER library (" << config.ansi_c.arch << ")"
1076  << messaget::eom;
1080  // library functions may introduce inline assembler
1081  while(has_asm(goto_model))
1082  {
1088  }
1089  }
1090 
1091  {
1093 
1094  if(
1098  {
1100 
1102  }
1103  }
1104 
1105  // skip over selected loops
1106  if(cmdline.isset("skip-loops"))
1107  {
1108  log.status() << "Adding gotos to skip loops" << messaget::eom;
1109  if(skip_loops(
1111  {
1112  throw 0;
1113  }
1114  }
1115 
1116  // now do full inlining, if requested
1117  if(cmdline.isset("inline"))
1118  {
1120 
1121  if(cmdline.isset("show-custom-bitvector-analysis") ||
1122  cmdline.isset("custom-bitvector-analysis"))
1123  {
1127  }
1128 
1129  log.status() << "Performing full inlining" << messaget::eom;
1131  }
1132 
1133  if(cmdline.isset("show-custom-bitvector-analysis") ||
1134  cmdline.isset("custom-bitvector-analysis"))
1135  {
1136  log.status() << "Propagating Constants" << messaget::eom;
1137  constant_propagator_ait constant_propagator_ai(goto_model);
1139  }
1140 
1141  if(cmdline.isset("escape-analysis"))
1142  {
1146 
1147  // recalculate numbers, etc.
1149 
1150  log.status() << "Escape Analysis" << messaget::eom;
1151  escape_analysist escape_analysis;
1152  escape_analysis(goto_model);
1153  escape_analysis.instrument(goto_model);
1154 
1155  // inline added functions, they are often small
1157 
1158  // recalculate numbers, etc.
1160  }
1161 
1162  if(cmdline.isset("loop-contracts-file"))
1163  {
1164  const auto file_name = cmdline.get_value("loop-contracts-file");
1165  contracts_wranglert contracts_wrangler(
1166  goto_model, file_name, ui_message_handler);
1167  }
1168 
1169  // Initialize loop contract config from cmdline.
1170  loop_contract_configt loop_contract_config = {
1174 
1175  if(
1178  {
1179  // After instrumentation, all annotated loops will be transformed to
1180  // loops execute exactly once. CBMC by default unwinds transformed loops
1181  // by twice.
1182  // Users may want to disable the default unwinding to avoid duplicate
1183  // assertions.
1184  log.warning() << "**** WARNING: transformed loops will not be unwound "
1185  << "after applying loop contracts. Note that transformed "
1186  << "loops require at least unwinding bounds 2 to pass "
1187  << "the unwinding assertions." << messaget::eom;
1188  }
1189 
1190  bool use_dfcc = cmdline.isset(FLAG_DFCC);
1191  if(use_dfcc)
1192  {
1193  if(cmdline.get_values(FLAG_DFCC).size() != 1)
1194  {
1196  "Redundant options detected",
1197  "--" FLAG_DFCC,
1198  "Use a single " FLAG_DFCC " option");
1199  }
1200 
1202  log.status() << "Trying to force one backedge per target" << messaget::eom;
1204 
1205  const irep_idt harness_id(cmdline.get_value(FLAG_DFCC));
1206 
1207  std::set<irep_idt> to_replace(
1210 
1211  if(
1214  {
1216  "Mutually exclusive options detected",
1218  "Use either --" FLAG_ENFORCE_CONTRACT
1219  " or --" FLAG_ENFORCE_CONTRACT_REC);
1220  }
1221 
1222  auto &to_enforce = !cmdline.get_values(FLAG_ENFORCE_CONTRACT_REC).empty()
1225 
1226  bool allow_recursive_calls =
1228 
1229  std::set<std::string> to_exclude_from_nondet_static(
1230  cmdline.get_values("nondet-static-exclude").begin(),
1231  cmdline.get_values("nondet-static-exclude").end());
1232 
1233  dfcc(
1234  options,
1235  goto_model,
1236  harness_id,
1237  to_enforce.empty() ? std::optional<irep_idt>{}
1238  : std::optional<irep_idt>{to_enforce.front()},
1239  allow_recursive_calls,
1240  to_replace,
1241  loop_contract_config,
1242  to_exclude_from_nondet_static,
1244  }
1245  else if((cmdline.isset(FLAG_LOOP_CONTRACTS) ||
1248  {
1250  log.status() << "Trying to force one backedge per target" << messaget::eom;
1252  code_contractst contracts(goto_model, log, loop_contract_config);
1253 
1254  std::set<std::string> to_replace(
1257 
1258  std::set<std::string> to_enforce(
1261 
1262  std::set<std::string> to_exclude_from_nondet_static(
1263  cmdline.get_values("nondet-static-exclude").begin(),
1264  cmdline.get_values("nondet-static-exclude").end());
1265 
1266  // It's important to keep the order of contracts instrumentation, i.e.,
1267  // first replacement then enforcement. We rely on contract replacement
1268  // and inlining of sub-function calls to properly annotate all
1269  // assignments.
1270  contracts.replace_calls(to_replace);
1271  contracts.enforce_contracts(to_enforce, to_exclude_from_nondet_static);
1272 
1274  {
1275  contracts.apply_loop_contracts(to_exclude_from_nondet_static);
1276  }
1277  }
1278 
1279  if(cmdline.isset("value-set-fi-fp-removal"))
1280  {
1283  }
1284 
1285  // replace function pointers, if explicitly requested
1286  if(cmdline.isset("remove-function-pointers"))
1287  {
1289  }
1290  else if(cmdline.isset("remove-const-function-pointers"))
1291  {
1293  }
1294 
1295  if(cmdline.isset("replace-calls"))
1296  {
1298 
1299  replace_callst replace_calls;
1300  replace_calls(goto_model, cmdline.get_values("replace-calls"));
1301  }
1302 
1303  if(cmdline.isset("function-inline"))
1304  {
1305  std::string function=cmdline.get_value("function-inline");
1306  PRECONDITION(!function.empty());
1307 
1308  bool caching=!cmdline.isset("no-caching");
1309 
1311 
1312  log.status() << "Inlining calls of function '" << function << "'"
1313  << messaget::eom;
1314 
1315  if(!cmdline.isset("log"))
1316  {
1318  goto_model, function, ui_message_handler, true, caching);
1319  }
1320  else
1321  {
1322  std::string filename=cmdline.get_value("log");
1323  bool have_file=!filename.empty() && filename!="-";
1324 
1326  goto_model, function, ui_message_handler, true, caching);
1327 
1328  if(have_file)
1329  {
1330  std::ofstream of(widen_if_needed(filename));
1331 
1332  if(!of)
1333  throw "failed to open file "+filename;
1334 
1335  of << result;
1336  of.close();
1337  }
1338  else
1339  {
1340  std::cout << result << '\n';
1341  }
1342  }
1343 
1346  }
1347 
1348  if(cmdline.isset("partial-inline"))
1349  {
1351 
1352  log.status() << "Partial inlining" << messaget::eom;
1354 
1357  }
1358 
1359  if(cmdline.isset("remove-calls-no-body"))
1360  {
1361  log.status() << "Removing calls to functions without a body"
1362  << messaget::eom;
1363 
1364  remove_calls_no_bodyt remove_calls_no_body;
1365  remove_calls_no_body(goto_model.goto_functions, ui_message_handler);
1366 
1369  }
1370 
1371  if(cmdline.isset("constant-propagator"))
1372  {
1375 
1376  log.status() << "Propagating Constants" << messaget::eom;
1377  log.warning() << "**** WARNING: Constant propagation as performed by "
1378  "goto-instrument is not expected to be sound. Do not use "
1379  "--constant-propagator if soundness is important for your "
1380  "use case."
1381  << messaget::eom;
1382 
1383  constant_propagator_ait constant_propagator_ai(goto_model);
1385  }
1386 
1387  if(cmdline.isset("generate-function-body"))
1388  {
1389  optionst c_object_factory_options;
1390  parse_c_object_factory_options(cmdline, c_object_factory_options);
1391  c_object_factory_parameterst object_factory_parameters(
1392  c_object_factory_options);
1393 
1394  auto generate_implementation = generate_function_bodies_factory(
1395  cmdline.get_value("generate-function-body-options"),
1396  object_factory_parameters,
1400  std::regex(cmdline.get_value("generate-function-body")),
1401  *generate_implementation,
1402  goto_model,
1404  }
1405 
1406  if(cmdline.isset("generate-havocing-body"))
1407  {
1408  optionst c_object_factory_options;
1409  parse_c_object_factory_options(cmdline, c_object_factory_options);
1410  c_object_factory_parameterst object_factory_parameters(
1411  c_object_factory_options);
1412 
1413  auto options_split =
1414  split_string(cmdline.get_value("generate-havocing-body"), ',');
1415  if(options_split.size() < 2)
1417  "not enough arguments for this option", "--generate-havocing-body"};
1418 
1419  if(options_split.size() == 2)
1420  {
1421  auto generate_implementation = generate_function_bodies_factory(
1422  std::string{"havoc,"} + options_split.back(),
1423  object_factory_parameters,
1427  std::regex(options_split[0]),
1428  *generate_implementation,
1429  goto_model,
1431  }
1432  else
1433  {
1434  CHECK_RETURN(options_split.size() % 2 == 1);
1435  for(size_t i = 1; i + 1 < options_split.size(); i += 2)
1436  {
1437  auto generate_implementation = generate_function_bodies_factory(
1438  std::string{"havoc,"} + options_split[i + 1],
1439  object_factory_parameters,
1443  options_split[0],
1444  options_split[i],
1445  *generate_implementation,
1446  goto_model,
1448  }
1449  }
1450  }
1451 
1452  // add generic checks, if needed
1455 
1456  // check for uninitalized local variables
1457  if(cmdline.isset("uninitialized-check"))
1458  {
1459  log.status() << "Adding checks for uninitialized local variables"
1460  << messaget::eom;
1462  }
1463 
1464  // check for maximum call stack size
1465  if(cmdline.isset("stack-depth"))
1466  {
1467  log.status() << "Adding check for maximum call stack size" << messaget::eom;
1468  stack_depth(
1469  goto_model,
1470  safe_string2size_t(cmdline.get_value("stack-depth")),
1472  }
1473 
1474  // ignore default/user-specified initialization of variables with static
1475  // lifetime
1476  if(cmdline.isset("nondet-static-exclude"))
1477  {
1478  log.status() << "Adding nondeterministic initialization "
1479  "of static/global variables except for "
1480  "the specified ones."
1481  << messaget::eom;
1482  std::set<std::string> to_exclude(
1483  cmdline.get_values("nondet-static-exclude").begin(),
1484  cmdline.get_values("nondet-static-exclude").end());
1485  nondet_static(goto_model, to_exclude);
1486  }
1487  else if(cmdline.isset("nondet-static"))
1488  {
1489  log.status() << "Adding nondeterministic initialization "
1490  "of static/global variables"
1491  << messaget::eom;
1493  }
1494 
1495  if(cmdline.isset("slice-global-inits"))
1496  {
1498 
1499  log.status() << "Slicing away initializations of unused global variables"
1500  << messaget::eom;
1502  }
1503 
1504  if(cmdline.isset("string-abstraction"))
1505  {
1508 
1509  log.status() << "String Abstraction" << messaget::eom;
1511  }
1512 
1513  // some analyses require function pointer removal and partial inlining
1514 
1515  if(cmdline.isset("remove-pointers") ||
1516  cmdline.isset("race-check") ||
1517  cmdline.isset("mm") ||
1518  cmdline.isset("isr") ||
1519  cmdline.isset("concurrency"))
1520  {
1522 
1523  log.status() << "Pointer Analysis" << messaget::eom;
1525  value_set_analysist value_set_analysis(ns);
1526  value_set_analysis(goto_model);
1527 
1528  if(cmdline.isset("remove-pointers"))
1529  {
1530  // removing pointers
1531  log.status() << "Removing Pointers" << messaget::eom;
1532  remove_pointers(goto_model, value_set_analysis, ui_message_handler);
1533  }
1534 
1535  if(cmdline.isset("race-check"))
1536  {
1537  log.status() << "Adding Race Checks" << messaget::eom;
1538  race_check(value_set_analysis, goto_model, ui_message_handler);
1539  }
1540 
1541  if(cmdline.isset("mm"))
1542  {
1543  std::string mm=cmdline.get_value("mm");
1544  memory_modelt model;
1545 
1546  // strategy of instrumentation
1547  instrumentation_strategyt inst_strategy;
1548  if(cmdline.isset("one-event-per-cycle"))
1549  inst_strategy=one_event_per_cycle;
1550  else if(cmdline.isset("minimum-interference"))
1551  inst_strategy=min_interference;
1552  else if(cmdline.isset("read-first"))
1553  inst_strategy=read_first;
1554  else if(cmdline.isset("write-first"))
1555  inst_strategy=write_first;
1556  else if(cmdline.isset("my-events"))
1557  inst_strategy=my_events;
1558  else
1559  /* default: instruments all unsafe pairs */
1560  inst_strategy=all;
1561 
1562  const unsigned max_var=
1563  cmdline.isset("max-var")?
1565  const unsigned max_po_trans=
1566  cmdline.isset("max-po-trans")?
1567  unsafe_string2unsigned(cmdline.get_value("max-po-trans")):0;
1568 
1569  if(mm=="tso")
1570  {
1571  log.status() << "Adding weak memory (TSO) Instrumentation"
1572  << messaget::eom;
1573  model=TSO;
1574  }
1575  else if(mm=="pso")
1576  {
1577  log.status() << "Adding weak memory (PSO) Instrumentation"
1578  << messaget::eom;
1579  model=PSO;
1580  }
1581  else if(mm=="rmo")
1582  {
1583  log.status() << "Adding weak memory (RMO) Instrumentation"
1584  << messaget::eom;
1585  model=RMO;
1586  }
1587  else if(mm=="power")
1588  {
1589  log.status() << "Adding weak memory (Power) Instrumentation"
1590  << messaget::eom;
1591  model=Power;
1592  }
1593  else
1594  {
1595  log.error() << "Unknown weak memory model '" << mm << "'"
1596  << messaget::eom;
1597  model=Unknown;
1598  }
1599 
1601 
1602  if(cmdline.isset("force-loop-duplication"))
1603  loops=all_loops;
1604  if(cmdline.isset("no-loop-duplication"))
1605  loops=no_loop;
1606 
1607  if(model!=Unknown)
1608  weak_memory(
1609  model,
1610  value_set_analysis,
1611  goto_model,
1612  cmdline.isset("scc"),
1613  inst_strategy,
1614  !cmdline.isset("cfg-kill"),
1615  cmdline.isset("no-dependencies"),
1616  loops,
1617  max_var,
1618  max_po_trans,
1619  !cmdline.isset("no-po-rendering"),
1620  cmdline.isset("render-cluster-file"),
1621  cmdline.isset("render-cluster-function"),
1622  cmdline.isset("cav11"),
1623  cmdline.isset("hide-internals"),
1625  cmdline.isset("ignore-arrays"));
1626  }
1627 
1628  // Interrupt handler
1629  if(cmdline.isset("isr"))
1630  {
1631  log.status() << "Instrumenting interrupt handler" << messaget::eom;
1632  interrupt(
1633  value_set_analysis,
1634  goto_model,
1635  cmdline.get_value("isr"),
1637  }
1638 
1639  // Memory-mapped I/O
1640  if(cmdline.isset("mmio"))
1641  {
1642  log.status() << "Instrumenting memory-mapped I/O" << messaget::eom;
1643  mmio(value_set_analysis, goto_model, ui_message_handler);
1644  }
1645 
1646  if(cmdline.isset("concurrency"))
1647  {
1648  log.status() << "Sequentializing concurrency" << messaget::eom;
1649  concurrency(value_set_analysis, goto_model);
1650  }
1651  }
1652 
1653  if(cmdline.isset("interval-analysis"))
1654  {
1655  log.status() << "Interval analysis" << messaget::eom;
1657  }
1658 
1659  if(cmdline.isset("havoc-loops"))
1660  {
1661  log.status() << "Havocking loops" << messaget::eom;
1663  }
1664 
1665  if(cmdline.isset("k-induction"))
1666  {
1667  bool base_case=cmdline.isset("base-case");
1668  bool step_case=cmdline.isset("step-case");
1669 
1670  if(step_case && base_case)
1671  throw "please specify only one of --step-case and --base-case";
1672  else if(!step_case && !base_case)
1673  throw "please specify one of --step-case and --base-case";
1674 
1675  unsigned k=unsafe_string2unsigned(cmdline.get_value("k-induction"));
1676 
1677  if(k==0)
1678  throw "please give k>=1";
1679 
1680  log.status() << "Instrumenting k-induction for k=" << k << ", "
1681  << (base_case ? "base case" : "step case") << messaget::eom;
1682 
1683  k_induction(goto_model, base_case, step_case, k);
1684  }
1685 
1686  if(cmdline.isset("function-enter"))
1687  {
1688  log.status() << "Function enter instrumentation" << messaget::eom;
1690  goto_model,
1691  cmdline.get_value("function-enter"));
1692  }
1693 
1694  if(cmdline.isset("function-exit"))
1695  {
1696  log.status() << "Function exit instrumentation" << messaget::eom;
1697  function_exit(
1698  goto_model,
1699  cmdline.get_value("function-exit"));
1700  }
1701 
1702  if(cmdline.isset("branch"))
1703  {
1704  log.status() << "Branch instrumentation" << messaget::eom;
1705  branch(
1706  goto_model,
1707  cmdline.get_value("branch"));
1708  }
1709 
1710  // add failed symbols
1712 
1713  // recalculate numbers, etc.
1715 
1716  // add loop ids
1718 
1719  // label the assertions
1721 
1722  nondet_volatile(goto_model, options);
1723 
1724  // reachability slice?
1725  if(cmdline.isset("reachability-slice"))
1726  {
1728 
1729  log.status() << "Performing a reachability slice" << messaget::eom;
1730 
1731  // reachability_slicer requires that the model has unique location numbers:
1733 
1734  if(cmdline.isset("property"))
1735  {
1738  }
1739  else
1741  }
1742 
1743  if(cmdline.isset("fp-reachability-slice"))
1744  {
1746 
1747  log.status() << "Performing a function pointer reachability slice"
1748  << messaget::eom;
1750  goto_model,
1751  cmdline.get_comma_separated_values("fp-reachability-slice"),
1753  }
1754 
1755  // full slice?
1756  if(cmdline.isset("full-slice"))
1757  {
1761  // full_slicer requires that the model has unique location numbers:
1763 
1764  log.warning() << "**** WARNING: Experimental option --full-slice, "
1765  << "analysis results may be unsound. See "
1766  << "https://github.com/diffblue/cbmc/issues/260"
1767  << messaget::eom;
1768  log.status() << "Performing a full slice" << messaget::eom;
1769  if(cmdline.isset("property"))
1772  else
1773  {
1775  }
1776  }
1777 
1778  // splice option
1779  if(cmdline.isset("splice-call"))
1780  {
1781  log.status() << "Performing call splicing" << messaget::eom;
1782  std::string callercallee=cmdline.get_value("splice-call");
1783  if(splice_call(
1785  callercallee,
1788  throw 0;
1789  }
1790 
1791  // aggressive slicer
1792  if(cmdline.isset("aggressive-slice"))
1793  {
1795 
1796  // reachability_slicer requires that the model has unique location numbers:
1798 
1799  log.status() << "Slicing away initializations of unused global variables"
1800  << messaget::eom;
1802 
1803  log.status() << "Performing an aggressive slice" << messaget::eom;
1804  aggressive_slicert aggressive_slicer(goto_model, ui_message_handler);
1805 
1806  if(cmdline.isset("aggressive-slice-call-depth"))
1807  aggressive_slicer.call_depth =
1808  safe_string2unsigned(cmdline.get_value("aggressive-slice-call-depth"));
1809 
1810  if(cmdline.isset("aggressive-slice-preserve-function"))
1811  aggressive_slicer.preserve_functions(
1812  cmdline.get_values("aggressive-slice-preserve-function"));
1813 
1814  if(cmdline.isset("property"))
1815  aggressive_slicer.user_specified_properties =
1816  cmdline.get_values("property");
1817 
1818  if(cmdline.isset("aggressive-slice-preserve-functions-containing"))
1819  aggressive_slicer.name_snippets =
1820  cmdline.get_values("aggressive-slice-preserve-functions-containing");
1821 
1822  aggressive_slicer.preserve_all_direct_paths =
1823  cmdline.isset("aggressive-slice-preserve-all-direct-paths");
1824 
1825  aggressive_slicer.doit();
1826 
1828 
1829  log.status() << "Performing a reachability slice" << messaget::eom;
1830  if(cmdline.isset("property"))
1831  {
1834  }
1835  else
1837  }
1838 
1839  if(cmdline.isset("ensure-one-backedge-per-target"))
1840  {
1841  log.status() << "Trying to force one backedge per target" << messaget::eom;
1843  }
1844 
1845  // recalculate numbers, etc.
1847 }
1848 
1851 {
1852  std::cout << '\n'
1853  << banner_string("Goto-Instrument", CBMC_VERSION) << '\n'
1854  << align_center_with_border("Copyright (C) 2008-2013") << '\n'
1855  << align_center_with_border("Daniel Kroening") << '\n'
1856  << align_center_with_border("kroening@kroening.com") << '\n';
1857 
1858  // clang-format off
1859  std::cout << help_formatter(
1860  "\n"
1861  "Usage: \tPurpose:\n"
1862  "\n"
1863  " {bgoto-instrument} [{y-?}] [{y-h}] [{y--help}] \t show this help\n"
1864  " {bgoto-instrument} {y--version} \t show version and exit\n"
1865  " {bgoto-instrument} [options] {uin} [{uout}] \t perform analysis or"
1866  " instrumentation\n"
1867  "\n"
1868  "Dump Source:\n"
1869  HELP_DUMP_C
1870  " {y--horn} \t print program as constrained horn clauses\n"
1871  "\n"
1872  "Diagnosis:\n"
1875  " {y--show-symbol-table} \t show loaded symbol table\n"
1876  " {y--list-symbols} \t list symbols with type information\n"
1879  " {y--show-locations} \t show all source locations\n"
1880  " {y--dot} \t generate CFG graph in DOT format\n"
1881  " {y--print-internal-representation} \t show verbose internal"
1882  " representation of the program\n"
1883  " {y--list-undefined-functions} \t list functions without body\n"
1884  " {y--list-calls-args} \t list all function calls with their arguments\n"
1885  " {y--call-graph} \t show graph of function calls\n"
1886  " {y--reachable-call-graph} \t show graph of function calls potentially"
1887  " reachable from main function\n"
1890  " {y--validate-goto-binary} \t check the well-formedness of the passed in"
1891  " goto binary and then exit\n"
1892  " {y--interpreter} \t do concrete execution\n"
1893  "\n"
1894  "Data-flow analyses:\n"
1895  " {y--show-struct-alignment} \t show struct members that might be"
1896  " concurrently accessed\n"
1897  " {y--show-threaded} \t show instructions that may be executed by more than"
1898  " one thread\n"
1899  " {y--show-local-safe-pointers} \t show pointer expressions that are"
1900  " trivially dominated by a not-null check\n"
1901  " {y--show-safe-dereferences} \t show pointer expressions that are"
1902  " trivially dominated by a not-null check *and* used as a dereference"
1903  " operand\n"
1904  " {y--show-value-sets} \t show points-to information (using value sets)\n"
1905  " {y--show-global-may-alias} \t show may-alias information over globals\n"
1906  " {y--show-local-bitvector-analysis} \t show procedure-local pointer"
1907  " analysis\n"
1908  " {y--escape-analysis} \t perform escape analysis\n"
1909  " {y--show-escape-analysis} \t show results of escape analysis\n"
1910  " {y--custom-bitvector-analysis} \t perform configurable bitvector"
1911  " analysis\n"
1912  " {y--show-custom-bitvector-analysis} \t show results of configurable"
1913  " bitvector analysis\n"
1914  " {y--interval-analysis} \t perform interval analysis\n"
1915  " {y--show-intervals} \t show results of interval analysis\n"
1916  " {y--show-uninitialized} \t show maybe-uninitialized variables\n"
1917  " {y--show-points-to} \t show points-to information\n"
1918  " {y--show-rw-set} \t show read-write sets\n"
1919  " {y--show-call-sequences} \t show function call sequences\n"
1920  " {y--show-reaching-definitions} \t show reaching definitions\n"
1921  " {y--show-dependence-graph} \t show program-dependence graph\n"
1922  " {y--show-sese-regions} \t show single-entry-single-exit regions\n"
1923  "\n"
1924  "Safety checks:\n"
1925  " {y--no-assertions} \t ignore user assertions\n"
1928  " {y--stack-depth} {un} \t add check that call stack size of non-inlined"
1929  " functions never exceeds {un}\n"
1930  " {y--race-check} \t add floating-point data race checks\n"
1931  "\n"
1932  "Semantic transformations:\n"
1934  " {y--isr} {ufunction} \t instruments an interrupt service routine\n"
1935  " {y--mmio} \t instruments memory-mapped I/O\n"
1936  " {y--nondet-static} \t add nondeterministic initialization of variables"
1937  " with static lifetime\n"
1938  " {y--nondet-static-exclude} {ue} \t same as nondet-static except for the"
1939  " variable {ue} (use multiple times if required)\n"
1940  " {y--nondet-static-matching} {ur} \t add nondeterministic initialization"
1941  " of variables with static lifetime matching regex {ur}\n"
1942  " {y--function-enter} {uf}, {y--function-exit} {uf}, {y--branch} {uf} \t"
1943  " instruments a call to {uf} at the beginning, the exit, or a branch point,"
1944  " respectively\n"
1945  " {y--splice-call} {ucaller},{ucallee} \t prepends a call to {ucallee} in"
1946  " the body of {ucaller}\n"
1947  " {y--check-call-sequence} {useq} \t instruments checks to assert that all"
1948  " call sequences match {useq}\n"
1949  " {y--undefined-function-is-assume-false} \t convert each call to an"
1950  " undefined function to assume(false)\n"
1955  " {y--add-library} \t add models of C library functions\n"
1957  " {y--model-argc-argv} {un} \t model up to {un} command line arguments\n"
1958  " {y--remove-function-body} {uf} remove the implementation of function {uf}"
1959  " (may be repeated)\n"
1962  "\n"
1963  "Semantics-preserving transformations:\n"
1964  " {y--ensure-one-backedge-per-target} \t transform loop bodies such that"
1965  " there is a single edge back to the loop head\n"
1966  " {y--drop-unused-functions} \t drop functions trivially unreachable from"
1967  " main function\n"
1969  " {y--constant-propagator} \t propagate constants and simplify"
1970  " expressions\n"
1971  " {y--inline} \t perform full inlining\n"
1972  " {y--partial-inline} \t perform partial inlining\n"
1973  " {y--function-inline} {ufunction} \t transitively inline all calls"
1974  " {ufunction} makes\n"
1975  " {y--no-caching} \t disable caching of intermediate results during"
1976  " transitive function inlining\n"
1977  " {y--log} {ufile} \t log in JSON format which code segments were inlined,"
1978  " use with {y--function-inline}\n"
1979  " {y--remove-function-pointers} \t replace function pointers by case"
1980  " statement over function calls\n"
1982  " {y--value-set-fi-fp-removal} \t build flow-insensitive value set and"
1983  " replace function pointers by a case statement over the possible"
1984  " assignments. If the set of possible assignments is empty the function"
1985  " pointer is removed using the standard remove-function-pointers pass.\n"
1986  "\n"
1987  "Loop information and transformations:\n"
1989  " {y--unwindset-file_<file>} \t read unwindset from file\n"
1990  " {y--partial-loops} \t permit paths with partial loops\n"
1991  " {y--unwinding-assertions} \t generate unwinding assertions"
1992  " (enabled by default)\n"
1993  " {y--no-unwinding-assertions} \t do not generate unwinding assertions\n"
1994  " {y--continue-as-loops} \t add loop for remaining iterations after"
1995  " unwound part\n"
1996  " {y--k-induction} {uk} \t check loops with k-induction\n"
1997  " {y--step-case} \t k-induction: do step-case\n"
1998  " {y--base-case} \t k-induction: do base-case\n"
1999  " {y--havoc-loops} \t over-approximate all loops\n"
2000  " {y--accelerate} \t add loop accelerators\n"
2001  " {y--z3} \t use Z3 when computing loop accelerators\n"
2002  " {y--skip-loops {uloop-ids} \t add gotos to skip selected loops during"
2003  " execution\n"
2004  " {y--show-lexical-loops} \t show single-entry-single-back-edge loops\n"
2005  " {y--show-natural-loops} \t show natural loop heads\n"
2006  "\n"
2007  "Memory model instrumentations:\n"
2009  "\n"
2010  "Slicing:\n"
2013  " {y--full-slice} \t slice away instructions that don't affect assertions\n"
2014  " {y--property} {uid} \t slice with respect to specific property only\n"
2015  " {y--slice-global-inits} \t slice away initializations of unused global"
2016  " variables\n"
2017  " {y--aggressive-slice} \t remove bodies of any functions not on the"
2018  " shortest path between the start function and the function containing the"
2019  " property/properties\n"
2020  " {y--aggressive-slice-call-depth} {un} \t used with aggressive-slice,"
2021  " preserves all functions within {un} function calls of the functions on"
2022  " the shortest path\n"
2023  " {y--aggressive-slice-preserve-function} {uf} \t force the aggressive"
2024  " slicer to preserve function {uf}\n"
2025  " {y--aggressive-slice-preserve-functions-containing} {uf} \t force the"
2026  " aggressive slicer to preserve all functions with names containing {uf}\n"
2027  " {y--aggressive-slice-preserve-all-direct-paths} \t force aggressive"
2028  " slicer to preserve all direct paths\n"
2029  "\n"
2030  "Code contracts:\n"
2031  HELP_DFCC
2039  "\n"
2040  "User-interface options:\n"
2041  HELP_FLUSH
2042  " {y--xml} \t output files in XML where supported\n"
2043  " {y--xml-ui} \t use XML-formatted output\n"
2044  " {y--json-ui} \t use JSON-formatted output\n"
2045  " {y--verbosity} {u#} \t verbosity level\n"
2047  "\n");
2048  // clang-format on
2049 }
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:1482
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:1563
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:1442
bool set(const cmdlinet &cmdline)
Definition: config.cpp:863
void set_from_symbol_table(const symbol_table_baset &)
Definition: config.cpp:1347
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:391
mstreamt & warning() const
Definition: message.h:396
mstreamt & status() const
Definition: message.h:406
message_handlert & get_message_handler()
Definition: message.h:183
@ M_STATUS
Definition: message.h:169
static eomt eom
Definition: message.h:289
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:51
#define HELP_DISABLE_SIDE_EFFECT_CHECK
Definition: contracts.h:38
#define FLAG_REPLACE_CALL
Definition: contracts.h:50
#define FLAG_ENFORCE_CONTRACT
Definition: contracts.h:55
#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:42
#define HELP_ENFORCE_CONTRACT
Definition: contracts.h:56
#define HELP_LOOP_CONTRACTS_FILE
Definition: contracts.h:46
#define FLAG_DISABLE_SIDE_EFFECT_CHECK
Definition: contracts.h:36
#define FLAG_LOOP_CONTRACTS_NO_UNWIND
Definition: contracts.h:41
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:62
#define FLAG_DFCC
Definition: dfcc.h:54
#define HELP_DFCC
Definition: dfcc.h:57
#define HELP_ENFORCE_CONTRACT_REC
Definition: dfcc.h:64
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 loop_contract_configt loop_contract_config, 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:113
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:154
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_modelt &goto_model, 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:223
std::list< std::string > defines
Definition: config.h:269
preprocessort preprocessor
Definition: config.h:267
This is unused by this implementation of guards, but can be used by other implementations of the same...
Definition: guard_expr.h:20
Loop contract configurations.
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.