Skip to content

Commit 1275983

Browse files
author
martin
committed
Convert --unreachable-instructions, --unreachable-functions and --reachable-functions
from specific to general tasks. If the options are given on their own then the specific version is used. If a domain is given as well then that is run and used to determine what is (un)reachable.
1 parent e936c50 commit 1275983

File tree

13 files changed

+424
-22
lines changed

13 files changed

+424
-22
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
../unreachable-instructions-basic-text/unreachable.c
3+
--reachable-functions --json -
4+
"function": "main",$
5+
"function": "dead_inside",$
6+
"function": "obviously_dead",$
7+
"function": "not_obviously_dead",$
8+
--
9+
^warning: ignoring
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
../unreachable-instructions-basic-text/unreachable.c
3+
--reachable-functions
4+
unreachable.c main 35 42$
5+
unreachable.c dead_inside 8 14$
6+
unreachable.c obviously_dead 16 23$
7+
unreachable.c not_obviously_dead 25 31$
8+
--
9+
^warning: ignoring
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
../unreachable-instructions-basic-text/unreachable.c
3+
--reachable-functions --constants
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
unreachable.c main 35 42$
7+
unreachable.c dead_inside 8 14$
8+
unreachable.c obviously_dead 16 23$
9+
unreachable.c not_obviously_dead 25 31$
10+
--
11+
^warning: ignoring
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
../unreachable-instructions-basic-text/unreachable.c
3+
--unreachable-functions --json -
4+
"file name": ".*unreachable.c",
5+
"first line": 3,
6+
"function": "not_called",
7+
"last line": 6
8+
--
9+
^warning: ignoring
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CORE
2+
../unreachable-instructions-basic-text/unreachable.c
3+
--unreachable-functions
4+
unreachable.c not_called 3 6$
5+
--
6+
^warning: ignoring
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
../unreachable-instructions-basic-text/unreachable.c
3+
--unreachable-functions --constants
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
unreachable.c not_called 3 6$
7+
--
8+
^warning: ignoring
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
CORE
2+
../unreachable-instructions-basic-text/unreachable.c
3+
--unreachable-instructions --json -
4+
"function": "not_called",
5+
"unreachableInstructions":
6+
"sourceLocation":
7+
"function": "not_called",
8+
"line": "5",
9+
"statement": "not_called#return_value = x \+ x;"
10+
"sourceLocation":
11+
"function": "not_called",
12+
"line": "5",
13+
"statement": "GOTO 1"
14+
"function": "dead_inside",
15+
"unreachableInstructions":
16+
"sourceLocation":
17+
"function": "dead_inside",
18+
"line": "12",
19+
"statement": "y = y \+ 1;"
20+
--
21+
^warning: ignoring
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CORE
2+
unreachable.c
3+
--unreachable-instructions
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
not_called
7+
// 28 file unreachable.c line 5 function not_called$
8+
not_called#return_value = x \+ x;$
9+
// 29 file unreachable.c line 5 function not_called$
10+
GOTO 1$
11+
dead_inside
12+
// 34 file unreachable.c line 12 function dead_inside$
13+
y = y \+ 1;$
14+
--
15+
^warning: ignoring
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include <assert.h>
2+
3+
int not_called(int x)
4+
{
5+
return x + x;
6+
}
7+
8+
int dead_inside(int x)
9+
{
10+
int y = x + x;
11+
goto end;
12+
++y;
13+
end : return y;
14+
}
15+
16+
int obviously_dead(int x)
17+
{
18+
if (0)
19+
{
20+
x++;
21+
}
22+
return x;
23+
}
24+
25+
int not_obviously_dead(int x)
26+
{
27+
if (dead_inside(x) != x + x) {
28+
x++;
29+
}
30+
return obviously_dead(x);
31+
}
32+
33+
int nondet_int(void);
34+
35+
int main(int argc, char **argv)
36+
{
37+
int x = 23;
38+
39+
assert(x == not_obviously_dead(x));
40+
41+
return;
42+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CORE
2+
../unreachable-instructions-basic-text/unreachable.c
3+
--unreachable-instructions --constants
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
not_called
7+
// 28 file unreachable.c line 5 function not_called$
8+
not_called#return_value = x \+ x;$
9+
// 29 file unreachable.c line 5 function not_called$
10+
GOTO 1$
11+
dead_inside
12+
// 34 file unreachable.c line 12 function dead_inside$
13+
y = y \+ 1;$
14+
obviously_dead
15+
// 40 file unreachable-instructions-basic-text/unreachable.c line 20 function obviously_dead
16+
x = x \+ 1;
17+
--
18+
^warning: ignoring

src/goto-analyzer/goto_analyzer_parse_options.cpp

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -146,20 +146,26 @@ void goto_analyzer_parse_optionst::get_command_line_options(optionst &options)
146146
options.set_option("taint", true);
147147
options.set_option("specific-analysis", true);
148148
}
149+
// For backwards compatibility,
150+
// these are first recognised as specific analyses
151+
bool reachability_task = false;
149152
if(cmdline.isset("unreachable-instructions"))
150153
{
151154
options.set_option("unreachable-instructions", true);
152155
options.set_option("specific-analysis", true);
156+
reachability_task = true;
153157
}
154158
if(cmdline.isset("unreachable-functions"))
155159
{
156160
options.set_option("unreachable-functions", true);
157161
options.set_option("specific-analysis", true);
162+
reachability_task = true;
158163
}
159164
if(cmdline.isset("reachable-functions"))
160165
{
161166
options.set_option("reachable-functions", true);
162167
options.set_option("specific-analysis", true);
168+
reachability_task = true;
163169
}
164170
if(cmdline.isset("show-local-may-alias"))
165171
{
@@ -244,7 +250,7 @@ void goto_analyzer_parse_optionst::get_command_line_options(optionst &options)
244250
options.set_option("general-analysis", true);
245251
}
246252

