Skip to content

Commit c359c35

Browse files
committed
Fix misleading error message for --generate-function-body on existing bodies
Previously, when the option was used with a function name that matched an existing function that already had a body, the error message incorrectly stated "No function name matched regex", which confused users into thinking their regex was wrong when in fact the function was found but had an existing body. The fix improves user experience by providing clear, actionable error messages that distinguish between: - Functions that don't match the provided regex - Functions that match the regex but already have bodies (and thus cannot have bodies generated) Fixes: #2974
1 parent 4fe3ade commit c359c35

File tree

8 files changed

+90
-16
lines changed

8 files changed

+90
-16
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
int generate_my_body();
2+
3+
int replace_my_body()
4+
{
5+
return 1;
6+
}
7+
8+
int main(void)
9+
{
10+
generate_my_body();
11+
replace_my_body();
12+
return 0;
13+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CORE
2+
main.c
3+
--generate-function-body replace_my_body --generate-function-body-options assert-false
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^WARNING: generate function bodies: Function\(s\) matched but already have bodies
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include <assert.h>
2+
3+
void generate_me();
4+
5+
void already_has_body()
6+
{
7+
assert(0);
8+
}
9+
10+
int main(void)
11+
{
12+
generate_me();
13+
already_has_body();
14+
return 0;
15+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
main.c
3+
--generate-function-body '.*' --generate-function-body-options assert-false
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
^\[generate_me.assertion.1\] .* undefined function should be unreachable: FAILURE$
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
int some_function()
2+
{
3+
return 1;
4+
}
5+
6+
int main(void)
7+
{
8+
some_function();
9+
return 0;
10+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CORE
2+
main.c
3+
--generate-function-body nonexistent_function --generate-function-body-options assert-false
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^WARNING: generate function bodies: No function name matched regex

src/goto-instrument/generate_function_bodies.cpp

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -510,30 +510,46 @@ void generate_function_bodies(
510510
messaget messages(message_handler);
511511
const std::regex cprover_prefix = std::regex("__CPROVER.*");
512512
bool did_generate_body = false;
513+
bool matched_function_with_body = false;
513514
for(auto &function : model.goto_functions.function_map)
514515
{
515-
if(
516-
!function.second.body_available() &&
517-
std::regex_match(id2string(function.first), functions_regex))
516+
if(std::regex_match(id2string(function.first), functions_regex))
518517
{
519-
if(std::regex_match(id2string(function.first), cprover_prefix))
518+
if(!function.second.body_available())
520519
{
521-
messages.warning() << "generate function bodies: matched function '"
522-
<< id2string(function.first)
523-
<< "' begins with __CPROVER "
524-
<< "the generated body for this function "
525-
<< "may interfere with analysis" << messaget::eom;
520+
if(std::regex_match(id2string(function.first), cprover_prefix))
521+
{
522+
messages.warning() << "generate function bodies: matched function '"
523+
<< id2string(function.first)
524+
<< "' begins with __CPROVER "
525+
<< "the generated body for this function "
526+
<< "may interfere with analysis" << messaget::eom;
527+
}
528+
did_generate_body = true;
529+
generate_function_body.generate_function_body(
530+
function.second, model.symbol_table, function.first);
531+
}
532+
else
533+
{
534+
matched_function_with_body = true;
526535
}
527-
did_generate_body = true;
528-
generate_function_body.generate_function_body(
529-
function.second, model.symbol_table, function.first);
530536
}
531537
}
532538
if(!did_generate_body && !ignore_no_match)
533539
{
534-
messages.warning()
535-
<< "generate function bodies: No function name matched regex"
536-
<< messaget::eom;
540+
if(matched_function_with_body)
541+
{
542+
messages.warning()
543+
<< "generate function bodies: Function(s) matched but already have "
544+
<< "bodies (body generation is only performed for functions without "
545+
<< "existing bodies)" << messaget::eom;
546+
}
547+
else
548+
{
549+
messages.warning()
550+
<< "generate function bodies: No function name matched regex"
551+
<< messaget::eom;
552+
}
537553
}
538554
}
539555

src/goto-instrument/generate_function_bodies.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ void generate_function_bodies(
9292

9393
#define HELP_REPLACE_FUNCTION_BODY \
9494
" {y--generate-function-body} {uregex} \t " \
95-
"generate bodies for functions matching {uregex}\n" \
95+
"generate bodies for functions matching {uregex} that do not already " \
96+
"have bodies\n" \
9697
" {y--generate-havocing-body} <option> " \
9798
"{ufun_name},{yparams}:{up1};{up2};.. \t " \
9899
"generate havocing body\n" \

0 commit comments

Comments
 (0)