cprover
Loading...
Searching...
No Matches
goto_instrument_parse_options.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Main Module
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
11
13
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/mm_io.h>
49
50#include <analyses/call_graph.h>
56#include <analyses/guard.h>
69#include <ansi-c/gcc_version.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 "nondet_static.h"
91#include "nondet_volatile.h"
92#include "points_to.h"
93#include "race_check.h"
94#include "remove_function.h"
95#include "rw_set.h"
96#include "show_locations.h"
97#include "skip_loops.h"
98#include "splice_call.h"
99#include "stack_depth.h"
101#include "undefined_functions.h"
102#include "unwind.h"
104
105#include <fstream> // IWYU pragma: keep
106#include <iostream>
107#include <memory>
108#include <sstream>
109
111
114{
115 if(cmdline.isset("version"))
116 {
117 std::cout << CBMC_VERSION << '\n';
119 }
120
121 if(cmdline.args.size()!=1 && cmdline.args.size()!=2)
122 {
123 help();
125 }
126
128 cmdline.get_value("verbosity"), messaget::M_STATUS, ui_message_handler);
129
130 {
132
134
135 // configure gcc, if required -- get_goto_program will have set the config
136 if(config.ansi_c.preprocessor == configt::ansi_ct::preprocessort::GCC)
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 {
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 {
172 goto_model.validate();
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;
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"),
197 }
198
199 if(unwindset_given)
200 {
201 unwindset.parse_unwindset(
202 cmdline.get_comma_separated_values("unwindset"),
205 }
206
207 bool continue_as_loops=cmdline.isset("continue-as-loops");
208 bool partial_loops = cmdline.isset("partial-loops");
209 bool unwinding_assertions = cmdline.isset("unwinding-assertions") ||
210 (!continue_as_loops && !partial_loops &&
211 !cmdline.isset("no-unwinding-assertions"));
212 if(continue_as_loops)
213 {
214 if(unwinding_assertions)
215 {
216 throw "unwinding assertions cannot be used with "
217 "--continue-as-loops";
218 }
219 else if(partial_loops)
220 throw "partial loops cannot be used with --continue-as-loops";
221 }
222
223 goto_unwindt::unwind_strategyt unwind_strategy=
225
226 if(unwinding_assertions)
227 {
228 if(partial_loops)
230 else
232 }
233 else if(partial_loops)
234 {
236 }
237 else if(continue_as_loops)
238 {
240 }
241
242 goto_unwindt goto_unwind;
243 goto_unwind(goto_model, unwindset, unwind_strategy);
244
245 if(cmdline.isset("log"))
246 {
247 std::string filename = cmdline.value_opt("log").value_or("-");
248 bool have_file = filename != "-";
249
250 jsont result=goto_unwind.output_log_json();
251
252 if(have_file)
253 {
254 std::ofstream of(widen_if_needed(filename));
255
256 if(!of)
257 throw "failed to open file "+filename;
258
259 of << result;
260 of.close();
261 }
262 else
263 {
264 std::cout << result << '\n';
265 }
266 }
267
268 // goto_unwind holds references to instructions, only do remove_skip
269 // after having generated the log above
271 }
272 }
273
274 if(cmdline.isset("show-threaded"))
275 {
276 namespacet ns(goto_model.symbol_table);
277
278 is_threadedt is_threaded(goto_model);
279
280 for(const auto &gf_entry : goto_model.goto_functions.function_map)
281 {
282 std::cout << "////\n";
283 std::cout << "//// Function: " << gf_entry.first << '\n';
284 std::cout << "////\n\n";
285
286 const goto_programt &goto_program = gf_entry.second.body;
287
288 forall_goto_program_instructions(i_it, goto_program)
289 {
290 i_it->output(std::cout);
291 std::cout << "Is threaded: " << (is_threaded(i_it)?"True":"False")
292 << "\n\n";
293 }
294 }
295
297 }
298
299 if(cmdline.isset("insert-final-assert-false"))
300 {
301 log.status() << "Inserting final assert false" << messaget::eom;
302 bool fail = insert_final_assert_false(
304 cmdline.get_value("insert-final-assert-false"),
306 if(fail)
307 {
309 }
310 // otherwise, fall-through to write new binary
311 }
312
313 if(cmdline.isset("show-value-sets"))
314 {
316
317 // recalculate numbers, etc.
318 goto_model.goto_functions.update();
319
320 log.status() << "Pointer Analysis" << messaget::eom;
321 namespacet ns(goto_model.symbol_table);
322 value_set_analysist value_set_analysis(ns);
323 value_set_analysis(goto_model);
325 ui_message_handler.get_ui(), goto_model, value_set_analysis);
327 }
328
329 if(cmdline.isset("show-global-may-alias"))
330 {
334
335 // recalculate numbers, etc.
336 goto_model.goto_functions.update();
337
338 global_may_alias_analysist global_may_alias_analysis;
339 global_may_alias_analysis(goto_model);
340 global_may_alias_analysis.output(goto_model, std::cout);
341
343 }
344
345 if(cmdline.isset("show-local-bitvector-analysis"))
346 {
349
350 // recalculate numbers, etc.
351 goto_model.goto_functions.update();
352
353 namespacet ns(goto_model.symbol_table);
354
355 for(const auto &gf_entry : goto_model.goto_functions.function_map)
356 {
357 local_bitvector_analysist local_bitvector_analysis(gf_entry.second, ns);
358 std::cout << ">>>>\n";
359 std::cout << ">>>> " << gf_entry.first << '\n';
360 std::cout << ">>>>\n";
361 local_bitvector_analysis.output(std::cout, gf_entry.second, ns);
362 std::cout << '\n';
363 }
364
366 }
367
368 if(cmdline.isset("show-local-safe-pointers") ||
369 cmdline.isset("show-safe-dereferences"))
370 {
371 // Ensure location numbering is unique:
372 goto_model.goto_functions.update();
373
374 namespacet ns(goto_model.symbol_table);
375
376 for(const auto &gf_entry : goto_model.goto_functions.function_map)
377 {
378 local_safe_pointerst local_safe_pointers;
379 local_safe_pointers(gf_entry.second.body);
380 std::cout << ">>>>\n";
381 std::cout << ">>>> " << gf_entry.first << '\n';
382 std::cout << ">>>>\n";
383 if(cmdline.isset("show-local-safe-pointers"))
384 local_safe_pointers.output(std::cout, gf_entry.second.body, ns);
385 else
386 {
387 local_safe_pointers.output_safe_dereferences(
388 std::cout, gf_entry.second.body, ns);
389 }
390 std::cout << '\n';
391 }
392
394 }
395
396 if(cmdline.isset("show-sese-regions"))
397 {
398 // Ensure location numbering is unique:
399 goto_model.goto_functions.update();
400
401 namespacet ns(goto_model.symbol_table);
402
403 for(const auto &gf_entry : goto_model.goto_functions.function_map)
404 {
405 sese_region_analysist sese_region_analysis;
406 sese_region_analysis(gf_entry.second.body);
407 std::cout << ">>>>\n";
408 std::cout << ">>>> " << gf_entry.first << '\n';
409 std::cout << ">>>>\n";
410 sese_region_analysis.output(std::cout, gf_entry.second.body, ns);
411 std::cout << '\n';
412 }
413
415 }
416
417 if(cmdline.isset("show-custom-bitvector-analysis"))
418 {
422
424
425 if(!cmdline.isset("inline"))
426 {
429 }
430
431 // recalculate numbers, etc.
432 goto_model.goto_functions.update();
433
434 custom_bitvector_analysist custom_bitvector_analysis;
435 custom_bitvector_analysis(goto_model);
436 custom_bitvector_analysis.output(goto_model, std::cout);
437
439 }
440
441 if(cmdline.isset("show-escape-analysis"))
442 {
446
447 // recalculate numbers, etc.
448 goto_model.goto_functions.update();
449
450 escape_analysist escape_analysis;
451 escape_analysis(goto_model);
452 escape_analysis.output(goto_model, std::cout);
453
455 }
456
457 if(cmdline.isset("custom-bitvector-analysis"))
458 {
462
464
465 if(!cmdline.isset("inline"))
466 {
469 }
470
471 // recalculate numbers, etc.
472 goto_model.goto_functions.update();
473
474 namespacet ns(goto_model.symbol_table);
475
476 custom_bitvector_analysist custom_bitvector_analysis;
477 custom_bitvector_analysis(goto_model);
478 custom_bitvector_analysis.check(
480 cmdline.isset("xml-ui"),
481 std::cout);
482
484 }
485
486 if(cmdline.isset("show-points-to"))
487 {
489
490 // recalculate numbers, etc.
491 goto_model.goto_functions.update();
492
493 namespacet ns(goto_model.symbol_table);
494
495 log.status() << "Pointer Analysis" << messaget::eom;
496 points_tot points_to;
497 points_to(goto_model);
498 points_to.output(std::cout);
500 }
501
502 if(cmdline.isset("show-intervals"))
503 {
505
506 // recalculate numbers, etc.
507 goto_model.goto_functions.update();
508
509 log.status() << "Interval Analysis" << messaget::eom;
510 namespacet ns(goto_model.symbol_table);
513 interval_analysis.output(goto_model, std::cout);
515 }
516
517 if(cmdline.isset("show-call-sequences"))
518 {
522 }
523
524 if(cmdline.isset("check-call-sequence"))
525 {
529 }
530
531 if(cmdline.isset("list-calls-args"))
532 {
534
536
538 }
539
540 if(cmdline.isset("show-rw-set"))
541 {
542 namespacet ns(goto_model.symbol_table);
543
544 if(!cmdline.isset("inline"))
545 {
547
548 // recalculate numbers, etc.
549 goto_model.goto_functions.update();
550 }
551
552 log.status() << "Pointer Analysis" << messaget::eom;
553 value_set_analysist value_set_analysis(ns);
554 value_set_analysis(goto_model);
555
556 const symbolt &symbol=ns.lookup(ID_main);
557 symbol_exprt main(symbol.name, symbol.type);
558
559 std::cout << rw_set_functiont(
560 value_set_analysis, goto_model, main, ui_message_handler);
562 }
563
564 if(cmdline.isset("show-symbol-table"))
565 {
568 }
569
570 if(cmdline.isset("show-reaching-definitions"))
571 {
574
575 const namespacet ns(goto_model.symbol_table);
577 rd_analysis(goto_model);
578 rd_analysis.output(goto_model, std::cout);
579
581 }
582
583 if(cmdline.isset("show-dependence-graph"))
584 {
587
588 const namespacet ns(goto_model.symbol_table);
589 dependence_grapht dependence_graph(ns, ui_message_handler);
590 dependence_graph(goto_model);
591 dependence_graph.output(goto_model, std::cout);
592 dependence_graph.output_dot(std::cout);
593
595 }
596
597 if(cmdline.isset("count-eloc"))
598 {
601 }
602
603 if(cmdline.isset("list-eloc"))
604 {
607 }
608
609 if(cmdline.isset("print-path-lengths"))
610 {
613 }
614
615 if(cmdline.isset("print-global-state-size"))
616 {
619 }
620
621 if(cmdline.isset("list-symbols"))
622 {
625 }
626
627 if(cmdline.isset("show-uninitialized"))
628 {
629 show_uninitialized(goto_model, std::cout);
631 }
632
633 if(cmdline.isset("interpreter"))
634 {
637
638 log.status() << "Starting interpreter" << messaget::eom;
641 }
642
643 if(cmdline.isset("show-claims") ||
644 cmdline.isset("show-properties"))
645 {
646 const namespacet ns(goto_model.symbol_table);
649 }
650
651 if(cmdline.isset("document-claims-html") ||
652 cmdline.isset("document-properties-html"))
653 {
656 }
657
658 if(cmdline.isset("document-claims-latex") ||
659 cmdline.isset("document-properties-latex"))
660 {
663 }
664
665 if(cmdline.isset("show-loops"))
666 {
669 }
670
671 if(cmdline.isset("show-natural-loops"))
672 {
673 show_natural_loops(goto_model, std::cout);
675 }
676
677 if(cmdline.isset("show-lexical-loops"))
678 {
679 show_lexical_loops(goto_model, std::cout);
681 }
682
683 if(cmdline.isset("print-internal-representation"))
684 {
685 for(auto const &pair : goto_model.goto_functions.function_map)
686 for(auto const &ins : pair.second.body.instructions)
687 {
688 if(ins.code().is_not_nil())
689 log.status() << ins.code().pretty() << messaget::eom;
690 if(ins.has_condition())
691 {
692 log.status() << "[guard] " << ins.condition().pretty()
693 << messaget::eom;
694 }
695 }
697 }
698
699 if(
700 cmdline.isset("show-goto-functions") ||
701 cmdline.isset("list-goto-functions"))
702 {
704 goto_model, ui_message_handler, cmdline.isset("list-goto-functions"));
706 }
707
708 if(cmdline.isset("list-undefined-functions"))
709 {
712 }
713
714 // experimental: print structs
715 if(cmdline.isset("show-struct-alignment"))
716 {
717 print_struct_alignment_problems(goto_model.symbol_table, std::cout);
719 }
720
721 if(cmdline.isset("show-locations"))
722 {
725 }
726
727 if(
728 cmdline.isset("dump-c") || cmdline.isset("dump-cpp") ||
729 cmdline.isset("dump-c-type-header"))
730 {
731 const bool is_cpp=cmdline.isset("dump-cpp");
732 const bool is_header = cmdline.isset("dump-c-type-header");
733 const bool h_libc=!cmdline.isset("no-system-headers");
734 const bool h_all=cmdline.isset("use-all-headers");
735 const bool harness=cmdline.isset("harness");
736 namespacet ns(goto_model.symbol_table);
737
738 // restore RETURN instructions in case remove_returns had been
739 // applied
741
742 // dump_c (actually goto_program2code) requires valid instruction
743 // location numbers:
744 goto_model.goto_functions.update();
745
746 if(cmdline.args.size()==2)
747 {
748 std::ofstream out(widen_if_needed(cmdline.args[1]));
749
750 if(!out)
751 {
752 log.error() << "failed to write to '" << cmdline.args[1] << "'";
754 }
755 if(is_header)
756 {
758 goto_model.goto_functions,
759 h_libc,
760 h_all,
761 harness,
762 ns,
763 cmdline.get_value("dump-c-type-header"),
764 out);
765 }
766 else
767 {
768 (is_cpp ? dump_cpp : dump_c)(
769 goto_model.goto_functions, h_libc, h_all, harness, ns, out);
770 }
771 }
772 else
773 {
774 if(is_header)
775 {
777 goto_model.goto_functions,
778 h_libc,
779 h_all,
780 harness,
781 ns,
782 cmdline.get_value("dump-c-type-header"),
783 std::cout);
784 }
785 else
786 {
787 (is_cpp ? dump_cpp : dump_c)(
788 goto_model.goto_functions, h_libc, h_all, harness, ns, std::cout);
789 }
790 }
791
793 }
794
795 if(cmdline.isset("call-graph"))
796 {
798 call_grapht call_graph(goto_model);
799
800 if(cmdline.isset("xml"))
801 call_graph.output_xml(std::cout);
802 else if(cmdline.isset("dot"))
803 call_graph.output_dot(std::cout);
804 else
805 call_graph.output(std::cout);
806
808 }
809
810 if(cmdline.isset("reachable-call-graph"))
811 {
813 call_grapht call_graph =
816 if(cmdline.isset("xml"))
817 call_graph.output_xml(std::cout);
818 else if(cmdline.isset("dot"))
819 call_graph.output_dot(std::cout);
820 else
821 call_graph.output(std::cout);
822
823 return 0;
824 }
825
826 if(cmdline.isset("show-class-hierarchy"))
827 {
828 class_hierarchyt hierarchy;
829 hierarchy(goto_model.symbol_table);
830 if(cmdline.isset("dot"))
831 hierarchy.output_dot(std::cout);
832 else
834
836 }
837
838 if(cmdline.isset("dot"))
839 {
840 namespacet ns(goto_model.symbol_table);
841
842 if(cmdline.args.size()==2)
843 {
844 std::ofstream out(widen_if_needed(cmdline.args[1]));
845
846 if(!out)
847 {
848 log.error() << "failed to write to " << cmdline.args[1] << "'";
850 }
851
852 dot(goto_model, out);
853 }
854 else
855 dot(goto_model, std::cout);
856
858 }
859
860 if(cmdline.isset("accelerate"))
861 {
863
864 namespacet ns(goto_model.symbol_table);
865
866 log.status() << "Performing full inlining" << messaget::eom;
868
869 log.status() << "Removing calls to functions without a body"
870 << messaget::eom;
871 remove_calls_no_bodyt remove_calls_no_body;
872 remove_calls_no_body(goto_model.goto_functions, ui_message_handler);
873
874 log.status() << "Accelerating" << messaget::eom;
875 guard_managert guard_manager;
877 goto_model, ui_message_handler, cmdline.isset("z3"), guard_manager);
879 }
880
881 if(cmdline.isset("horn"))
882 {
883 log.status() << "Horn-clause encoding" << messaget::eom;
884 namespacet ns(goto_model.symbol_table);
885
886 if(cmdline.args.size()==2)
887 {
888 std::ofstream out(widen_if_needed(cmdline.args[1]));
889
890 if(!out)
891 {
892 log.error() << "Failed to open output file " << cmdline.args[1]
893 << messaget::eom;
895 }
896
898 }
899 else
900 horn_encoding(goto_model, std::cout);
901
903 }
904
905 if(cmdline.isset("drop-unused-functions"))
906 {
909
910 log.status() << "Removing unused functions" << messaget::eom;
912 }
913
914 if(cmdline.isset("undefined-function-is-assume-false"))
915 {
918 }
919
920 // write new binary?
921 if(cmdline.args.size()==2)
922 {
923 log.status() << "Writing GOTO program to '" << cmdline.args[1] << "'"
924 << messaget::eom;
925
928 else
930 }
931 else if(cmdline.args.size() < 2)
932 {
934 "Invalid number of positional arguments passed",
935 "[in] [out]",
936 "goto-instrument needs one input and one output file, aside from other "
937 "flags");
938 }
939
940 help();
942 }
943// NOLINTNEXTLINE(readability/fn_size)
944}
945
947 bool force)
948{
950 return;
951
953
954 log.status() << "Function Pointer Removal" << messaget::eom;
956 log.status() << "Virtual function removal" << messaget::eom;
958 log.status() << "Cleaning inline assembler statements" << messaget::eom;
959 remove_asm(goto_model, log.get_message_handler());
960}
961
966{
967 // Don't bother if we've already done a full function pointer
968 // removal.
970 {
971 return;
972 }
973
974 log.status() << "Removing const function pointers only" << messaget::eom;
978 true); // abort if we can't resolve via const pointers
979}
980
982{
984 return;
985
987
988 if(!cmdline.isset("inline"))
989 {
990 log.status() << "Partial Inlining" << messaget::eom;
992 }
993}
994
996{
998 return;
999
1001
1002 log.status() << "Removing returns" << messaget::eom;
1004}
1005
1007{
1008 log.status() << "Reading GOTO program from '" << cmdline.args[0] << "'"
1009 << messaget::eom;
1010
1011 config.set(cmdline);
1012
1013 auto result = read_goto_binary(cmdline.args[0], ui_message_handler);
1014
1015 if(!result.has_value())
1016 throw 0;
1017
1018 goto_model = std::move(result.value());
1019
1020 config.set_from_symbol_table(goto_model.symbol_table);
1021}
1022
1024{
1025 optionst options;
1026
1028
1029 // disable simplify when adding various checks?
1030 if(cmdline.isset("no-simplify"))
1031 options.set_option("simplify", false);
1032 else
1033 options.set_option("simplify", true);
1034
1035 // all checks supported by goto_check
1037
1038 // initialize argv with valid pointers
1039 if(cmdline.isset("model-argc-argv"))
1040 {
1041 unsigned max_argc=
1042 safe_string2unsigned(cmdline.get_value("model-argc-argv"));
1043 std::list<std::string> argv;
1044 argv.resize(max_argc);
1045
1046 log.status() << "Adding up to " << max_argc << " command line arguments"
1047 << messaget::eom;
1048
1049 if(model_argc_argv(
1050 goto_model, argv, true /*model_argv*/, ui_message_handler))
1051 throw 0;
1052 }
1053
1054 if(cmdline.isset("add-cmd-line-arg"))
1055 {
1056 const std::list<std::string> &argv = cmdline.get_values("add-cmd-line-arg");
1057 unsigned argc = 0;
1058
1059 std::stringstream ss;
1060 ss << "[";
1061 std::string sep = "";
1062 for(auto const &arg : argv)
1063 {
1064 ss << sep << "\"" << arg << "\"";
1065 argc++;
1066 sep = ", ";
1067 }
1068 ss << "]";
1069
1070 log.status() << "Adding " << argc << " arguments: " << ss.str()
1071 << messaget::eom;
1072
1073 if(model_argc_argv(
1074 goto_model, argv, false /*model_argv*/, ui_message_handler))
1075 throw 0;
1076 }
1077
1078 if(cmdline.isset("remove-function-body"))
1079 {
1081 goto_model,
1082 cmdline.get_values("remove-function-body"),
1084 }
1085
1086 if(cmdline.isset("remove-function-body-regex"))
1087 {
1089 goto_model,
1090 cmdline.get_value("remove-function-body-regex"),
1092 }
1093
1094 // we add the library in some cases, as some analyses benefit
1095
1096 if(
1097 cmdline.isset("add-library") || cmdline.isset("mm") ||
1098 cmdline.isset("reachability-slice") ||
1099 cmdline.isset("reachability-slice-fb") ||
1100 cmdline.isset("fp-reachability-slice"))
1101 {
1102 if(cmdline.isset("show-custom-bitvector-analysis") ||
1103 cmdline.isset("custom-bitvector-analysis"))
1104 {
1105 config.ansi_c.defines.push_back(
1106 std::string(CPROVER_PREFIX) + "CUSTOM_BITVECTOR_ANALYSIS");
1107 }
1108
1109 // remove inline assembler as that may yield further library function calls
1110 // that need to be resolved
1112
1113 // add the library
1114 log.status() << "Adding CPROVER library (" << config.ansi_c.arch << ")"
1115 << messaget::eom;
1119 // library functions may introduce inline assembler
1120 while(has_asm(goto_model))
1121 {
1127 }
1128 }
1129
1130 {
1132
1133 if(
1137 {
1139
1141 }
1142 }
1143
1144 // skip over selected loops
1145 if(cmdline.isset("skip-loops"))
1146 {
1147 log.status() << "Adding gotos to skip loops" << messaget::eom;
1148 if(skip_loops(
1149 goto_model, cmdline.get_value("skip-loops"), ui_message_handler))
1150 {
1151 throw 0;
1152 }
1153 }
1154
1155 // now do full inlining, if requested
1156 if(cmdline.isset("inline"))
1157 {
1159
1160 if(cmdline.isset("show-custom-bitvector-analysis") ||
1161 cmdline.isset("custom-bitvector-analysis"))
1162 {
1166 }
1167
1168 log.status() << "Performing full inlining" << messaget::eom;
1170 }
1171
1172 if(cmdline.isset("show-custom-bitvector-analysis") ||
1173 cmdline.isset("custom-bitvector-analysis"))
1174 {
1175 log.status() << "Propagating Constants" << messaget::eom;
1176 constant_propagator_ait constant_propagator_ai(goto_model);
1178 }
1179
1180 if(cmdline.isset("escape-analysis"))
1181 {
1185
1186 // recalculate numbers, etc.
1187 goto_model.goto_functions.update();
1188
1189 log.status() << "Escape Analysis" << messaget::eom;
1190 escape_analysist escape_analysis;
1191 escape_analysis(goto_model);
1192 escape_analysis.instrument(goto_model);
1193
1194 // inline added functions, they are often small
1196
1197 // recalculate numbers, etc.
1198 goto_model.goto_functions.update();
1199 }
1200
1201 if(cmdline.isset("loop-contracts-file"))
1202 {
1203 const auto file_name = cmdline.get_value("loop-contracts-file");
1204 contracts_wranglert contracts_wrangler(
1205 goto_model, file_name, ui_message_handler);
1206 }
1207
1208 // Initialize loop contract config from cmdline.
1209 loop_contract_configt loop_contract_config = {
1213
1214 if(
1217 {
1218 // After instrumentation, all annotated loops will be transformed to
1219 // loops execute exactly once. CBMC by default unwinds transformed loops
1220 // by twice.
1221 // Users may want to disable the default unwinding to avoid duplicate
1222 // assertions.
1223 log.warning() << "**** WARNING: transformed loops will not be unwound "
1224 << "after applying loop contracts. Note that transformed "
1225 << "loops require at least unwinding bounds 2 to pass "
1226 << "the unwinding assertions." << messaget::eom;
1227 }
1228
1229 bool use_dfcc = cmdline.isset(FLAG_DFCC);
1230 if(use_dfcc)
1231 {
1232 if(cmdline.get_values(FLAG_DFCC).size() != 1)
1233 {
1235 "Redundant options detected",
1236 "--" FLAG_DFCC,
1237 "Use a single " FLAG_DFCC " option");
1238 }
1239
1241 log.status() << "Trying to force one backedge per target" << messaget::eom;
1243
1244 const irep_idt harness_id(cmdline.get_value(FLAG_DFCC));
1245
1246 std::set<irep_idt> to_replace(
1247 cmdline.get_values(FLAG_REPLACE_CALL).begin(),
1248 cmdline.get_values(FLAG_REPLACE_CALL).end());
1249
1250 if(
1251 !cmdline.get_values(FLAG_ENFORCE_CONTRACT).empty() &&
1252 !cmdline.get_values(FLAG_ENFORCE_CONTRACT_REC).empty())
1253 {
1255 "Mutually exclusive options detected",
1257 "Use either --" FLAG_ENFORCE_CONTRACT
1258 " or --" FLAG_ENFORCE_CONTRACT_REC);
1259 }
1260
1261 auto &to_enforce = !cmdline.get_values(FLAG_ENFORCE_CONTRACT_REC).empty()
1263 : cmdline.get_values(FLAG_ENFORCE_CONTRACT);
1264
1265 bool allow_recursive_calls =
1266 !cmdline.get_values(FLAG_ENFORCE_CONTRACT_REC).empty();
1267
1268 std::set<std::string> to_exclude_from_nondet_static(
1269 cmdline.get_values("nondet-static-exclude").begin(),
1270 cmdline.get_values("nondet-static-exclude").end());
1271
1272 dfcc(
1273 options,
1274 goto_model,
1275 harness_id,
1276 to_enforce.empty() ? std::optional<irep_idt>{}
1277 : std::optional<irep_idt>{to_enforce.front()},
1278 allow_recursive_calls,
1279 to_replace,
1280 loop_contract_config,
1281 to_exclude_from_nondet_static,
1282 log.get_message_handler());
1283 }
1284 else if((cmdline.isset(FLAG_LOOP_CONTRACTS) ||
1285 cmdline.isset(FLAG_REPLACE_CALL) ||
1287 {
1289 log.status() << "Trying to force one backedge per target" << messaget::eom;
1291 code_contractst contracts(goto_model, log, loop_contract_config);
1292
1293 std::set<std::string> to_replace(
1294 cmdline.get_values(FLAG_REPLACE_CALL).begin(),
1295 cmdline.get_values(FLAG_REPLACE_CALL).end());
1296
1297 std::set<std::string> to_enforce(
1298 cmdline.get_values(FLAG_ENFORCE_CONTRACT).begin(),
1299 cmdline.get_values(FLAG_ENFORCE_CONTRACT).end());
1300
1301 std::set<std::string> to_exclude_from_nondet_static(
1302 cmdline.get_values("nondet-static-exclude").begin(),
1303 cmdline.get_values("nondet-static-exclude").end());
1304
1305 // It's important to keep the order of contracts instrumentation, i.e.,
1306 // first replacement then enforcement. We rely on contract replacement
1307 // and inlining of sub-function calls to properly annotate all
1308 // assignments.
1309 contracts.replace_calls(to_replace);
1310 contracts.enforce_contracts(to_enforce, to_exclude_from_nondet_static);
1311
1312 if(cmdline.isset(FLAG_LOOP_CONTRACTS))
1313 {
1314 contracts.apply_loop_contracts(to_exclude_from_nondet_static);
1315 }
1316 }
1317
1318 if(cmdline.isset("value-set-fi-fp-removal"))
1319 {
1322 }
1323
1324 // replace function pointers, if explicitly requested
1325 if(cmdline.isset("remove-function-pointers"))
1326 {
1328 }
1329 else if(cmdline.isset("remove-const-function-pointers"))
1330 {
1332 }
1333
1334 if(cmdline.isset("replace-calls"))
1335 {
1337
1338 replace_callst replace_calls;
1339 replace_calls(goto_model, cmdline.get_values("replace-calls"));
1340 }
1341
1342 if(cmdline.isset("function-inline"))
1343 {
1344 std::string function=cmdline.get_value("function-inline");
1345 PRECONDITION(!function.empty());
1346
1347 bool caching=!cmdline.isset("no-caching");
1348
1350
1351 log.status() << "Inlining calls of function '" << function << "'"
1352 << messaget::eom;
1353
1354 if(!cmdline.isset("log"))
1355 {
1357 goto_model, function, ui_message_handler, true, caching);
1358 }
1359 else
1360 {
1361 std::string filename = cmdline.value_opt("log").value_or("-");
1362 bool have_file = filename != "-";
1363
1365 goto_model, function, ui_message_handler, true, caching);
1366
1367 if(have_file)
1368 {
1369 std::ofstream of(widen_if_needed(filename));
1370
1371 if(!of)
1372 throw "failed to open file "+filename;
1373
1374 of << result;
1375 of.close();
1376 }
1377 else
1378 {
1379 std::cout << result << '\n';
1380 }
1381 }
1382
1383 goto_model.goto_functions.update();
1384 goto_model.goto_functions.compute_loop_numbers();
1385 }
1386
1387 if(cmdline.isset("partial-inline"))
1388 {
1390
1391 log.status() << "Partial inlining" << messaget::eom;
1393
1394 goto_model.goto_functions.update();
1395 goto_model.goto_functions.compute_loop_numbers();
1396 }
1397
1398 if(cmdline.isset("remove-calls-no-body"))
1399 {
1400 log.status() << "Removing calls to functions without a body"
1401 << messaget::eom;
1402
1403 remove_calls_no_bodyt remove_calls_no_body;
1404 remove_calls_no_body(goto_model.goto_functions, ui_message_handler);
1405
1406 goto_model.goto_functions.update();
1407 goto_model.goto_functions.compute_loop_numbers();
1408 }
1409
1410 if(cmdline.isset("constant-propagator"))
1411 {
1414
1415 log.status() << "Propagating Constants" << messaget::eom;
1416 log.warning() << "**** WARNING: Constant propagation as performed by "
1417 "goto-instrument is not expected to be sound. Do not use "
1418 "--constant-propagator if soundness is important for your "
1419 "use case."
1420 << messaget::eom;
1421
1422 constant_propagator_ait constant_propagator_ai(goto_model);
1424 }
1425
1426 if(cmdline.isset("generate-function-body"))
1427 {
1428 optionst c_object_factory_options;
1429 parse_c_object_factory_options(cmdline, c_object_factory_options);
1430 c_object_factory_parameterst object_factory_parameters(
1431 c_object_factory_options);
1432
1433 auto generate_implementation = generate_function_bodies_factory(
1434 cmdline.get_value("generate-function-body-options"),
1435 object_factory_parameters,
1436 goto_model.symbol_table,
1439 std::regex(cmdline.get_value("generate-function-body")),
1440 *generate_implementation,
1441 goto_model,
1443 false);
1444 }
1445
1446 if(cmdline.isset("generate-havocing-body"))
1447 {
1448 optionst c_object_factory_options;
1449 parse_c_object_factory_options(cmdline, c_object_factory_options);
1450 c_object_factory_parameterst object_factory_parameters(
1451 c_object_factory_options);
1452
1453 auto options_split =
1454 split_string(cmdline.get_value("generate-havocing-body"), ',');
1455 if(options_split.size() < 2)
1457 "not enough arguments for this option", "--generate-havocing-body"};
1458
1459 if(options_split.size() == 2)
1460 {
1461 auto generate_implementation = generate_function_bodies_factory(
1462 std::string{"havoc,"} + options_split.back(),
1463 object_factory_parameters,
1464 goto_model.symbol_table,
1467 std::regex(options_split[0]),
1468 *generate_implementation,
1469 goto_model,
1471 false);
1472 }
1473 else
1474 {
1475 CHECK_RETURN(options_split.size() % 2 == 1);
1476 for(size_t i = 1; i + 1 < options_split.size(); i += 2)
1477 {
1478 auto generate_implementation = generate_function_bodies_factory(
1479 std::string{"havoc,"} + options_split[i + 1],
1480 object_factory_parameters,
1481 goto_model.symbol_table,
1484 options_split[0],
1485 options_split[i],
1486 *generate_implementation,
1487 goto_model,
1489 }
1490 }
1491 }
1492
1493 // add generic checks, if needed
1496
1497 // check for uninitalized local variables
1498 if(cmdline.isset("uninitialized-check"))
1499 {
1500 log.status() << "Adding checks for uninitialized local variables"
1501 << messaget::eom;
1503 }
1504
1505 // check for maximum call stack size
1506 if(cmdline.isset("stack-depth"))
1507 {
1508 log.status() << "Adding check for maximum call stack size" << messaget::eom;
1510 goto_model,
1511 safe_string2size_t(cmdline.get_value("stack-depth")),
1513 }
1514
1515 // ignore default/user-specified initialization of variables with static
1516 // lifetime
1517 if(cmdline.isset("nondet-static-exclude"))
1518 {
1519 log.status() << "Adding nondeterministic initialization "
1520 "of static/global variables except for "
1521 "the specified ones."
1522 << messaget::eom;
1523 std::set<std::string> to_exclude(
1524 cmdline.get_values("nondet-static-exclude").begin(),
1525 cmdline.get_values("nondet-static-exclude").end());
1526 nondet_static(goto_model, to_exclude);
1527 }
1528 else if(cmdline.isset("nondet-static"))
1529 {
1530 log.status() << "Adding nondeterministic initialization "
1531 "of static/global variables"
1532 << messaget::eom;
1534 }
1535
1536 if(cmdline.isset("slice-global-inits"))
1537 {
1539
1540 log.status() << "Slicing away initializations of unused global variables"
1541 << messaget::eom;
1543 }
1544
1545 if(cmdline.isset("string-abstraction"))
1546 {
1549
1550 log.status() << "String Abstraction" << messaget::eom;
1552 }
1553
1554 // some analyses require function pointer removal and partial inlining
1555
1556 if(cmdline.isset("remove-pointers") ||
1557 cmdline.isset("race-check") ||
1558 cmdline.isset("mm") ||
1559 cmdline.isset("isr") ||
1560 cmdline.isset("concurrency"))
1561 {
1563
1564 log.status() << "Pointer Analysis" << messaget::eom;
1565 const namespacet ns(goto_model.symbol_table);
1566 value_set_analysist value_set_analysis(ns);
1567 value_set_analysis(goto_model);
1568
1569 if(cmdline.isset("remove-pointers"))
1570 {
1571 // removing pointers
1572 log.status() << "Removing Pointers" << messaget::eom;
1573 remove_pointers(goto_model, value_set_analysis, ui_message_handler);
1574 }
1575
1576 if(cmdline.isset("race-check"))
1577 {
1578 log.status() << "Adding Race Checks" << messaget::eom;
1579 race_check(value_set_analysis, goto_model, ui_message_handler);
1580 }
1581
1582 if(cmdline.isset("mm"))
1583 {
1584 std::string mm=cmdline.get_value("mm");
1585 memory_modelt model;
1586
1587 // strategy of instrumentation
1588 instrumentation_strategyt inst_strategy;
1589 if(cmdline.isset("one-event-per-cycle"))
1590 inst_strategy=one_event_per_cycle;
1591 else if(cmdline.isset("minimum-interference"))
1592 inst_strategy=min_interference;
1593 else if(cmdline.isset("read-first"))
1594 inst_strategy=read_first;
1595 else if(cmdline.isset("write-first"))
1596 inst_strategy=write_first;
1597 else if(cmdline.isset("my-events"))
1598 inst_strategy=my_events;
1599 else
1600 /* default: instruments all unsafe pairs */
1601 inst_strategy=all;
1602
1603 const unsigned max_var=
1604 cmdline.isset("max-var")?
1605 unsafe_string2unsigned(cmdline.get_value("max-var")):0;
1606 const unsigned max_po_trans=
1607 cmdline.isset("max-po-trans")?
1608 unsafe_string2unsigned(cmdline.get_value("max-po-trans")):0;
1609
1610 if(mm=="tso")
1611 {
1612 log.status() << "Adding weak memory (TSO) Instrumentation"
1613 << messaget::eom;
1614 model=TSO;
1615 }
1616 else if(mm=="pso")
1617 {
1618 log.status() << "Adding weak memory (PSO) Instrumentation"
1619 << messaget::eom;
1620 model=PSO;
1621 }
1622 else if(mm=="rmo")
1623 {
1624 log.status() << "Adding weak memory (RMO) Instrumentation"
1625 << messaget::eom;
1626 model=RMO;
1627 }
1628 else if(mm=="power")
1629 {
1630 log.status() << "Adding weak memory (Power) Instrumentation"
1631 << messaget::eom;
1632 model=Power;
1633 }
1634 else
1635 {
1636 log.error() << "Unknown weak memory model '" << mm << "'"
1637 << messaget::eom;
1638 model=Unknown;
1639 }
1640
1642
1643 if(cmdline.isset("force-loop-duplication"))
1644 loops=all_loops;
1645 if(cmdline.isset("no-loop-duplication"))
1646 loops=no_loop;
1647
1648 if(model!=Unknown)
1650 model,
1651 value_set_analysis,
1652 goto_model,
1653 cmdline.isset("scc"),
1654 inst_strategy,
1655 !cmdline.isset("cfg-kill"),
1656 cmdline.isset("no-dependencies"),
1657 loops,
1658 max_var,
1659 max_po_trans,
1660 !cmdline.isset("no-po-rendering"),
1661 cmdline.isset("render-cluster-file"),
1662 cmdline.isset("render-cluster-function"),
1663 cmdline.isset("cav11"),
1664 cmdline.isset("hide-internals"),
1666 cmdline.isset("ignore-arrays"));
1667 }
1668
1669 // Interrupt handler
1670 if(cmdline.isset("isr"))
1671 {
1672 log.status() << "Instrumenting interrupt handler" << messaget::eom;
1673 interrupt(
1674 value_set_analysis,
1675 goto_model,
1676 cmdline.get_value("isr"),
1678 }
1679
1680 // Memory-mapped I/O
1681 if(cmdline.isset("mmio"))
1682 {
1683 log.status() << "Instrumenting memory-mapped I/O" << messaget::eom;
1684 mmio(value_set_analysis, goto_model, ui_message_handler);
1685 }
1686
1687 if(cmdline.isset("concurrency"))
1688 {
1689 log.status() << "Sequentializing concurrency" << messaget::eom;
1690 concurrency(value_set_analysis, goto_model);
1691 }
1692 }
1693
1694 if(cmdline.isset("interval-analysis"))
1695 {
1696 log.status() << "Interval analysis" << messaget::eom;
1698 }
1699
1700 if(cmdline.isset("havoc-loops"))
1701 {
1702 log.status() << "Havocking loops" << messaget::eom;
1704 }
1705
1706 if(cmdline.isset("k-induction"))
1707 {
1708 bool base_case=cmdline.isset("base-case");
1709 bool step_case=cmdline.isset("step-case");
1710
1711 if(step_case && base_case)
1712 throw "please specify only one of --step-case and --base-case";
1713 else if(!step_case && !base_case)
1714 throw "please specify one of --step-case and --base-case";
1715
1716 unsigned k=unsafe_string2unsigned(cmdline.get_value("k-induction"));
1717
1718 if(k==0)
1719 throw "please give k>=1";
1720
1721 log.status() << "Instrumenting k-induction for k=" << k << ", "
1722 << (base_case ? "base case" : "step case") << messaget::eom;
1723
1724 k_induction(goto_model, base_case, step_case, k);
1725 }
1726
1727 if(cmdline.isset("function-enter"))
1728 {
1729 log.status() << "Function enter instrumentation" << messaget::eom;
1731 goto_model,
1732 cmdline.get_value("function-enter"));
1733 }
1734
1735 if(cmdline.isset("function-exit"))
1736 {
1737 log.status() << "Function exit instrumentation" << messaget::eom;
1739 goto_model,
1740 cmdline.get_value("function-exit"));
1741 }
1742
1743 if(cmdline.isset("branch"))
1744 {
1745 log.status() << "Branch instrumentation" << messaget::eom;
1746 branch(
1747 goto_model,
1748 cmdline.get_value("branch"));
1749 }
1750
1751 // add failed symbols
1752 add_failed_symbols(goto_model.symbol_table);
1753
1754 // recalculate numbers, etc.
1755 goto_model.goto_functions.update();
1756
1757 // add loop ids
1758 goto_model.goto_functions.compute_loop_numbers();
1759
1760 // label the assertions
1762
1763 nondet_volatile(goto_model, options);
1764
1765 // reachability slice?
1766 if(cmdline.isset("reachability-slice"))
1767 {
1769
1770 log.status() << "Performing a reachability slice" << messaget::eom;
1771
1772 // reachability_slicer requires that the model has unique location numbers:
1773 goto_model.goto_functions.update();
1774
1775 if(cmdline.isset("property"))
1776 {
1778 goto_model, cmdline.get_values("property"), ui_message_handler);
1779 }
1780 else
1782 }
1783
1784 if(cmdline.isset("fp-reachability-slice"))
1785 {
1787
1788 log.status() << "Performing a function pointer reachability slice"
1789 << messaget::eom;
1791 goto_model,
1792 cmdline.get_comma_separated_values("fp-reachability-slice"),
1794 }
1795
1796 // full slice?
1797 if(cmdline.isset("full-slice"))
1798 {
1802 // full_slicer requires that the model has unique location numbers:
1803 goto_model.goto_functions.update();
1804
1805 log.warning() << "**** WARNING: Experimental option --full-slice, "
1806 << "analysis results may be unsound. See "
1807 << "https://github.com/diffblue/cbmc/issues/260"
1808 << messaget::eom;
1809 log.status() << "Performing a full slice" << messaget::eom;
1810 if(cmdline.isset("property"))
1812 goto_model, cmdline.get_values("property"), ui_message_handler);
1813 else
1814 {
1816 }
1817 }
1818
1819 // splice option
1820 if(cmdline.isset("splice-call"))
1821 {
1822 log.status() << "Performing call splicing" << messaget::eom;
1823 std::string callercallee=cmdline.get_value("splice-call");
1824 if(splice_call(
1825 goto_model.goto_functions,
1826 callercallee,
1827 goto_model.symbol_table,
1829 throw 0;
1830 }
1831
1832 // aggressive slicer
1833 if(cmdline.isset("aggressive-slice"))
1834 {
1836
1837 // reachability_slicer requires that the model has unique location numbers:
1838 goto_model.goto_functions.update();
1839
1840 log.status() << "Slicing away initializations of unused global variables"
1841 << messaget::eom;
1843
1844 log.status() << "Performing an aggressive slice" << messaget::eom;
1846
1847 if(cmdline.isset("aggressive-slice-call-depth"))
1848 aggressive_slicer.call_depth =
1849 safe_string2unsigned(cmdline.get_value("aggressive-slice-call-depth"));
1850
1851 if(cmdline.isset("aggressive-slice-preserve-function"))
1852 aggressive_slicer.preserve_functions(
1853 cmdline.get_values("aggressive-slice-preserve-function"));
1854
1855 if(cmdline.isset("property"))
1856 aggressive_slicer.user_specified_properties =
1857 cmdline.get_values("property");
1858
1859 if(cmdline.isset("aggressive-slice-preserve-functions-containing"))
1860 aggressive_slicer.name_snippets =
1861 cmdline.get_values("aggressive-slice-preserve-functions-containing");
1862
1863 aggressive_slicer.preserve_all_direct_paths =
1864 cmdline.isset("aggressive-slice-preserve-all-direct-paths");
1865
1866 aggressive_slicer.doit();
1867
1868 goto_model.goto_functions.update();
1869
1870 log.status() << "Performing a reachability slice" << messaget::eom;
1871 if(cmdline.isset("property"))
1872 {
1874 goto_model, cmdline.get_values("property"), ui_message_handler);
1875 }
1876 else
1878 }
1879
1880 if(cmdline.isset("ensure-one-backedge-per-target"))
1881 {
1882 log.status() << "Trying to force one backedge per target" << messaget::eom;
1884 }
1885
1886 // recalculate numbers, etc.
1887 goto_model.goto_functions.update();
1888}
1889
1892{
1893 std::cout << '\n'
1894 << banner_string("Goto-Instrument", CBMC_VERSION) << '\n'
1895 << align_center_with_border("Copyright (C) 2008-2013") << '\n'
1896 << align_center_with_border("Daniel Kroening") << '\n'
1897 << align_center_with_border("kroening@kroening.com") << '\n';
1898
1899 // clang-format off
1900 std::cout << help_formatter(
1901 "\n"
1902 "Usage: \tPurpose:\n"
1903 "\n"
1904 " {bgoto-instrument} [{y-?}] [{y-h}] [{y--help}] \t show this help\n"
1905 " {bgoto-instrument} {y--version} \t show version and exit\n"
1906 " {bgoto-instrument} [options] {uin} [{uout}] \t perform analysis or"
1907 " instrumentation\n"
1908 "\n"
1909 "Dump Source:\n"
1911 " {y--horn} \t print program as constrained horn clauses\n"
1912 "\n"
1913 "Diagnosis:\n"
1916 " {y--show-symbol-table} \t show loaded symbol table\n"
1917 " {y--list-symbols} \t list symbols with type information\n"
1920 " {y--show-locations} \t show all source locations\n"
1921 " {y--dot} \t generate CFG graph in DOT format\n"
1922 " {y--print-internal-representation} \t show verbose internal"
1923 " representation of the program\n"
1924 " {y--list-undefined-functions} \t list functions without body\n"
1925 " {y--list-calls-args} \t list all function calls with their arguments\n"
1926 " {y--call-graph} \t show graph of function calls\n"
1927 " {y--reachable-call-graph} \t show graph of function calls potentially"
1928 " reachable from main function\n"
1931 " {y--validate-goto-binary} \t check the well-formedness of the passed in"
1932 " goto binary and then exit\n"
1933 " {y--interpreter} \t do concrete execution\n"
1934 "\n"
1935 "Data-flow analyses:\n"
1936 " {y--show-struct-alignment} \t show struct members that might be"
1937 " concurrently accessed\n"
1938 " {y--show-threaded} \t show instructions that may be executed by more than"
1939 " one thread\n"
1940 " {y--show-local-safe-pointers} \t show pointer expressions that are"
1941 " trivially dominated by a not-null check\n"
1942 " {y--show-safe-dereferences} \t show pointer expressions that are"
1943 " trivially dominated by a not-null check *and* used as a dereference"
1944 " operand\n"
1945 " {y--show-value-sets} \t show points-to information (using value sets)\n"
1946 " {y--show-global-may-alias} \t show may-alias information over globals\n"
1947 " {y--show-local-bitvector-analysis} \t show procedure-local pointer"
1948 " analysis\n"
1949 " {y--escape-analysis} \t perform escape analysis\n"
1950 " {y--show-escape-analysis} \t show results of escape analysis\n"
1951 " {y--custom-bitvector-analysis} \t perform configurable bitvector"
1952 " analysis\n"
1953 " {y--show-custom-bitvector-analysis} \t show results of configurable"
1954 " bitvector analysis\n"
1955 " {y--interval-analysis} \t perform interval analysis\n"
1956 " {y--show-intervals} \t show results of interval analysis\n"
1957 " {y--show-uninitialized} \t show maybe-uninitialized variables\n"
1958 " {y--show-points-to} \t show points-to information\n"
1959 " {y--show-rw-set} \t show read-write sets\n"
1960 " {y--show-call-sequences} \t show function call sequences\n"
1961 " {y--show-reaching-definitions} \t show reaching definitions\n"
1962 " {y--show-dependence-graph} \t show program-dependence graph\n"
1963 " {y--show-sese-regions} \t show single-entry-single-exit regions\n"
1964 "\n"
1965 "Safety checks:\n"
1966 " {y--no-assertions} \t ignore user assertions\n"
1969 " {y--stack-depth} {un} \t add check that call stack size of non-inlined"
1970 " functions never exceeds {un}\n"
1971 " {y--race-check} \t add floating-point data race checks\n"
1972 "\n"
1973 "Semantic transformations:\n"
1975 " {y--isr} {ufunction} \t instruments an interrupt service routine\n"
1976 " {y--mmio} \t instruments memory-mapped I/O\n"
1977 " {y--nondet-static} \t add nondeterministic initialization of variables"
1978 " with static lifetime\n"
1979 " {y--nondet-static-exclude} {ue} \t same as nondet-static except for the"
1980 " variable {ue} (use multiple times if required)\n"
1981 " {y--nondet-static-matching} {ur} \t add nondeterministic initialization"
1982 " of variables with static lifetime matching regex {ur}\n"
1983 " {y--function-enter} {uf}, {y--function-exit} {uf}, {y--branch} {uf} \t"
1984 " instruments a call to {uf} at the beginning, the exit, or a branch point,"
1985 " respectively\n"
1986 " {y--splice-call} {ucaller},{ucallee} \t prepends a call to {ucallee} in"
1987 " the body of {ucaller}\n"
1988 " {y--check-call-sequence} {useq} \t instruments checks to assert that all"
1989 " call sequences match {useq}\n"
1990 " {y--undefined-function-is-assume-false} \t convert each call to an"
1991 " undefined function to assume(false)\n"
1996 " {y--add-library} \t add models of C library functions\n"
1999 " {y--remove-function-body} {uf} \t remove the implementation of function"
2000 " {uf} (may be repeated)\n"
2001 " {y--remove-function-body-regex} {uregex} \t remove the implementation of"
2002 " functions matching regular expression {uregex}\n"
2005 "\n"
2006 "Semantics-preserving transformations:\n"
2007 " {y--ensure-one-backedge-per-target} \t transform loop bodies such that"
2008 " there is a single edge back to the loop head\n"
2009 " {y--drop-unused-functions} \t drop functions trivially unreachable from"
2010 " main function\n"
2012 " {y--constant-propagator} \t propagate constants and simplify"
2013 " expressions\n"
2014 " {y--inline} \t perform full inlining\n"
2015 " {y--partial-inline} \t perform partial inlining\n"
2016 " {y--function-inline} {ufunction} \t transitively inline all calls"
2017 " {ufunction} makes\n"
2018 " {y--no-caching} \t disable caching of intermediate results during"
2019 " transitive function inlining\n"
2020 " {y--log} {ufile} \t log in JSON format which code segments were inlined,"
2021 " use with {y--function-inline}\n"
2022 " {y--remove-function-pointers} \t replace function pointers by case"
2023 " statement over function calls\n"
2025 " {y--value-set-fi-fp-removal} \t build flow-insensitive value set and"
2026 " replace function pointers by a case statement over the possible"
2027 " assignments. If the set of possible assignments is empty the function"
2028 " pointer is removed using the standard remove-function-pointers pass.\n"
2029 "\n"
2030 "Loop information and transformations:\n"
2032 " {y--unwindset-file_<file>} \t read unwindset from file\n"
2033 " {y--partial-loops} \t permit paths with partial loops\n"
2034 " {y--unwinding-assertions} \t generate unwinding assertions"
2035 " (enabled by default)\n"
2036 " {y--no-unwinding-assertions} \t do not generate unwinding assertions\n"
2037 " {y--continue-as-loops} \t add loop for remaining iterations after"
2038 " unwound part\n"
2039 " {y--k-induction} {uk} \t check loops with k-induction\n"
2040 " {y--step-case} \t k-induction: do step-case\n"
2041 " {y--base-case} \t k-induction: do base-case\n"
2042 " {y--havoc-loops} \t over-approximate all loops\n"
2043 " {y--accelerate} \t add loop accelerators\n"
2044 " {y--z3} \t use Z3 when computing loop accelerators\n"
2045 " {y--skip-loops {uloop-ids} \t add gotos to skip selected loops during"
2046 " execution\n"
2047 " {y--show-lexical-loops} \t show single-entry-single-back-edge loops\n"
2048 " {y--show-natural-loops} \t show natural loop heads\n"
2049 "\n"
2050 "Memory model instrumentations:\n"
2052 "\n"
2053 "Slicing:\n"
2056 " {y--full-slice} \t slice away instructions that don't affect assertions\n"
2057 " {y--property} {uid} \t slice with respect to specific property only\n"
2058 " {y--slice-global-inits} \t slice away initializations of unused global"
2059 " variables\n"
2060 " {y--aggressive-slice} \t remove bodies of any functions not on the"
2061 " shortest path between the start function and the function containing the"
2062 " property/properties\n"
2063 " {y--aggressive-slice-call-depth} {un} \t used with aggressive-slice,"
2064 " preserves all functions within {un} function calls of the functions on"
2065 " the shortest path\n"
2066 " {y--aggressive-slice-preserve-function} {uf} \t force the aggressive"
2067 " slicer to preserve function {uf}\n"
2068 " {y--aggressive-slice-preserve-functions-containing} {uf} \t force the"
2069 " aggressive slicer to preserve all functions with names containing {uf}\n"
2070 " {y--aggressive-slice-preserve-all-direct-paths} \t force aggressive"
2071 " slicer to preserve all direct paths\n"
2072 "\n"
2073 "Code contracts:\n"
2074 HELP_DFCC
2082 "\n"
2083 "User-interface options:\n"
2085 " {y--xml} \t output files in XML where supported\n"
2086 " {y--xml-ui} \t use XML-formatted output\n"
2087 " {y--json-ui} \t use JSON-formatted output\n"
2088 " {y--verbosity} {u#} \t verbosity level\n"
2090 "\n");
2091 // clang-format on
2092}
void accelerate_functions(goto_modelt &goto_model, message_handlert &message_handler, bool use_z3, guard_managert &guard_manager)
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
void output(std::ostream &out) const
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
Non-graph-based representation of the class hierarchy.
void output_dot(std::ostream &) const
Output class hierarchy in Graphviz DOT format.
void apply_loop_contracts(const std::set< std::string > &to_exclude_from_nondet_init={})
Applies loop contract transformations.
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.
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.
void check(const goto_modelt &, bool xml, std::ostream &)
bool empty() const
Definition dstring.h:89
void instrument(goto_modelt &)
void get(const std::string &executable)
This is a may analysis (i.e.
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_remove_const_function_pointers_only()
Remove function pointers that can be resolved by analysing const variables (i.e.
int doit() override
invoke main modules
A generic container class for the GOTO intermediate representation of one function.
std::ostream & output(std::ostream &out) const
Output goto-program to given stream.
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
@ 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:91
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
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
ui_message_handlert ui_message_handler
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
void parse_unwind(const std::string &unwind)
Definition unwindset.cpp:23
void parse_unwindset(const std::list< std::string > &unwindset, abstract_goto_modelt &goto_model, message_handlert &message_handler)
void parse_unwindset_file(const std::string &file_name, abstract_goto_modelt &goto_model, message_handlert &message_handler)
void concurrency(value_setst &value_sets, goto_modelt &goto_model)
Encoding for Threaded Goto Programs.
#define HELP_CONFIG_LIBRARY
Definition config.h:85
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)
void print_global_state_size(const goto_modelt &goto_model)
void print_path_lengths(const goto_modelt &goto_model)
void list_eloc(const goto_modelt &goto_model)
#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, bool ignore_no_match)
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)
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)
#define HELP_GOTO_CHECK
void goto_inline(goto_modelt &goto_model, message_handlert &message_handler, bool adjust_function)
Inline every function call into the entry_point() function.
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:93
Guard Data Structure.
guard_expr_managert guard_managert
Definition guard.h:28
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, const std::list< std::string > &argv_args, bool model_argv, message_handlert &message_handler)
Set up argv to user-specified values (when model_argv is FALSE) or (when model_argv is TRUE) set up a...
#define HELP_ARGC_ARGV
Compute natural loops in a goto_function.
void show_natural_loops(const goto_modelt &goto_model, std::ostream &out)
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)
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...
bool has_asm(const goto_functionst &goto_functions)
returns true iff the given goto functions use asm instructions
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...
static void remove_functions_regex(goto_modelt &goto_model, const std::regex &pattern, const std::string &pattern_as_str, message_handlert &message_handler)
Remove functions matching a regular expression pattern.
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
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
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)
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)
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)
Stack depth checks.
unsigned safe_string2unsigned(const std::string &str, int base)
unsigned unsafe_string2unsigned(const std::string &str, int base)
std::size_t safe_string2size_t(const std::string &str, int base)
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)
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
Loop unwinding.
#define HELP_UNWINDSET
Definition unwindset.h:78
#define HELP_VALIDATE
Value Set Propagation.
value_set_analysis_templatet< value_set_domain_templatet< value_sett > > value_set_analysist
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
dstringt irep_idt
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.