247-
if (options.get_bool_option("general-analysis"))
253+
if(options.get_bool_option("general-analysis") || reachability_task)
248254
{
249255
// Abstract interpreter choice
250256
if(cmdline.isset("location-sensitive"))
@@ -280,12 +286,24 @@ void goto_analyzer_parse_optionst::get_command_line_options(optionst &options)
280286
options.set_option("domain set", true);
281287
}
282288

283-
284-
if(!options.get_bool_option("domain set"))
289+
// Reachability questions, when given with a domain swap from specific
290+
// to general tasks so that they can use the domain & parameterisations.
291+
if(reachability_task)
285292
{
286-
// Deafult to constants as it is light-weight but useful
287-
status() << "Domain defaults to --constants" << eom;
288-
options.set_option("constants", true);
293+
if(options.get_bool_option("domain set"))
294+
{
295+
options.set_option("specific-analysis", false);
296+
options.set_option("general-analysis", true);
297+
}
298+
}
299+
else
300+
{
301+
if(!options.get_bool_option("domain set"))
302+
{
303+
// Default to constants as it is light-weight but useful
304+
status() << "Domain not specified, defaulting to --constants" << eom;
305+
options.set_option("constants", true);
306+
}
289307
}
290308
}
291309
}
@@ -468,7 +486,9 @@ int goto_analyzer_parse_optionst::perform_analysis(const optionst &options)
468486
}
469487
}
470488

471-
if(options.get_bool_option("unreachable-instructions"))
489+
// If no domain is given, this lightweight version of the analysis is used.
490+
if(options.get_bool_option("unreachable-instructions") &&
491+
options.get_bool_option("specific-analysis"))
472492
{
473493
const std::string json_file=cmdline.get_value("json");
474494

@@ -492,7 +512,8 @@ int goto_analyzer_parse_optionst::perform_analysis(const optionst &options)
492512
return 0;
493513
}
494514

495-
if(options.get_bool_option("unreachable-functions"))
515+
if(options.get_bool_option("unreachable-functions") &&
516+
options.get_bool_option("specific-analysis"))
496517
{
497518
const std::string json_file=cmdline.get_value("json");
498519

@@ -516,7 +537,8 @@ int goto_analyzer_parse_optionst::perform_analysis(const optionst &options)
516537
return 0;
517538
}
518539

519-
if(options.get_bool_option("reachable-functions"))
540+
if(options.get_bool_option("reachable-functions") &&
541+
options.get_bool_option("specific-analysis"))
520542
{
521543
const std::string json_file=cmdline.get_value("json");
522544

@@ -629,6 +651,30 @@ int goto_analyzer_parse_optionst::perform_analysis(const optionst &options)
629651
get_message_handler(),
630652
out);
631653
}
654+
else if(options.get_bool_option("unreachable-instructions"))
655+
{
656+
result = static_unreachable_instructions(goto_model,
657+
*analyzer,
658+
options,
659+
get_message_handler(),
660+
out);
661+
}
662+
else if(options.get_bool_option("unreachable-functions"))
663+
{
664+
result = static_unreachable_functions(goto_model,
665+
*analyzer,
666+
options,
667+
get_message_handler(),
668+
out);
669+
}
670+
else if(options.get_bool_option("reachable-functions"))
671+
{
672+
result = static_reachable_functions(goto_model,
673+
*analyzer,
674+
options,
675+
get_message_handler(),
676+
out);
677+
}
632678
else
633679
{
634680
error() << "Unhandled task" << eom;
@@ -774,6 +820,11 @@ void goto_analyzer_parse_optionst::help()
774820
" --verify use the abstract domains to check assertions\n"
775821
// NOLINTNEXTLINE(whitespace/line_length)
776822
" --simplify file_name use the abstract domains to simplify the program\n"
823+
" --unreachable-instructions list dead code\n"
824+
// NOLINTNEXTLINE(whitespace/line_length)
825+
" --unreachable-functions list functions unreachable from the entry point\n"
826+
// NOLINTNEXTLINE(whitespace/line_length)
827+
" --reachable-functions list functions reachable from the entry point\n"
777828
"\n"
778829
"Abstract interpreter options:\n"
779830
// NOLINTNEXTLINE(whitespace/line_length)
@@ -796,11 +847,6 @@ void goto_analyzer_parse_optionst::help()
796847
"Specific analyses:\n"
797848
// NOLINTNEXTLINE(whitespace/line_length)
798849
" --taint file_name perform taint analysis using rules in given file\n"
799-
" --unreachable-instructions list dead code\n"
800-
// NOLINTNEXTLINE(whitespace/line_length)
801-
" --unreachable-functions list functions unreachable from the entry point\n"
802-
// NOLINTNEXTLINE(whitespace/line_length)
803-
" --reachable-functions list functions reachable from the entry point\n"
804850
"\n"
805851
"C/C++ frontend options:\n"
806852
" -I path set include path (C/C++)\n"

0 commit comments

Comments
 (0)