Skip to content

Commit fb38813

Browse files
authored
Merge pull request #5920 from martin-cs/refactor/make-goto-analyzer-more-modular
Refactor/make goto analyzer more modular
2 parents b5d2a72 + 11193e4 commit fb38813

File tree

9 files changed

+377
-295
lines changed

9 files changed

+377
-295
lines changed

scripts/expected_doxygen_warnings.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
/home/runner/work/cbmc/cbmc/src/util/rename.h:23: warning: documented empty return type of get_new_name
2121
warning: Include graph for 'goto_instrument_parse_options.cpp' not generated, too many nodes (97), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
2222
warning: Included by graph for 'goto_functions.h' not generated, too many nodes (66), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
23-
warning: Included by graph for 'goto_model.h' not generated, too many nodes (110), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
23+
warning: Included by graph for 'goto_model.h' not generated, too many nodes (111), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
2424
warning: Included by graph for 'arith_tools.h' not generated, too many nodes (181), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
2525
warning: Included by graph for 'c_types.h' not generated, too many nodes (141), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
2626
warning: Included by graph for 'config.h' not generated, too many nodes (87), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
@@ -30,7 +30,7 @@ warning: Included by graph for 'expr_util.h' not generated, too many nodes (61),
3030
warning: Included by graph for 'invariant.h' not generated, too many nodes (186), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
3131
warning: Included by graph for 'irep.h' not generated, too many nodes (62), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
3232
warning: Included by graph for 'message.h' not generated, too many nodes (117), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
33-
warning: Included by graph for 'namespace.h' not generated, too many nodes (109), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
33+
warning: Included by graph for 'namespace.h' not generated, too many nodes (110), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
3434
warning: Included by graph for 'pointer_expr.h' not generated, too many nodes (116), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
3535
warning: Included by graph for 'prefix.h' not generated, too many nodes (85), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.
3636
warning: Included by graph for 'simplify_expr.h' not generated, too many nodes (79), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES.

src/analyses/variable-sensitivity/variable_sensitivity_domain.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,37 @@
7272
#include <analyses/variable-sensitivity/abstract_environment.h>
7373
#include <analyses/variable-sensitivity/variable_sensitivity_configuration.h>
7474

75+
#define OPT_VSD \
76+
"(vsd-values):" \
77+
"(vsd-structs):" \
78+
"(vsd-arrays):" \
79+
"(vsd-pointers):" \
80+
"(vsd-unions):" \
81+
"(vsd-flow-insensitive)" \
82+
"(vsd-data-dependencies)"
83+
84+
// clang-format off
85+
#define HELP_VSD \
86+
" --vsd-values value tracking - constants|intervals|set-of-constants\n" /* NOLINT(whitespace/line_length) */ \
87+
" --vsd-structs struct field sensitive analysis - top-bottom|every-field\n" /* NOLINT(whitespace/line_length) */ \
88+
" --vsd-arrays array entry sensitive analysis - top-bottom|every-element\n" /* NOLINT(whitespace/line_length) */ \
89+
" --vsd-pointers pointer sensitive analysis - top-bottom|constants|value-set\n" /* NOLINT(whitespace/line_length) */ \
90+
" --vsd-unions union sensitive analysis - top-bottom\n" \
91+
" --vsd-flow-insensitive disables flow sensitivity\n" \
92+
" --vsd-data-dependencies track data dependencies\n" \
93+
94+
// cland-format on
95+
96+
#define PARSE_OPTIONS_VSD(cmdline, options) \
97+
options.set_option("values", cmdline.get_value("vsd-values")); \
98+
options.set_option("pointers", cmdline.get_value("vsd-pointers")); \
99+
options.set_option("arrays", cmdline.get_value("vsd-arrays")); \
100+
options.set_option("structs", cmdline.get_value("vsd-structs")); \
101+
options.set_option("unions", cmdline.get_value("vsd-unions")); \
102+
options.set_option("flow-insensitive", cmdline.isset("vsd-flow-insensitive")); /* NOLINT(whitespace/line_length) */ \
103+
options.set_option("data-dependencies", cmdline.isset("vsd-data-dependencies")); /* NOLINT(whitespace/line_length) */ \
104+
(void)0
105+
75106
class variable_sensitivity_domaint : public ai_domain_baset
76107
{
77108
public:

src/goto-analyzer/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ SRC = goto_analyzer_main.cpp \
77
static_show_domain.cpp \
88
static_simplifier.cpp \
99
static_verifier.cpp \
10+
build_analyzer.cpp \
1011
# Empty last line
1112

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

src/goto-analyzer/build_analyzer.cpp

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*******************************************************************\
2+
3+
Module: Goto-Analyzer Command Line Option Processing
4+
5+
Author: Martin Brain, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#include "build_analyzer.h"
10+
11+
#include <analyses/ai.h>
12+
#include <analyses/call_stack_history.h>
13+
#include <analyses/constant_propagator.h>
14+
#include <analyses/dependence_graph.h>
15+
#include <analyses/goto_check.h>
16+
#include <analyses/interval_domain.h>
17+
#include <analyses/is_threaded.h>
18+
#include <analyses/local_control_flow_history.h>
19+
#include <analyses/local_may_alias.h>
20+
#include <analyses/variable-sensitivity/three_way_merge_abstract_interpreter.h>
21+
#include <analyses/variable-sensitivity/variable_sensitivity_configuration.h>
22+
#include <analyses/variable-sensitivity/variable_sensitivity_dependence_graph.h>
23+
#include <analyses/variable-sensitivity/variable_sensitivity_domain.h>
24+
#include <analyses/variable-sensitivity/variable_sensitivity_object_factory.h>
25+
26+
#include <goto-programs/goto_model.h>
27+
28+
#include <util/namespace.h>
29+
#include <util/options.h>
30+
31+
/// Ideally this should be a pure function of options.
32+
/// However at the moment some domains require the goto_model or parts of it
33+
std::unique_ptr<ai_baset> build_analyzer(
34+
const optionst &options,
35+
const goto_modelt &goto_model,
36+
const namespacet &ns)
37+
{
38+
auto vsd_config = vsd_configt::from_options(options);
39+
auto vs_object_factory =
40+
variable_sensitivity_object_factoryt::configured_with(vsd_config);
41+
42+
// These support all of the option categories
43+
if(
44+
options.get_bool_option("recursive-interprocedural") ||
45+
options.get_bool_option("three-way-merge"))
46+
{
47+
// Build the history factory
48+
std::unique_ptr<ai_history_factory_baset> hf = nullptr;
49+
if(options.get_bool_option("ahistorical"))
50+
{
51+
hf = util_make_unique<
52+
ai_history_factory_default_constructort<ahistoricalt>>();
53+
}
54+
else if(options.get_bool_option("call-stack"))
55+
{
56+
hf = util_make_unique<call_stack_history_factoryt>(
57+
options.get_unsigned_int_option("call-stack-recursion-limit"));
58+
}
59+
else if(options.get_bool_option("local-control-flow-history"))
60+
{
61+
hf = util_make_unique<local_control_flow_history_factoryt>(
62+
options.get_bool_option("local-control-flow-history-forward"),
63+
options.get_bool_option("local-control-flow-history-backward"),
64+
options.get_unsigned_int_option("local-control-flow-history-limit"));
65+
}
66+
67+
// Build the domain factory
68+
std::unique_ptr<ai_domain_factory_baset> df = nullptr;
69+
if(options.get_bool_option("constants"))
70+
{
71+
df = util_make_unique<
72+
ai_domain_factory_default_constructort<constant_propagator_domaint>>();
73+
}
74+
else if(options.get_bool_option("intervals"))
75+
{
76+
df = util_make_unique<
77+
ai_domain_factory_default_constructort<interval_domaint>>();
78+
}
79+
else if(options.get_bool_option("vsd"))
80+
{
81+
df = util_make_unique<variable_sensitivity_domain_factoryt>(
82+
vs_object_factory, vsd_config);
83+
}
84+
// non-null is not fully supported, despite the historical options
85+
// dependency-graph is quite heavily tied to the legacy-ait infrastructure
86+
// dependency-graph-vs is very similar to dependency-graph
87+
88+
// Build the storage object
89+
std::unique_ptr<ai_storage_baset> st = nullptr;
90+
if(options.get_bool_option("one-domain-per-history"))
91+
{
92+
st = util_make_unique<history_sensitive_storaget>();
93+
}
94+
else if(options.get_bool_option("one-domain-per-location"))
95+
{
96+
st = util_make_unique<location_sensitive_storaget>();
97+
}
98+
99+
// Only try to build the abstract interpreter if all the parts have been
100+
// correctly specified and configured
101+
if(hf != nullptr && df != nullptr && st != nullptr)
102+
{
103+
if(options.get_bool_option("recursive-interprocedural"))
104+
{
105+
return util_make_unique<ai_recursive_interproceduralt>(
106+
std::move(hf), std::move(df), std::move(st));
107+
}
108+
else if(options.get_bool_option("three-way-merge"))
109+
{
110+
// Only works with VSD
111+
if(options.get_bool_option("vsd"))
112+
{
113+
return util_make_unique<ai_three_way_merget>(
114+
std::move(hf), std::move(df), std::move(st));
115+
}
116+
}
117+
}
118+
}
119+
else if(options.get_bool_option("legacy-ait"))
120+
{
121+
if(options.get_bool_option("constants"))
122+
{
123+
// constant_propagator_ait derives from ait<constant_propagator_domaint>
124+
return util_make_unique<constant_propagator_ait>(
125+
goto_model.goto_functions);
126+
}
127+
else if(options.get_bool_option("dependence-graph"))
128+
{
129+
return util_make_unique<dependence_grapht>(ns);
130+
}
131+
else if(options.get_bool_option("dependence-graph-vs"))
132+
{
133+
return util_make_unique<variable_sensitivity_dependence_grapht>(
134+
goto_model.goto_functions, ns, vs_object_factory, vsd_config);
135+
}
136+
else if(options.get_bool_option("vsd"))
137+
{
138+
auto df = util_make_unique<variable_sensitivity_domain_factoryt>(
139+
vs_object_factory, vsd_config);
140+
return util_make_unique<ait<variable_sensitivity_domaint>>(std::move(df));
141+
}
142+
else if(options.get_bool_option("intervals"))
143+
{
144+
return util_make_unique<ait<interval_domaint>>();
145+
}
146+
#if 0
147+
// Not actually implemented, despite the option...
148+
else if(options.get_bool_option("non-null"))
149+
{
150+
return util_make_unique<ait<non_null_domaint> >();
151+
}
152+
#endif
153+
}
154+
else if(options.get_bool_option("legacy-concurrent"))
155+
{
156+
#if 0
157+
// Very few domains can work with this interpreter
158+
// as it requires that changes to the domain are
159+
// 'non-revertable' and it has merge shared
160+
if(options.get_bool_option("dependence-graph"))
161+
{
162+
return util_make_unique<dependence_grapht>(ns);
163+
}
164+
#endif
165+
}
166+
167+
// Construction failed due to configuration errors
168+
return nullptr;
169+
}

src/goto-analyzer/build_analyzer.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*******************************************************************\
2+
3+
Module: Goto-Analyzer Command Line Option Processing
4+
5+
Author: Martin Brain, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#ifndef CPROVER_GOTO_ANALYZER_BUILD_ANALYZER_H
10+
#define CPROVER_GOTO_ANALYZER_BUILD_ANALYZER_H
11+
12+
#include <memory>
13+
14+
class ai_baset;
15+
class goto_modelt;
16+
class namespacet;
17+
class optionst;
18+
19+
/// Build an abstract interpreter configured by the options.
20+
/// This may require options for:
21+
/// * which interpreter to use
22+
/// * which history to use
23+
/// * which storage to use
24+
/// * which domain to use
25+
/// * how that domain is configured
26+
/// Not every combination of options is supported.
27+
/// Unsupported options will give null.
28+
/// Domains also may throw a invalid_command_line_argument_exceptiont
29+
std::unique_ptr<ai_baset> build_analyzer(
30+
const optionst &options,
31+
const goto_modelt &goto_model,
32+
const namespacet &ns);
33+
34+
#endif // CPROVER_GOTO_ANALYZER_GOTO_ANALYZER_PARSE_OPTIONS_H

0 commit comments

Comments
 (0)