-
Notifications
You must be signed in to change notification settings - Fork 67
M14-6-1: Address performance problems and restrict scope #205
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
The rule specifically only refers to dependent base types of class templates.
The query didn't explicitly enforce this condition, and instead relied on the fact that NameQualifiableElement's without any qualifier would only point to the "wrong" element within templates. However, there are some edge cases (static member functions with overrides) where non-class templates could be flagged. This commit restricts the output to the set of template classes with dependent base types, therefore avoiding the sort of false positives seen above. In addition, this improves performance for this query because the set of template classes with dependent base types is much much much smaller than the overall set of base types.
Push the dependent type context into the individual determination of contravening cases to work towards addressing performance issues.
Previously the logic of this query asserted that the function call did not target the selected function in the dependent base type with the same name. In theory this is wrong, as overloading can permit multiple functions declarations with the same name, but different signatures, so we now say that the target is not declared on the same base type. In practice, such results would be excluded because to call an overload of the same function would always have a qualifier in this case, however this logic makes the intention clearer.
Performance issues occurred because we are trying to find pairs of functions or variables which have the same name but are not the same. The join orderer is very keen on joining two copies of the function/ variable table early on which, on large databases like openpilot with a lot of name duplication, can cause signficant blow-up. The workaround is to provide helper predicates that ensure the restricted set of functions/variables we care about (targets of accesses or calls in templates with dependent base types) are computed first, then the name is joined with a member on the dependent base type.
Improve the alert message to include: - The name of the identifier - A link to the target of the use of the identifier - A link to the dependent base type member with the same name.
Access of a local scope variable shadowing a dependent base member is not a case with confusing behaviour - the local scope variable would be expected to be the target.
🤖 Beep Boop! Matrix Testing for this PR has been initiated. Please check back later for results. |
1 similar comment
🤖 Beep Boop! Matrix Testing for this PR has been initiated. Please check back later for results. |
🤖 Beep Boop! clang/c/x86_64 Matrix Testing for this PR has been completed but I didn't find anything to test! |
🤖 Beep Boop! clang/cpp/x86_64 Matrix Testing for this PR has been completed. See below for the results!
|
🤖 Beep Boop! clang/c/x86_64 Matrix Testing for this PR has been completed but I didn't find anything to test! |
🤖 Beep Boop! clang/cpp/x86_64 Matrix Testing for this PR has been completed. See below for the results!
|
🤖 Beep Boop! gcc/cpp/x86_64 Matrix Testing for this PR has been completed. See below for the results!
|
🤖 Beep Boop! gcc/c/x86_64 Matrix Testing for this PR has been completed but I didn't find anything to test! |
🤖 Beep Boop! Matrix Testing for this PR has been completed. If no reports were posted it means this PR does not contain things that need matrix testing! |
/test-performance |
🏁 Beep Boop! Performance testing for this PR has been initiated. Please check back later for results. Note that the query package generation step must complete before testing will start so it might be a minute. |
🏁 Beep Boop! Performance testing complete! See below for performance of the last 3 runs vs your PR. Times are based on predicate performance. You can find full graphs and stats in the PR that was created for this test in the release engineering repo.
🏁 Below are the slowest predicates for the last 2 releases vs this PR.
|
Performance testing above shows that overall time for the The slowest set of predicates in the last release show |
* Formatting * Address compiler testing issues - Accidental name conflicts - Type of member function parameter
🤖 Beep Boop! Matrix Testing for this PR has been initiated. Please check back later for results. |
🤖 Beep Boop! clang/cpp/x86_64 Matrix Testing for this PR has been completed. See below for the results!
|
🤖 Beep Boop! clang/c/x86_64 Matrix Testing for this PR has been completed but I didn't find anything to test! |
🤖 Beep Boop! gcc/cpp/x86_64 Matrix Testing for this PR has been completed. See below for the results!
|
🤖 Beep Boop! Matrix Testing for this PR has been completed. If no reports were posted it means this PR does not contain things that need matrix testing! |
🤖 Beep Boop! Matrix Testing for this PR has been initiated. Please check back later for results. |
🤖 Beep Boop! clang/c/x86_64 Matrix Testing for this PR has been completed but I didn't find anything to test! |
🤖 Beep Boop! gcc/c/x86_64 Matrix Testing for this PR has been completed but I didn't find anything to test! |
🤖 Beep Boop! clang/cpp/x86_64 Matrix Testing for this PR has been completed. See below for the results!
|
🤖 Beep Boop! gcc/cpp/x86_64 Matrix Testing for this PR has been completed. See below for the results!
|
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.
just a few minor improvement suggestions!
otherwise, absolutely perfect! 🎉
haha wish I could say that Ive learned to now identify when a join is happening on some names first and creating a huge initial state space but... we shall see! 😅
To take a pointer to a member function we need to provide a qualifier to the name. The cases in the COMPLIANT classes are therefore non-compilable. The reason some cases were not previously causing EDG to crash was that the templates weren't instantiated. We now instantiate all templates, and add explanatory comments.
🤖 Beep Boop! Matrix Testing for this PR has been initiated. Please check back later for results. |
1 similar comment
🤖 Beep Boop! Matrix Testing for this PR has been initiated. Please check back later for results. |
🤖 Beep Boop! gcc/c/x86_64 Matrix Testing for this PR has been completed but I didn't find anything to test! |
🤖 Beep Boop! clang/c/x86_64 Matrix Testing for this PR has been completed but I didn't find anything to test! |
🤖 Beep Boop! gcc/c/x86_64 Matrix Testing for this PR has been completed but I didn't find anything to test! |
🤖 Beep Boop! clang/c/x86_64 Matrix Testing for this PR has been completed but I didn't find anything to test! |
🤖 Beep Boop! gcc/cpp/x86_64 Matrix Testing for this PR has been completed. See below for the results!
|
🤖 Beep Boop! clang/cpp/x86_64 Matrix Testing for this PR has been completed. See below for the results!
|
🤖 Beep Boop! clang/cpp/x86_64 Matrix Testing for this PR has been completed. See below for the results!
|
🤖 Beep Boop! gcc/cpp/x86_64 Matrix Testing for this PR has been completed. See below for the results!
|
🤖 Beep Boop! Matrix Testing for this PR has been completed. If no reports were posted it means this PR does not contain things that need matrix testing! |
1 similar comment
🤖 Beep Boop! Matrix Testing for this PR has been completed. If no reports were posted it means this PR does not contain things that need matrix testing! |
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 addressing those comments! looks good!
Description
Fixes #192.
This PR fixes a real world performance issue in this query, that was also raised by our integration performance testing on openpilot.
The problem is in the
NameInDependentBase::parentMemberFunctionCall
predicate:The intention of the predicate is to find function calls where the target of the function could be confused with a member declaration in a dependent base type. The key performance problems were:
child
andparent
, which means we could be reporting any member function with the same name.other.getName() = parentFunction.getName()
early on, which essentially creates cross-product on all functions with the same name. This causes issues on databases with a lot of name duplication across classes (such as in openpilot, and typically in projects with lots of generated code).The solution is to (a) push more context into the predicate and (b) create a helper predicate to ensure the join orderer evaluates the context prior to trying to match on function names.
I recommend a commit-wise review, with the following highlights:
template<typename T> class A : B<T>
. This is because the name lookup rules are different in this case, which is what can cause developer confusion. We now apply this restriction explicitly in the query - previously, the query mostly worked (apart from an edge case around static members) because the condition (unqualified name uses where the target is outside the class and the parent class declares the same name) could only occur in templates. However, applying the explicit restriction (a) makes it clearer the query is doing the "right" thing and (b) allows us to push more context into the predicate to avoid performance issues. This will also improve results in the case that a template has multiple instantiations - previously it would have reported one alert per instantiation per use, but now reports one alert per template class per use.child
/parent
context from the query into theparentMemberFunctionCall
and similar predicates in the same file. This improves performance substantially, but does not fully solve the problem.@knewbury01 I'm assigning this to you as you originally wrote the query.
Change request type
.ql
,.qll
,.qls
or unit tests)Rules with added or modified queries
Release change checklist
A change note (development_handbook.md#change-notes) is required for any pull request which modifies:
If you are only adding new rule queries, a change note is not required.
Author: Is a change note required?
🚨🚨🚨
Reviewer: Confirm that format of shared queries (not the .qll file, the
.ql file that imports it) is valid by running them within VS Code.
Reviewer: Confirm that either a change note is not required or the change note is required and has been added.
Query development review checklist
For PRs that add new queries or modify existing queries, the following checklist should be completed by both the author and reviewer:
Author
As a rule of thumb, predicates specific to the query should take no more than 1 minute, and for simple queries be under 10 seconds. If this is not the case, this should be highlighted and agreed in the code review process.
Reviewer
As a rule of thumb, predicates specific to the query should take no more than 1 minute, and for simple queries be under 10 seconds. If this is not the case, this should be highlighted and agreed in the code review process.