1
1
/* ******************************************************************\
2
2
3
- Module: Goto-Analyser Command Line Option Processing
3
+ Module: Goto-Analyzer Command Line Option Processing
4
4
5
5
Author: Daniel Kroening, [email protected]
6
6
38
38
#include < goto-programs/goto_inline.h>
39
39
#include < goto-programs/link_to_library.h>
40
40
41
+ #include < analyses/is_threaded.h>
42
+ #include < analyses/goto_check.h>
41
43
#include < analyses/local_may_alias.h>
44
+ #include < analyses/constant_propagator.h>
45
+ #include < analyses/dependence_graph.h>
42
46
43
47
#include < langapi/mode.h>
44
48
47
51
#include < util/config.h>
48
52
#include < util/string2int.h>
49
53
#include < util/unicode.h>
54
+ #include < util/exit_codes.h>
50
55
51
56
#include < cbmc/version.h>
52
57
53
58
#include " taint_analysis.h"
54
59
#include " unreachable_instructions.h"
55
60
#include " static_analyzer.h"
61
+ #include " static_show_domain.h"
62
+ #include " static_simplifier.h"
63
+ #include " static_verifier.h"
56
64
57
65
goto_analyzer_parse_optionst::goto_analyzer_parse_optionst (
58
66
int argc,
@@ -200,6 +208,106 @@ void goto_analyzer_parse_optionst::get_command_line_options(optionst &options)
200
208
options.set_option (" text" , true );
201
209
options.set_option (" outfile" , " -" );
202
210
}
211
+
212
+ // The use should either select:
213
+ // 1. a specific analysis, or
214
+ // 2. a triple of task / analyzer / domain, or
215
+ // 3. one of the general display options
216
+
217
+ // Task options
218
+ if (cmdline.isset (" show" ))
219
+ {
220
+ options.set_option (" show" , true );
221
+ options.set_option (" general-analysis" , true );
222
+ }
223
+ else if (cmdline.isset (" verify" ))
224
+ {
225
+ options.set_option (" verify" , true );
226
+ options.set_option (" general-analysis" , true );
227
+ }
228
+ else if (cmdline.isset (" simplify" ))
229
+ {
230
+ options.set_option (" simplify" , true );
231
+ options.set_option (" outfile" , cmdline.get_value (" simplify" ));
232
+ options.set_option (" general-analysis" , true );
233
+
234
+ // For development allow slicing to be disabled in the simplify task
235
+ options.set_option (
236
+ " simplify-slicing" ,
237
+ !(cmdline.isset (" no-simplify-slicing" )));
238
+ }
239
+
240
+
241
+ if (options.get_bool_option (" general-analysis" ))
242
+ {
243
+ // Abstract interpreter choice
244
+ if (cmdline.isset (" location-sensitive" ))
245
+ options.set_option (" location-sensitive" , true );
246
+ else if (cmdline.isset (" concurrent" ))
247
+ options.set_option (" concurrent" , true );
248
+ else
249
+ {
250
+ // Silently default to location-sensitive as it's the "default"
251
+ // view of abstract interpretation.
252
+ options.set_option (" location-sensitive" , true );
253
+ }
254
+
255
+ // Domain choice
256
+ if (cmdline.isset (" constants" ))
257
+ {
258
+ options.set_option (" constants" , true );
259
+ options.set_option (" domain set" , true );
260
+ }
261
+ else if (cmdline.isset (" dependence-graph" ))
262
+ {
263
+ options.set_option (" dependence-graph" , true );
264
+ options.set_option (" domain set" , true );
265
+ }
266
+
267
+ if (!options.get_bool_option (" domain set" ))
268
+ {
269
+ // Deafult to constants as it is light-weight but useful
270
+ status () << " Domain defaults to --constants" << eom;
271
+ options.set_option (" constants" , true );
272
+ }
273
+ }
274
+ }
275
+
276
+ // / For the task, build the appropriate kind of analyzer
277
+ // / Ideally this should be a pure function of options.
278
+ // / However at the moment some domains require the goto_model
279
+ ai_baset *goto_analyzer_parse_optionst::build_analyzer (const optionst &options)
280
+ {
281
+ ai_baset *domain = nullptr ;
282
+
283
+ if (options.get_bool_option (" location-sensitive" ))
284
+ {
285
+ if (options.get_bool_option (" constants" ))
286
+ {
287
+ // constant_propagator_ait derives from ait<constant_propagator_domaint>
288
+ domain=new constant_propagator_ait (goto_model.goto_functions );
289
+ }
290
+ else if (options.get_bool_option (" dependence-graph" ))
291
+ {
292
+ domain=new dependence_grapht (namespacet (goto_model.symbol_table ));
293
+ }
294
+ }
295
+ else if (options.get_bool_option (" concurrent" ))
296
+ {
297
+ #if 0
298
+ // Disabled until merge_shared is implemented for these
299
+ if(options.get_bool_option("constants"))
300
+ {
301
+ domain=new concurrency_aware_ait<constant_propagator_domaint>();
302
+ }
303
+ else if(options.get_bool_option("dependence-graph"))
304
+ {
305
+ domain=new dependence_grapht(namespacet(goto_model.symbol_table));
306
+ }
307
+ #endif
308
+ }
309
+
310
+ return domain;
203
311
}
204
312
205
313
// / invoke main modules
@@ -404,6 +512,79 @@ int goto_analyzer_parse_optionst::doit()
404
512
return result?10 :0 ;
405
513
}
406
514
515
+ if (options.get_bool_option (" general-analysis" ))
516
+ {
517
+
518
+ // Output file factory
519
+ const std::string outfile=options.get_option (" outfile" );
520
+ std::ofstream output_stream;
521
+ if (!(outfile==" -" ))
522
+ output_stream.open (outfile);
523
+
524
+ std::ostream &out ((outfile==" -" ) ? std::cout : output_stream);
525
+
526
+ if (!out)
527
+ {
528
+ error () << " Failed to open output file `"
529
+ << outfile << " '" << eom;
530
+ return CPROVER_EXIT_INTERNAL_ERROR;
531
+ }
532
+
533
+ // Build analyzer
534
+ status () << " Selecting abstract domain" << eom;
535
+ std::unique_ptr<ai_baset> analyzer (build_analyzer (options));
536
+
537
+ if (analyzer == nullptr )
538
+ {
539
+ status () << " Task / Interpreter / Domain combination not supported"
540
+ << messaget::eom;
541
+ return CPROVER_EXIT_INTERNAL_ERROR;
542
+ }
543
+
544
+
545
+ // Run
546
+ status () << " Computing abstract states" << eom;
547
+ (*analyzer)(goto_model);
548
+
549
+ // Perform the task
550
+ status () << " Performing task" << eom;
551
+ bool result = true ;
552
+ if (options.get_bool_option (" show" ))
553
+ {
554
+ result = static_show_domain (goto_model,
555
+ *analyzer,
556
+ options,
557
+ get_message_handler (),
558
+ out);
559
+ }
560
+ else if (options.get_bool_option (" verify" ))
561
+ {
562
+ result = static_verifier (goto_model,
563
+ *analyzer,
564
+ options,
565
+ get_message_handler (),
566
+ out);
567
+ }
568
+ else if (options.get_bool_option (" simplify" ))
569
+ {
570
+ result = static_simplifier (goto_model,
571
+ *analyzer,
572
+ options,
573
+ get_message_handler (),
574
+ out);
575
+ }
576
+ else
577
+ {
578
+ error () << " Unhandled task" << eom;
579
+ return CPROVER_EXIT_INTERNAL_ERROR;
580
+ }
581
+
582
+ return result ?
583
+ CPROVER_EXIT_VERIFICATION_UNSAFE : CPROVER_EXIT_VERIFICATION_SAFE;
584
+ }
585
+
586
+
587
+ // Final defensive error case
407
588
error () << " no analysis option given -- consider reading --help"
408
589
<< eom;
409
590
return 6 ;
@@ -516,7 +697,7 @@ void goto_analyzer_parse_optionst::help()
516
697
{
517
698
std::cout <<
518
699
" \n "
519
- " * * GOTO-ANALYSER " CBMC_VERSION " - Copyright (C) 2016 " ;
700
+ " * * GOTO-ANALYZER " CBMC_VERSION " - Copyright (C) 2017 " ;
520
701
521
702
std::cout << " (" << (sizeof (void *)*8 ) << " -bit version)" ;
522
703
@@ -531,8 +712,30 @@ void goto_analyzer_parse_optionst::help()
531
712
" goto-analyzer [-h] [--help] show help\n "
532
713
" goto-analyzer file.c ... source file names\n "
533
714
" \n "
534
- " Analyses:\n "
715
+ " Task options:\n "
716
+ " --show display the abstract domains\n "
717
+ // NOLINTNEXTLINE(whitespace/line_length)
718
+ " --verify use the abstract domains to check assertions\n "
719
+ // NOLINTNEXTLINE(whitespace/line_length)
720
+ " --simplify file_name use the abstract domains to simplify the program\n "
721
+ " \n "
722
+ " Abstract interpreter options:\n "
723
+ // NOLINTNEXTLINE(whitespace/line_length)
724
+ " --location-sensitive use location-sensitive abstract interpreter\n "
725
+ " --concurrent use concurrency-aware abstract interpreter\n "
726
+ " \n "
727
+ " Domain options:\n "
728
+ " --constants constant domain\n "
729
+ " --dependence-graph data and control dependencies between instructions\n " // NOLINT(*)
730
+ " \n "
731
+ " Output options:\n "
732
+ " --text file_name output results in plain text to given file\n "
733
+ // NOLINTNEXTLINE(whitespace/line_length)
734
+ " --json file_name output results in JSON format to given file\n "
735
+ " --xml file_name output results in XML format to given file\n "
736
+ " --dot file_name output results in DOT format to given file\n "
535
737
" \n "
738
+ " Specific analyses:\n "
536
739
// NOLINTNEXTLINE(whitespace/line_length)
537
740
" --taint file_name perform taint analysis using rules in given file\n "
538
741
" --unreachable-instructions list dead code\n "
@@ -543,11 +746,6 @@ void goto_analyzer_parse_optionst::help()
543
746
" --intervals interval analysis\n "
544
747
" --non-null non-null analysis\n "
545
748
" \n "
546
- " Analysis options:\n "
547
- // NOLINTNEXTLINE(whitespace/line_length)
548
- " --json file_name output results in JSON format to given file\n "
549
- " --xml file_name output results in XML format to given file\n "
550
- " \n "
551
749
" C/C++ frontend options:\n "
552
750
" -I path set include path (C/C++)\n "
553
751
" -D macro define preprocessor macro (C/C++)\n "
0 commit comments