Re-architecture of safe-buffers gadgets to re-classify them as warning and fixable
gadgets. The warning gadgets identify unsafe operations on buffer variables and
emit suitable warnings. While the fixable gadgets consider all operations on
variables identified by the warning gadgets and emit necessary fixits.
Differential Revision: https://reviews.llvm.org/D140062?id=486625
This reverts commit 22df4549a3718dcd8b387ba8246978349e4be50c.
After a quick investigation, realizing that the Sanitizer test
failures caused by this patch is not likely to block other
contributors. I re-land this patch before taking a closer look at
those tests so that it won't block the [-Wunsafe-buffer-usage]
development.
This reverts commit ef47a0a711f12add401394f7af07a0b4d1635b56.
Revert "[-Wunsafe-buffer-usage] Add a new `forEachDescendant` matcher that skips callable declarations"
This reverts commit b2ac5fd724c44cf662caed84bd8f84af574b981d.
This patch is causing failure in some Sanitizer tests
(https://lab.llvm.org/buildbot/#/builders/5/builds/30522/steps/13/logs/stdio). Reverting the patch and its' fix.
The original patch in commit b2ac5fd724c44cf662caed84bd8f84af574b981d
causes compilation errors which can be reproduced by the
`-fdelayed-template-parsing` flag. This commit fixes the problem.
Related differential revision: https://reviews.llvm.org/D138329
This reverts commit f58b025354ee2d3bcd7ab2399a11429ec940c1e0.
The previous revert reverts a patch that causes compilation problem on
windows which can be reproduced using `-fdelayed-template-parsing`.
I'm now to revert the patch back and commit a fix next.
For -Wunsafe-buffer-usage diagnostics, we want to warn about pointer
arithmetics since resulting pointers can be used to access buffers.
Therefore, I add an `UnsafeGadget` representing general pointer
arithmetic operations.
Reviewed by: NoQ
Differential revision: https://reviews.llvm.org/D139233
Note this is a change local to -Wunsafe-buffer-usage checks.
Add a new matcher `forEveryDescendant` that recursively matches
descendants of a `Stmt` but skips nested callable definitions. This
matcher has same effect as using `forEachDescendant` and skipping
`forCallable` explicitly but does not require the AST construction to be
complete.
Reviewed by: NoQ, xazax.hun
Differential revision: https://reviews.llvm.org/D138329
The assertion doesn't seem to hold due to ASTMatchers traversing code
inside GNU StmtExpr twice. This can screw up our algorithm's invariants.
We need a further investigation to properly fix this issue, but for now
let's avoid the crash.
Unsafe Buffer Usage analysis only warns unsafe buffer accesses but not
pointer dereferences. An array subscript on a literal zero is
equivalent to dereference a pointer thus we do not want to warn it.
Reviewed By: NoQ
Differential Revision: https://reviews.llvm.org/D138321
Generalize the pointer expression AST matcher in Unsafe Buffer Usage analysis.
Add test cases for various kinds of pointer usages.
Reviewed By: NoQ, aaron.ballman, xazax.hun
Differential Revision: https://reviews.llvm.org/D138318
This patch adds more abstractions that we'll need later for emitting
-Wunsafe-buffer-usage fixits. It doesn't emit any actual fixits,
so no change is observed behavior, but it introduces a way to emit fixits,
and existing tests now verify that the compiler still emits no fixits,
despite knowing how to do so.
The purpose of our code transformation analysis is to fix variable types
in the code from raw pointer types to C++ standard collection/view types.
The analysis has to decide on its own which specific type is
the most appropriate for every variable. This patch introduces
the Strategy class that maps variables to their most appropriate types.
In D137348 we've introduced the Gadget abstraction, which describes
a rigid AST pattern that the analysis "fully understands" and may need
to fix. Which specific fix is actually necessary for a given Gadget,
and whether it's necessary at all, and whether it's possible in the first place,
depends on the Strategy. So, this patch adds a virtual method which every
gadget can implement in order to teach the analysis how to fix that gadget:
Gadget->getFixits(Strategy)
However, even if the analysis knows how to fix every Gadget, doesn't
necessarily mean it can fix the variable. Some uses of the variable may have
never been covered by Gadgets, which corresponds to the situation that
the analysis doesn't fully understand how the variable is used. This patch
introduces a Tracker class that tracks all variable uses (i.e. DeclRefExprs)
in the function. Additionally, each Gadget now provides a new virtual method
Gadget->getClaimedVarUseSites()
that the Tracker can call to see which DeclRefExprs are "claimed" by the Gadget.
In order to fix the variable with a certain Strategy, the Tracker needs to
confirm that there are no unclaimed uses, and every Gadget has to provide
a fix for that Strategy.
This "conservative" behavior guarantees that fixes emitted by our analysis
are correct by construction. We can now be sure that the analysis won't
attempt to emit a fix if it doesn't understand the code. Later, as we implement
more getFixits() methods in individual Gadget classes, we'll start
progressively emitting more and more fixits.
Differential Revision: https://reviews.llvm.org/D138253
This patch introduces a hierarchy of Gadget classes, which are going to be
the core concept in the somewhat sophisticated machine behind the upcoming
-Wunsafe-buffer-usage fix-it hints.
A gadget is a rigid code pattern that constitutes an operation that
the fixit machine "understands" well enough to work with. A gadget may be
"unsafe" (i.e., constitute a raw buffer access) or "safe" (constitute
a use of a pointer or array variable that isn't unsafe per se,
but may need fixing if the participating variable changes type
to a safe container/view).
We'll be able to make decisions about how to fix the code depending on
the set of gadgets that we've enumerated. Basically, in order to fix a type
of a variable, each use of that variable has to participate in a gadget,
and each such gadget has to consent to fixing itself according to
the variable's new type.
Differential Revision: https://reviews.llvm.org/D137348
This is the initial commit for -Wunsafe-buffer-usage, a warning that helps
codebases (especially modern C++ codebases) transition away from raw buffer
pointers.
The warning is implemented in libAnalysis as it's going to become a non-trivial
analysis, mostly the fixit part where we try to figure out if we understand
a variable's use pattern well enough to suggest a safe container/view
as a replacement. Some parts of this analsysis may eventually prove useful
for any similar fixit machine that tries to change types of variables.
The warning is disabled by default.
RFC/discussion in https://discourse.llvm.org/t/rfc-c-buffer-hardening/65734
Differential Revision: https://reviews.llvm.org/D137346