-
Notifications
You must be signed in to change notification settings - Fork 273
DFCC instrumentation: skip unused functions #8628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
DFCC instrumentation: skip unused functions #8628
Conversation
Do not attempt to instrument functions that will never be used anyway. As we eventually use `remove_unused_functions` there is no point in trying to instrument them, and there is a scenario where the function may not have been compiled (see included test).
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #8628 +/- ##
========================================
Coverage 80.37% 80.37%
========================================
Files 1686 1686
Lines 206872 206877 +5
Branches 73 73
========================================
+ Hits 166265 166271 +6
+ Misses 40607 40606 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
@@ -272,7 +278,7 @@ void dfcct::partition_function_symbols( | |||
{ | |||
contract_symbols.insert(sym_name); | |||
} | |||
else | |||
else if(called_functions.find(sym_name) != called_functions.end()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the program uses function pointers find_used_functions
is not guaranteed to discover all reachable functions. Moreover users can expand function pointer calls after contract instrumentation, so we should at least inject assert(false);assume(false)
sentinel instructions in the functions we skip.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But then we use use remove_unused_functions afterwards, which itself uses
find_used_functions` to determine which functions to remove, so I wouldn't know how users would do something after contract instrumentation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still not convinced we are totally sound. CBMC removes function pointers very late, right before the analysis, so if we remove functions that we think are unused, but could have been used as a target due to their signature, wouldn't we create a change in semantics for function pointers between contracts and basic symex ?
What about a case like this one ? Would intfun_contract
still be considered used ?
Does find_used_functions
consider a function used if its address is taken and assigned to a function pointer variable (e.g. intfun bar = baz;
)?
typedef int (*intfun)(int);
intfun __VERIFIER_nondet_intfun();
int intfun_contract(int x)
__CPROVER_requires(-12 <= x && x <= 12)
__CPROVER_ensures(__CPROVER_return_value == 2*x)
;
int foo(intfun bar)
__CPROVER_requires(__CPROVER_obeys_contract(bar, intfun_contract))
__CPROVER_ensures(__CPROVER_return_value == 24)
{
return bar(12);
}
Do not attempt to instrument functions that will never be used anyway. As we eventually use
remove_unused_functions
there is no point in trying to instrument them, and there is a scenario where the function may not have been compiled (see included test).