Skip to content

Commit 99d8898

Browse files
committed
Add remove-function-body-regex command line option
This extends the existing `remove-function-body` option in `goto-instrument` with support for regular expressions to specify a broader set of functions.
1 parent 15b0003 commit 99d8898

File tree

7 files changed

+146
-3
lines changed

7 files changed

+146
-3
lines changed

doc/man/goto-instrument.1

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,10 @@ cbmc a.out
748748
\fB\-\-remove\-function\-body\fR \fIf\fR
749749
remove the implementation of function \fIf\fR (may be repeated)
750750
.TP
751+
\fB\-\-remove\-function\-body\-regex\fR \fIregex\fR
752+
remove the implementation of functions matching regular expression \fIregex\fR
753+
(may be repeated)
754+
.TP
751755
\fB\-\-replace\-calls\fR \fIf\fR:\fIg\fR
752756
replace calls to \fIf\fR with calls to \fIg\fR
753757
.TP
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <assert.h>
2+
3+
int foo123()
4+
{
5+
int a;
6+
assert(a > 0);
7+
return a;
8+
}
9+
10+
int foox()
11+
{
12+
int a;
13+
assert(a > 0);
14+
return a;
15+
}
16+
17+
int bar()
18+
{
19+
int b;
20+
assert(b > 0);
21+
return b;
22+
}
23+
24+
int main()
25+
{
26+
foo123();
27+
foox();
28+
bar();
29+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CORE
2+
main.c
3+
--remove-function-body-regex '^foo[0-9].*' --remove-function-body-regex '^bar$'
4+
^foox
5+
^EXIT=10$
6+
^SIGNAL=0$
7+
^\[main\.no-body\.foo123\] line 26 no body for callee foo123: FAILURE$
8+
^\[main\.no-body\.bar\] line 28 no body for callee bar: FAILURE$
9+
^VERIFICATION FAILED$
10+
--
11+
^warning: ignoring
12+
^bar
13+
^foo123

src/goto-instrument/goto_instrument_parse_options.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,14 @@ void goto_instrument_parse_optionst::instrument_goto_program()
10551055
ui_message_handler);
10561056
}
10571057

1058+
if(cmdline.isset("remove-function-body-regex"))
1059+
{
1060+
remove_functions_regex(
1061+
goto_model,
1062+
cmdline.get_values("remove-function-body-regex"),
1063+
ui_message_handler);
1064+
}
1065+
10581066
// we add the library in some cases, as some analyses benefit
10591067

10601068
if(
@@ -1960,8 +1968,10 @@ void goto_instrument_parse_optionst::help()
19601968
" {y--add-library} \t add models of C library functions\n"
19611969
HELP_CONFIG_LIBRARY
19621970
" {y--model-argc-argv} {un} \t model up to {un} command line arguments\n"
1963-
" {y--remove-function-body} {uf} remove the implementation of function {uf}"
1964-
" (may be repeated)\n"
1971+
" {y--remove-function-body} {uf} \t remove the implementation of function"
1972+
" {uf} (may be repeated)\n"
1973+
" {y--remove-function-body-regex} {uregex} \t remove the implementation of"
1974+
" functions matching regular expression {uregex} (may be repeated)\n"
19651975
HELP_REPLACE_CALLS
19661976
HELP_ANSI_C_LANGUAGE
19671977
"\n"

src/goto-instrument/goto_instrument_parse_options.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ Author: Daniel Kroening, [email protected]
110110
OPT_ENFORCE_CONTRACT_REC \
111111
"(show-threaded)(list-calls-args)" \
112112
"(undefined-function-is-assume-false)" \
113-
"(remove-function-body):"\
113+
"(remove-function-body):" \
114+
"(remove-function-body-regex):" \
114115
OPT_AGGRESSIVE_SLICER \
115116
OPT_FLUSH \
116117
"(splice-call):" \

src/goto-instrument/remove_function.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Date: April 2017
1717

1818
#include <goto-programs/goto_model.h>
1919

20+
#include <regex>
21+
2022
/// Remove the body of function "identifier" such that an analysis will treat it
2123
/// as a side-effect free function with non-deterministic return value.
2224
/// \par parameters: symbol_table Input symbol table to be modified
@@ -73,3 +75,78 @@ void remove_functions(
7375
for(const auto &f : names)
7476
remove_function(goto_model, f, message_handler);
7577
}
78+
79+
/// Remove functions matching a regular expression pattern
80+
/// \param goto_model: The goto model to modify
81+
/// \param pattern: The regex pattern to match function names against
82+
/// \param pattern_as_str: The string representation of \p pattern
83+
/// \param message_handler: For status/warning/error messages
84+
static void remove_functions_regex(
85+
goto_modelt &goto_model,
86+
const std::regex &pattern,
87+
const std::string &pattern_as_str,
88+
message_handlert &message_handler)
89+
{
90+
messaget message{message_handler};
91+
92+
message.debug() << "Removing functions matching pattern: " << pattern_as_str
93+
<< messaget::eom;
94+
95+
// Collect matching function names first to avoid modifying the map while
96+
// iterating
97+
std::list<irep_idt> matching_functions;
98+
99+
for(const auto &entry : goto_model.goto_functions.function_map)
100+
{
101+
const std::string &function_name = id2string(entry.first);
102+
if(std::regex_match(function_name, pattern))
103+
{
104+
matching_functions.push_back(entry.first);
105+
}
106+
}
107+
108+
// Now remove all matching functions
109+
for(const auto &func : matching_functions)
110+
{
111+
remove_function(goto_model, func, message_handler);
112+
}
113+
114+
message.debug() << "Removed " << matching_functions.size()
115+
<< " function(s) matching pattern: " << pattern_as_str
116+
<< messaget::eom;
117+
}
118+
119+
void remove_functions_regex(
120+
goto_modelt &goto_model,
121+
const std::list<std::string> &patterns,
122+
message_handlert &message_handler)
123+
{
124+
std::string combined_pattern;
125+
for(const auto &pattern : patterns)
126+
{
127+
if(pattern.empty())
128+
continue;
129+
if(!combined_pattern.empty())
130+
combined_pattern += '|';
131+
combined_pattern += pattern;
132+
}
133+
134+
if(combined_pattern.empty())
135+
return;
136+
137+
messaget message{message_handler};
138+
139+
try
140+
{
141+
std::regex regex_pattern{combined_pattern};
142+
143+
remove_functions_regex(
144+
goto_model, regex_pattern, combined_pattern, message_handler);
145+
}
146+
catch(const std::regex_error &e)
147+
{
148+
message.error() << "Invalid regular expression pattern: "
149+
<< combined_pattern << " (" << e.what() << ")"
150+
<< messaget::eom;
151+
}
152+
}

src/goto-instrument/remove_function.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,13 @@ void remove_functions(
3232
const std::list<std::string> &names,
3333
message_handlert &);
3434

35+
/// Remove functions matching any of the provided regular expression patterns.
36+
/// \param goto_model: The goto model to modify
37+
/// \param patterns: List of regex patterns to match function names against
38+
/// \param message_handler: For status/warning/error messages
39+
void remove_functions_regex(
40+
goto_modelt &goto_model,
41+
const std::list<std::string> &patterns,
42+
message_handlert &message_handler);
43+
3544
#endif // CPROVER_GOTO_INSTRUMENT_REMOVE_FUNCTION_H

0 commit comments

Comments
 (0)