Skip to content

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

Merged
merged 1 commit into from
Aug 17, 2022

Conversation

nwetzler
Copy link

@nwetzler nwetzler commented Jul 27, 2022

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

  • Each commit message has a non-empty body, explaining why the change was made.
  • Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
  • The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/
  • Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
  • My commit message includes data points confirming performance improvements (if claimed).
  • My PR is restricted to a single feature or bugfix.
  • White-space or formatting changes outside the feature-related changed lines are in commits of their own.

@tautschnig
Copy link
Collaborator

@nwetzler The failing tests still need looking at.

@@ -674,6 +674,28 @@ void c_typecheck_baset::apply_asm_label(
}
}

/// Recursively set function name in source locations of expression
Copy link
Member

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?

Copy link
Author

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.

Copy link
Member

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.

Copy link
Author

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.

@nwetzler nwetzler force-pushed the contract-coverage branch from f5cadb0 to 3880b98 Compare July 28, 2022 23:51
@nwetzler
Copy link
Author

@nwetzler The failing tests still need looking at.

I've updated the contract tests to include the function name in regular expressions.

@codecov
Copy link

codecov bot commented Aug 1, 2022

Codecov Report

Merging #7037 (83abf73) into develop (948994a) will increase coverage by 0.00%.
The diff coverage is 87.28%.

@@           Coverage Diff            @@
##           develop    #7037   +/-   ##
========================================
  Coverage    77.87%   77.87%           
========================================
  Files         1574     1574           
  Lines       181163   181180   +17     
========================================
+ Hits        141072   141089   +17     
  Misses       40091    40091           
Impacted Files Coverage Δ
jbmc/src/jbmc/jbmc_parse_options.cpp 75.88% <0.00%> (ø)
...variable-sensitivity/variable_sensitivity_domain.h 100.00% <ø> (ø)
.../analyses/variable-sensitivity/write_stack_entry.h 100.00% <ø> (ø)
src/ansi-c/ansi_c_typecheck.cpp 67.85% <0.00%> (ø)
src/ansi-c/expr2c_class.h 100.00% <ø> (ø)
src/cpp/cpp_typecheck.cpp 77.70% <0.00%> (ø)
src/goto-analyzer/goto_analyzer_parse_options.cpp 72.27% <ø> (ø)
src/goto-cc/armcc_cmdline.cpp 22.22% <ø> (ø)
src/goto-cc/gcc_cmdline.cpp 79.23% <ø> (ø)
src/goto-cc/ms_cl_cmdline.cpp 0.00% <ø> (ø)
... and 127 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@feliperodri feliperodri added bugfix aws Bugs or features of importance to AWS CBMC users Code Contracts Function and loop contracts labels Aug 11, 2022
@nwetzler nwetzler force-pushed the contract-coverage branch 2 times, most recently from 43be30c to 6a8c9a6 Compare August 15, 2022 19:47
@nwetzler nwetzler changed the title Populate function name in source locations for function contracts CONTRACTS: Populate function name in source locations Aug 15, 2022
@nwetzler nwetzler force-pushed the contract-coverage branch 2 times, most recently from ca619bf to 1b168d1 Compare August 16, 2022 01:14
@nwetzler nwetzler requested a review from jimgrundy August 16, 2022 01:17
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
Copy link
Collaborator

@jimgrundy jimgrundy left a 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.

Copy link
Collaborator

@feliperodri feliperodri left a 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.
Copy link
Collaborator

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.

Copy link
Author

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.

Copy link
Collaborator

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.

Comment on lines +3415 to +3416
int contract_in_global_scope = (PARSER.scopes.size() == 1);
int contract_in_top_level_function_scope = (PARSER.scopes.size() == 2);
Copy link
Collaborator

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?

Copy link
Author

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()) {
Copy link
Collaborator

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?

Copy link
Author

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.

Copy link
Contributor

@SaswatPadhi SaswatPadhi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aws Bugs or features of importance to AWS CBMC users bugfix Code Contracts Function and loop contracts
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants