Skip to content

Commit 9e02d7f

Browse files
author
martin
committed
Add a new set of options that allow task, abstract interpreter and domain
to be picked independently. This should only add functionality, not change any of the existing behaviour.
1 parent 71d2053 commit 9e02d7f

9 files changed

+827
-8
lines changed

src/goto-analyzer/Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ SRC = goto_analyzer_main.cpp \
44
taint_analysis.cpp \
55
taint_parser.cpp \
66
unreachable_instructions.cpp \
7+
static_show_domain.cpp \
8+
static_simplifier.cpp \
9+
static_verifier.cpp \
710
# Empty last line
811

912
OBJ += ../ansi-c/ansi-c$(LIBEXT) \

src/goto-analyzer/goto_analyzer_parse_options.cpp

+206-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*******************************************************************\
22
3-
Module: Goto-Analyser Command Line Option Processing
3+
Module: Goto-Analyzer Command Line Option Processing
44
55
Author: Daniel Kroening, [email protected]
66
@@ -38,7 +38,11 @@ Author: Daniel Kroening, [email protected]
3838
#include <goto-programs/goto_inline.h>
3939
#include <goto-programs/link_to_library.h>
4040

41+
#include <analyses/is_threaded.h>
42+
#include <analyses/goto_check.h>
4143
#include <analyses/local_may_alias.h>
44+
#include <analyses/constant_propagator.h>
45+
#include <analyses/dependence_graph.h>
4246

4347
#include <langapi/mode.h>
4448

@@ -47,12 +51,16 @@ Author: Daniel Kroening, [email protected]
4751
#include <util/config.h>
4852
#include <util/string2int.h>
4953
#include <util/unicode.h>
54+
#include <util/exit_codes.h>
5055

5156
#include <cbmc/version.h>
5257

5358
#include "taint_analysis.h"
5459
#include "unreachable_instructions.h"
5560
#include "static_analyzer.h"
61+
#include "static_show_domain.h"
62+
#include "static_simplifier.h"
63+
#include "static_verifier.h"
5664

5765
goto_analyzer_parse_optionst::goto_analyzer_parse_optionst(
5866
int argc,
@@ -200,6 +208,106 @@ void goto_analyzer_parse_optionst::get_command_line_options(optionst &options)
200208
options.set_option("text", true);
201209
options.set_option("outfile", "-");
202210
}
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;
203311
}
204312

205313
/// invoke main modules
@@ -404,6 +512,79 @@ int goto_analyzer_parse_optionst::doit()
404512
return result?10:0;
405513
}
406514

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
407588
error() << "no analysis option given -- consider reading --help"
408589
<< eom;
409590
return 6;
@@ -516,7 +697,7 @@ void goto_analyzer_parse_optionst::help()
516697
{
517698
std::cout <<
518699
"\n"
519-
"* * GOTO-ANALYSER " CBMC_VERSION " - Copyright (C) 2016 ";
700+
"* * GOTO-ANALYZER " CBMC_VERSION " - Copyright (C) 2017 ";
520701

521702
std::cout << "(" << (sizeof(void *)*8) << "-bit version)";
522703

@@ -531,8 +712,30 @@ void goto_analyzer_parse_optionst::help()
531712
" goto-analyzer [-h] [--help] show help\n"
532713
" goto-analyzer file.c ... source file names\n"
533714
"\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"
535737
"\n"
738+
"Specific analyses:\n"
536739
// NOLINTNEXTLINE(whitespace/line_length)
537740
" --taint file_name perform taint analysis using rules in given file\n"
538741
" --unreachable-instructions list dead code\n"
@@ -543,11 +746,6 @@ void goto_analyzer_parse_optionst::help()
543746
" --intervals interval analysis\n"
544747
" --non-null non-null analysis\n"
545748
"\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"
551749
"C/C++ frontend options:\n"
552750
" -I path set include path (C/C++)\n"
553751
" -D macro define preprocessor macro (C/C++)\n"

0 commit comments

Comments
 (0)