-
Notifications
You must be signed in to change notification settings - Fork 277
CONTRACTS: Populate function name in source locations #7037
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
Conversation
@nwetzler The failing tests still need looking at. |
src/ansi-c/c_typecheck_base.cpp
Outdated
@@ -674,6 +674,28 @@ void c_typecheck_baset::apply_asm_label( | |||
} | |||
} | |||
|
|||
/// Recursively set function name in source locations of expression |
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.
Would it not be better to set the function name when parsing the contract?
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.
Remi and I were under the impression that the function name doesn't exist or isn't readily available at parsing time. This is because the function doesn't fully exist until the body has been parsed. If it is possible during parsing, that would be a better solution, but I didn't see a way to make it happen.
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.
You've got the function name once the declarator has been seen; this is well before the contract.
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.
@kroening I've now changed this in the parser and have removed changes from type-checking. The parser will now set the function in source location, but only for top-level functions. I think this change results in the correct behavior and excludes problems introduced by function pointers.
f5cadb0
to
3880b98
Compare
I've updated the contract tests to include the function name in regular expressions. |
Codecov Report
@@ Coverage Diff @@
## develop #7037 +/- ##
========================================
Coverage 77.87% 77.87%
========================================
Files 1574 1574
Lines 181163 181180 +17
========================================
+ Hits 141072 141089 +17
Misses 40091 40091
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
3880b98
to
9f92553
Compare
43be30c
to
6a8c9a6
Compare
ca619bf
to
1b168d1
Compare
During parsing of function parameters, the function name should be set in the source location, but only for top-level function declarations and definitions. In addition, function contracts should be only allowed for top-level function declarations and definitions. CBMC Viewer reports a failure when analyzing the incomplete coverage report, causing the CMBC Starter Kit to fail during a standard build. Also removed source location from "end function" command during contract checking and added proper source location to function contract instrumentation. Resolves issues diffblue#7032, diffblue#7070
1b168d1
to
83abf73
Compare
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.
Thanks for those changes. I like it.
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.
LGTM, only minor comments.
-- | ||
Checks if function contracts can be attached to function pointers | ||
(with non-empty parameter lists) in function parameters. This should | ||
fail. Exit code 64 for Windows servers. |
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.
You don't need to include "Exit code 64 for Windows servers." in the description, the error code itself is self-explanatory.
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.
I felt better reminding myself why there are two acceptable exit codes. I'd like to keep the comment unless the 1 and 64 pattern is super common.
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.
The pattern is quite common as it appears in 118 test description, but there is no harm in leaving this reminder here as well.
int contract_in_global_scope = (PARSER.scopes.size() == 1); | ||
int contract_in_top_level_function_scope = (PARSER.scopes.size() == 2); |
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.
Could you explain the magic numbers 1
and 2
in the comment?
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.
I was hoping the long variable names, combined with the comment above, would be self-documenting. When we initialize the parser, we start by pushing a global scope onto the stack. (There's an invariant that we never have an empty scopes stack.) So a size of 1 means the stack only contains the global scope. A size of two means we must be in some top-level event like a function declaration or definition because we've pushed something else on the stack.
// Set function name (last declarator) in source location | ||
// before parsing function contracts. Only do this if we | ||
// are at a global scope. | ||
if (PARSER.current_scope().prefix.empty()) { |
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.
@kroening is there a better way to check if we are at a global scope?
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.
I borrowed this methodology from the add_declarator
function in ansi_c_parser.cpp
:
// global?
if(current_scope().prefix.empty())
ansi_c_declaration.set_is_global(true);
I had originally written something like:
if (PARSER.current_scope() == PARSER.root_scope())
But there's no equality comparator defined for the scope class.
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.
Thanks! LGTM
During parsing of function parameters, the function name should be set
in the source location, but only for top-level function declarations
and definitions. In addition, function contracts should be only
allowed for top-level function declarations and definitions.
CBMC Viewer reports a failure when analyzing the incomplete coverage
report, causing the CMBC Starter Kit to fail during a standard build.
Also removed source location from "end function" command during
contract checking and added proper source location to function
contract instrumentation.
Resolves issues #7032, #7070