Skip to content

Commit 248f23a

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 248f23a

File tree

7 files changed

+138
-1
lines changed

7 files changed

+138
-1
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\.foo\] line 19 no body for callee foo123: FAILURE$
8+
^\[main\.no-body\.bar\] line 21 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: 10 additions & 0 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(
@@ -1962,6 +1970,8 @@ void goto_instrument_parse_optionst::help()
19621970
" {y--model-argc-argv} {un} \t model up to {un} command line arguments\n"
19631971
" {y--remove-function-body} {uf} remove the implementation of function {uf}"
19641972
" (may be repeated)\n"
1973+
" {y--remove-function-body-regex} {uregex} 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: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,74 @@ void remove_functions(
7373
for(const auto &f : names)
7474
remove_function(goto_model, f, message_handler);
7575
}
76+
77+
/// Remove functions matching a regular expression pattern
78+
/// \param goto_model: The goto model to modify
79+
/// \param pattern: The regex pattern to match function names against
80+
/// \param message_handler: For status/warning/error messages
81+
static void remove_functions_regex(
82+
goto_modelt &goto_model,
83+
const std::regex &pattern,
84+
message_handlert &message_handler)
85+
{
86+
messaget message{message_handler};
87+
88+
message.debug() << "Removing functions matching pattern: " << pattern
89+
<< messaget::eom;
90+
91+
// Collect matching function names first to avoid modifying the map while iterating
92+
std::list<irep_idt> matching_functions;
93+
94+
for(const auto &entry : goto_model.goto_functions.function_map)
95+
{
96+
const std::string &function_name = id2string(entry.first);
97+
if(std::regex_match(function_name, pattern))
98+
{
99+
matching_functions.push_back(entry.first);
100+
}
101+
}
102+
103+
// Now remove all matching functions
104+
for(const auto &func : matching_functions)
105+
{
106+
remove_function(goto_model, func, message_handler);
107+
}
108+
109+
message.debug() << "Removed " << matching_functions.size()
110+
<< " function(s) matching pattern: " << pattern
111+
<< messaget::eom;
112+
}
113+
114+
void remove_functions_regex(
115+
goto_modelt &goto_model,
116+
const std::list<std::string> &patterns,
117+
message_handlert &message_handler)
118+
{
119+
std::string combined_pattern;
120+
for(const auto &pattern : patterns)
121+
{
122+
if(pattern.empty())
123+
continue;
124+
if(!combined_pattern.empty())
125+
combined_pattern += '|';
126+
combined_pattern += pattern;
127+
}
128+
129+
if(combined_pattern.empty())
130+
return;
131+
132+
messaget message{message_handler};
133+
134+
try
135+
{
136+
std::regex regex_pattern{combined_pattern};
137+
138+
remove_functions_regex(goto_model, regex_pattern, message_handler);
139+
}
140+
catch(const std::regex_error &e)
141+
{
142+
message.error() << "Invalid regular expression pattern: "
143+
<< combined_pattern << " (" << e.what() << ")"
144+
<< messaget::eom;
145+
}
146+
}

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)