-
Notifications
You must be signed in to change notification settings - Fork 1.8k
C++: Switch to the shared Guards library #20485
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: main
Are you sure you want to change the base?
Conversation
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.
Pull Request Overview
This PR switches the C++ CodeQL library from its own guards library to the shared guards library that was introduced previously. The main purpose is to reduce C++-specific QL code maintenance and enable C++ to use the shared "nullness" library. This change also improves query results on existing queries, particularly reducing false positives in the cpp/missing-check-scanf
query.
Key changes include:
- Replacing the old C++-specific guards implementation with the shared guards library
- Updating guard value types from
AbstractValue
toGuardValue
- Making guards extend
Element
instead ofExpr
to support parameters as guards - Improving the guards logic to provide better query results
Reviewed Changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
GuardsEnsure.expected | Updated test expectations showing improved guard inference with more comprehensive results |
GuardsControl.ql | Changed parameter type from AbstractValue to GuardValue |
GuardsControl.expected | Expanded test results with additional guard control relationships |
GuardsCompare.ql | Updated parameter type from AbstractValue to GuardValue |
GuardsCompare.expected | Extended comparison results with more comprehensive guard comparisons |
Guards.ql | Removed simple guard selection query |
Guards.expected | Removed corresponding test expectations |
tests.ql | Updated parameter types to use GuardValue |
TOCTOUFilesystemRace.ql | Fixed guard child access by casting to Expr |
SSLResultConflation.ql | Fixed guard child access by casting to Expr |
SemanticExprSpecific.qll | Updated method call from controlsEdge to controlsBranchEdge |
Instruction.qll | Added getAnInput() method to BinaryInstruction |
EdgeKind.qll | Enhanced switch edge handling with better value range support |
SsaImpl.qll | Major updates to SSA implementation with improved guard integration |
IRGuards.qll | Complete rewrite using shared guards library with expanded functionality |
RangeAnalysis.qll | Updated method call to use controlsBranchEdge |
} | ||
|
||
private import semmle.code.cpp.dataflow.new.DataFlow::DataFlow as DataFlow | ||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as Private |
Check warning
Code scanning / CodeQL
Names only differing by case Warning
…nIndirectUse'. This will solve a non-monotonic recursion issue later.
…rk after instantiating the shared guards library.
c99ab52
to
6fe3e83
Compare
… a guard condition.
No. Parameters can't be Guards. But |
Oh. I guess there's a subtle thing for C/C++ here then: In the IR world a parameter is an Is that ... bad? |
6fe3e83
to
c481be8
Compare
No, I guess that's actually completely fine - I just didn't expect it. That just represents the initial value of the parameter, and pretty much anything with a value can be a guard. I just generally expected the ast nodes that could have a value (and could be assigned to a variable) to be expressions. |
Sure, I'll take a look (not today, though). |
This PR switches C/C++ away from our own guards library and over to the shared guards library which was introduced in #19573.
The main motivation for this is two-fold: It reduces the amount of C/C++ specific QL code that needs to be maintained 1. It also enables C/C++ to instantiate the newly shared "nullness" library which was introduced in #20367. This should hopefully open the doors to better null dereference / use-after-free / double free queries.
On top of that, the improvements to the internal guards logic also means much better query results on existing queries. In particular, the
cpp/missing-check-scanf
query has lost a tons of FPs 🎉.Commit-by-commit review extremely recommended. It's a large PR, but I actually think I managed to make it fairly reviewable 🤞.
This PR does bring a syntactic breaking changes which was just decided a couple of weeks ago would be okay for CodeQL going forward. The breaking change is that the AST wrapper around the IR-based guards library now extends
Element
instead ofExpr
. This is because the shared library also infers thatParameter
s (which are notExpr
s in the AST) can be guards if the parameter determines a condition.In fact, whereas the old library only made the condition (and certain subexpressions inside the condition) were
Guard
s, the new library makes every expression aGuard
, but only some of thoseGuard
s actually controls conditions. This is a fundamental difference that's always been between the C/C++ guards library and the Java/C# guards library, and we're finally getting rid of that difference which brings some more language consistency 🎉.Footnotes
Although, there is still lots of maintenance required because C/C++ still relies on our own implication of
ensuresEq
andensuresLt
. Getting rid of those requires switching C/C++ fully over to the shared range analysis library. ↩