|
48 | 48 | #include <analyses/goto_check.h>
|
49 | 49 | #include <analyses/interval_domain.h>
|
50 | 50 | #include <analyses/is_threaded.h>
|
| 51 | +#include <analyses/local_control_flow_history.h> |
51 | 52 | #include <analyses/local_may_alias.h>
|
52 | 53 |
|
53 | 54 | #include <langapi/mode.h>
|
@@ -295,6 +296,34 @@ void goto_analyzer_parse_optionst::get_command_line_options(optionst &options)
|
295 | 296 | "call-stack-recursion-limit", cmdline.get_value("call-stack"));
|
296 | 297 | options.set_option("history set", true);
|
297 | 298 | }
|
| 299 | + else if(cmdline.isset("loop-unwind")) |
| 300 | + { |
| 301 | + options.set_option("local-control-flow-history", true); |
| 302 | + options.set_option("local-control-flow-history-forward", false); |
| 303 | + options.set_option("local-control-flow-history-backward", true); |
| 304 | + options.set_option( |
| 305 | + "local-control-flow-history-limit", cmdline.get_value("loop-unwind")); |
| 306 | + options.set_option("history set", true); |
| 307 | + } |
| 308 | + else if(cmdline.isset("branching")) |
| 309 | + { |
| 310 | + options.set_option("local-control-flow-history", true); |
| 311 | + options.set_option("local-control-flow-history-forward", true); |
| 312 | + options.set_option("local-control-flow-history-backward", false); |
| 313 | + options.set_option( |
| 314 | + "local-control-flow-history-limit", cmdline.get_value("branching")); |
| 315 | + options.set_option("history set", true); |
| 316 | + } |
| 317 | + else if(cmdline.isset("loop-unwind-and-branching")) |
| 318 | + { |
| 319 | + options.set_option("local-control-flow-history", true); |
| 320 | + options.set_option("local-control-flow-history-forward", true); |
| 321 | + options.set_option("local-control-flow-history-backward", true); |
| 322 | + options.set_option( |
| 323 | + "local-control-flow-history-limit", |
| 324 | + cmdline.get_value("loop-unwind-and-branching")); |
| 325 | + options.set_option("history set", true); |
| 326 | + } |
298 | 327 |
|
299 | 328 | if(!options.get_bool_option("history set"))
|
300 | 329 | {
|
@@ -400,6 +429,13 @@ ai_baset *goto_analyzer_parse_optionst::build_analyzer(
|
400 | 429 | hf = util_make_unique<call_stack_history_factoryt>(
|
401 | 430 | options.get_unsigned_int_option("call-stack-recursion-limit"));
|
402 | 431 | }
|
| 432 | + else if(options.get_bool_option("local-control-flow-history")) |
| 433 | + { |
| 434 | + hf = util_make_unique<local_control_flow_history_factoryt>( |
| 435 | + options.get_bool_option("local-control-flow-history-forward"), |
| 436 | + options.get_bool_option("local-control-flow-history-backward"), |
| 437 | + options.get_unsigned_int_option("local-control-flow-history-limit")); |
| 438 | + } |
403 | 439 |
|
404 | 440 | // Build the domain factory
|
405 | 441 | std::unique_ptr<ai_domain_factory_baset> df = nullptr;
|
@@ -855,6 +891,18 @@ void goto_analyzer_parse_optionst::help()
|
855 | 891 | " --call-stack n track the calling location stack for each function\n"
|
856 | 892 | // NOLINTNEXTLINE(whitespace/line_length)
|
857 | 893 | " limiting to at most n recursive loops, 0 to disable\n"
|
| 894 | + // NOLINTNEXTLINE(whitespace/line_length) |
| 895 | + " --loop-unwind n track the number of loop iterations within a function\n" |
| 896 | + // NOLINTNEXTLINE(whitespace/line_length) |
| 897 | + " limited to n histories per location, 0 is unlimited\n" |
| 898 | + // NOLINTNEXTLINE(whitespace/line_length) |
| 899 | + " --branching n track the forwards jumps (if, switch, etc.) within a function\n" |
| 900 | + // NOLINTNEXTLINE(whitespace/line_length) |
| 901 | + " limited to n histories per location, 0 is unlimited\n" |
| 902 | + // NOLINTNEXTLINE(whitespace/line_length) |
| 903 | + " --loop-unwind-and-branching n track all local control flow\n" |
| 904 | + // NOLINTNEXTLINE(whitespace/line_length) |
| 905 | + " limited to n histories per location, 0 is unlimited\n" |
858 | 906 | "\n"
|
859 | 907 | "Domain options:\n"
|
860 | 908 | " --constants a constant for each variable if possible\n"
|
|
0 commit comments