Currently, parameters of functions without their definition present cannot
be represented as regions because it would be difficult to ensure that the
same declaration is used in every case. To overcome this, we split
`VarRegion` to two subclasses: `NonParamVarRegion` and `ParamVarRegion`.
The latter does not store the `Decl` of the parameter variable. Instead it
stores the index of the parameter which enables retrieving the actual
`Decl` every time using the function declaration of the stack frame. To
achieve this we also removed storing of `Decl` from `DeclRegion` and made
`getDecl()` pure virtual. The individual `Decl`s are stored in the
appropriate subclasses, such as `FieldRegion`, `ObjCIvarRegion` and the
newly introduced `NonParamVarRegion`.
Differential Revision: https://reviews.llvm.org/D80522
Summary:
I wanted to extend the diagnostics of the CStringChecker with taintedness.
This requires the CStringChecker to be refactored to support a more flexible
reporting mechanism.
This patch does only refactorings, such:
- eliminates always false parameters (like WarnAboutSize)
- reduces the number of parameters
- makes strong types differentiating *source* and *destination* buffers
(same with size expressions)
- binds the argument expression and the index, making diagnostics accurate
and easy to emit
- removes a bunch of default parameters to make it more readable
- remove random const char* warning message parameters, making clear where
and what is going to be emitted
Note that:
- CheckBufferAccess now checks *only* one buffer, this removed about 100 LOC
code duplication
- not every function was refactored to use the /new/ strongly typed API, since
the CString related functions are really closely coupled monolithic beasts,
I will refactor them separately
- all tests are preserved and passing; only the message changed at some places.
In my opinion, these messages are holding the same information.
I would also highlight that this refactoring caught a bug in
clang/test/Analysis/string.c:454 where the diagnostic did not reflect reality.
This catch backs my effort on simplifying this monolithic CStringChecker.
Reviewers: NoQ, baloghadamsoftware, Szelethus, rengolin, Charusso
Reviewed By: NoQ
Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin,
mikhail.ramalho, donat.nagy, dkrupp, Charusso, martong, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D74806
Some checkers may not only depend on language options but also analyzer options.
To make this possible this patch changes the parameter of the shouldRegister*
function to CheckerManager to be able to query the analyzer options when
deciding whether the checker should be registered.
Differential Revision: https://reviews.llvm.org/D75271
Summary:
This patch introduces a placeholder for representing the dynamic size of
regions. It also moves the `getExtent()` method of `SubRegions` to the
`MemRegionManager` as `getStaticSize()`.
Reviewed By: NoQ
Differential Revision: https://reviews.llvm.org/D69540
While analyzing code `memcmp(a, NULL, n);', where `a' has an unconstrained
symbolic value, the analyzer was emitting a warning about the *first* argument
being a null pointer, even though we'd rather have it warn about the *second*
argument.
This happens because CStringChecker first checks whether the two argument
buffers are in fact the same buffer, in order to take the fast path.
This boils down to assuming `a == NULL' to true. Then the subsequent check
for null pointer argument "discovers" that `a' is null.
Don't take the fast path unless we are *sure* that the buffers are the same.
Otherwise proceed as normal.
Differential Revision: https://reviews.llvm.org/D71322
- Fix false positive reports of strlcat.
- The return value of strlcat and strlcpy is now correctly calculated.
- The resulting string length of strlcat and strlcpy is now correctly
calculated.
Patch by Daniel Krupp!
Differential Revision: https://reviews.llvm.org/D66049
Traditionally, clang-tidy uses the term check, and the analyzer uses checker,
but in the very early years, this wasn't the case, and code originating from the
early 2010's still incorrectly refer to checkers as checks.
This patch attempts to hunt down most of these, aiming to refer to checkers as
checkers, but preserve references to callback functions (like checkPreCall) as
checks.
Differential Revision: https://reviews.llvm.org/D67140
llvm-svn: 371760
Checkers are now required to specify whether they're creating a
path-sensitive report or a path-insensitive report by constructing an
object of the respective type.
This makes BugReporter more independent from the rest of the Static Analyzer
because all Analyzer-specific code is now in sub-classes.
Differential Revision: https://reviews.llvm.org/D66572
llvm-svn: 371450
There are some functions which can't be given a null pointer as parameter either
because it has a nonnull attribute or it is declared to have undefined behavior
(e.g. strcmp()). Sometimes it is hard to determine from the checker message
which parameter is null at the invocation, so now this information is included
in the message.
This commit fixes https://bugs.llvm.org/show_bug.cgi?id=39358
Reviewed By: NoQ, Szelethus, whisperity
Patch by Tibor Brunner!
Differential Revision: https://reviews.llvm.org/D66333
llvm-svn: 370798
Now that we've moved to C++14, we no longer need the llvm::make_unique
implementation from STLExtras.h. This patch is a mechanical replacement
of (hopefully) all the llvm::make_unique instances across the monorepo.
Differential revision: https://reviews.llvm.org/D66259
llvm-svn: 368942
This patch uses the new CDF_MaybeBuiltin flag to handle C library functions.
It's mostly an NFC/refactoring pass, but it does fix a bug in handling memset()
when it expands to __builtin___memset_chk() because the latter has
one more argument and memset() handling code was trying to match
the exact number of arguments. Now the code is deduplicated and there's
less room for mistakes.
Differential Revision: https://reviews.llvm.org/D62557
llvm-svn: 364868
This changes the checker callback signature to use the modern, easy to
use interface. Additionally, this unblocks future work on allowing
checkers to implement evalCall() for calls that don't correspond to any
call-expression or require additional information that's only available
as part of the CallEvent, such as C++ constructors and destructors.
Differential Revision: https://reviews.llvm.org/D62440
llvm-svn: 363893
This patch effectively fixes the almost decade old checker naming issue.
The solution is to assert when CheckerManager::getChecker is called on an
unregistered checker, and assert when CheckerManager::registerChecker is called
on a checker that is already registered.
Differential Revision: https://reviews.llvm.org/D55429
llvm-svn: 352292
Unfortunately, up until now, the fact that certain checkers depended on one
another was known, but how these actually unfolded was hidden deep within the
implementation. For example, many checkers (like RetainCount, Malloc or CString)
modelled a certain functionality, and exposed certain reportable bug types to
the user. For example, while MallocChecker models many many different types of
memory handling, the actual "unix.MallocChecker" checker the user was exposed to
was merely and option to this modeling part.
Other than this being an ugly mess, this issue made resolving the checker naming
issue almost impossible. (The checker naming issue being that if a checker
registered more than one checker within its registry function, both checker
object recieved the same name) Also, if the user explicitly disabled a checker
that was a dependency of another that _was_ explicitly enabled, it implicitly,
without "telling" the user, reenabled it.
Clearly, changing this to a well structured, declarative form, where the
handling of dependencies are done on a higher level is very much preferred.
This patch, among the detailed things later, makes checkers declare their
dependencies within the TableGen file Checkers.td, and exposes the same
functionality to plugins and statically linked non-generated checkers through
CheckerRegistry::addDependency. CheckerRegistry now resolves these dependencies,
makes sure that checkers are added to CheckerManager in the correct order,
and makes sure that if a dependency is disabled, so will be every checker that
depends on it.
In detail:
* Add a new field to the Checker class in CheckerBase.td called Dependencies,
which is a list of Checkers.
* Move unix checkers before cplusplus, as there is no forward declaration in
tblgen :/
* Add the following new checkers:
- StackAddrEscapeBase
- StackAddrEscapeBase
- CStringModeling
- DynamicMemoryModeling (base of the MallocChecker family)
- IteratorModeling (base of the IteratorChecker family)
- ValistBase
- SecuritySyntaxChecker (base of bcmp, bcopy, etc...)
- NSOrCFErrorDerefChecker (base of NSErrorChecker and CFErrorChecker)
- IvarInvalidationModeling (base of IvarInvalidation checker family)
- RetainCountBase (base of RetainCount and OSObjectRetainCount)
* Clear up and registry functions in MallocChecker, happily remove old FIXMEs.
* Add a new addDependency function to CheckerRegistry.
* Neatly format RUN lines in files I looked at while debugging.
Big thanks to Artem Degrachev for all the guidance through this project!
Differential Revision: https://reviews.llvm.org/D54438
llvm-svn: 352287
Introduce the boolean ento::shouldRegister##CHECKERNAME(const LangOptions &LO)
function very similarly to ento::register##CHECKERNAME. This will force every
checker to implement this function, but maybe it isn't that bad: I saw a lot of
ObjC or C++ specific checkers that should probably not register themselves based
on some LangOptions (mine too), but they do anyways.
A big benefit of this is that all registry functions now register their checker,
once it is called, registration is guaranteed.
This patch is a part of a greater effort to reinvent checker registration, more
info here: D54438#1315953
Differential Revision: https://reviews.llvm.org/D55424
llvm-svn: 352277
to reflect the new license.
We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.
Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.
llvm-svn: 351636
It turns out that it's not all that uncommon to have a C++ override of, say,
memcpy that receives a structure (or two) by reference (or by value, if it's
being copied from) and copies memory from it (or into it, if it's passed
by reference). In this case the argument will be of structure type (recall that
expressions of reference type do not exist: instead, C++ classifies expressions
into prvalues and lvalues and xvalues).
In this scenario we crash because we are trying to assume that, say,
a memory region is equal to an empty CompoundValue (the non-lazy one; this is
what makeZeroVal() return for compound types and it represents prvalue of
an object that is initialized with an empty initializer list).
Add defensive checks.
Differential Revision: https://reviews.llvm.org/D55873
rdar://problem/45366551
llvm-svn: 349682
ClangCheckerRegistry is a very non-obvious, poorly documented, weird concept.
It derives from CheckerRegistry, and is placed in lib/StaticAnalyzer/Frontend,
whereas it's base is located in lib/StaticAnalyzer/Core. It was, from what I can
imagine, used to circumvent the problem that the registry functions of the
checkers are located in the clangStaticAnalyzerCheckers library, but that
library depends on clangStaticAnalyzerCore. However, clangStaticAnalyzerFrontend
depends on both of those libraries.
One can make the observation however, that CheckerRegistry has no place in Core,
it isn't used there at all! The only place where it is used is Frontend, which
is where it ultimately belongs.
This move implies that since
include/clang/StaticAnalyzer/Checkers/ClangCheckers.h only contained a single function:
class CheckerRegistry;
void registerBuiltinCheckers(CheckerRegistry ®istry);
it had to re purposed, as CheckerRegistry is no longer available to
clangStaticAnalyzerCheckers. It was renamed to BuiltinCheckerRegistration.h,
which actually describes it a lot better -- it does not contain the registration
functions for checkers, but only those generated by the tblgen files.
Differential Revision: https://reviews.llvm.org/D54436
llvm-svn: 349275
- explicit_bzero has limited scope/usage only for security/crypto purposes but is non-optimisable version of memset/0 and bzero.
- explicit_memset has similar signature and semantics as memset but is also a non-optimisable version.
Reviewers: NoQ
Reviewed By: NoQ
Differential Revision: https://reviews.llvm.org/D54592
llvm-svn: 348884
It's an old bug that consists in stale references to symbols remaining in the
GDM if they disappear from other program state sections as a result of any
operation that isn't the actual dead symbol collection. The most common example
here is:
FILE *fp = fopen("myfile.txt", "w");
fp = 0; // leak of file descriptor
In this example the leak were not detected previously because the symbol
disappears from the public part of the program state due to evaluating
the assignment. For that reason the checker never receives a notification
that the symbol is dead, and never reports a leak.
This patch not only causes leak false negatives, but also a number of other
problems, including false positives on some checkers.
What's worse, even though the program state contains a finite number of symbols,
the set of symbols that dies is potentially infinite. This means that is
impossible to compute the set of all dead symbols to pass off to the checkers
for cleaning up their part of the GDM.
No longer compute the dead set at all. Disallow iterating over dead symbols.
Disallow querying if any symbols are dead. Remove the API for marking symbols
as dead, as it is no longer necessary. Update checkers accordingly.
Differential Revision: https://reviews.llvm.org/D18860
llvm-svn: 347953
trackNullOrUndefValue is a long and confusing name,
and it does not actually reflect what the function is doing.
Give a function a new name, with a relatively clear semantics.
Also remove some dead code.
Differential Revision: https://reviews.llvm.org/D52758
llvm-svn: 345064
When emitting a bug report, it is important to highlight which argument of the
call-expression is causing the problem.
Before:
warning: Null pointer argument in call to string comparison function
strcmp(a, b);
^~~~~~~~~~~~
After:
warning: Null pointer argument in call to string comparison function
strcmp(a, b);
^ ~
Affects other output modes as well, not just text.
Differential Revision: https://reviews.llvm.org/D50028
llvm-svn: 338333
It was not possible to disable alpha.unix.cstring.OutOfBounds checker's reports
since unix.Malloc checker always implicitly enabled the filter. Moreover if the
checker was disabled from command line (-analyzer-disable-checker ..) the out
of bounds warnings were nevertheless emitted under different checker names such
as unix.cstring.NullArg, or unix.Malloc.
This patch fixes the case sot that Malloc checker only enables implicitly the
underlying modeling of strcpy, memcpy etc. but not the warning messages that
would have been emmitted by alpha.unix.cstring.OutOfBounds
Patch by: Dániel Krupp
Differential Revision: https://reviews.llvm.org/D48831
llvm-svn: 337000
Again, strlc* does not return a pointer so the zero size case doest not fit.
Reviewers: NoQ, george.karpenkov
Reviewed by: NoQ
Differential Revision: https://reviews.llvm.org/D47007
llvm-svn: 333060
Since there is no perfect way bind the non-zero value with the default binding, this patch only considers the case where buffer's offset is zero and the char value is 0. And according to the value for overwriting, decide how to update the string length.
Reviewers: dcoughlin, NoQ, xazax.hun, a.sidorin, george.karpenkov
Reviewed By: NoQ
Differential Revision: https://reviews.llvm.org/D44934
llvm-svn: 332463
The return values of the newly supported functions were not handled correctly:
strlcpy()/strlcat() return string sizes rather than pointers.
Differential Revision: https://reviews.llvm.org/D45177
llvm-svn: 331401
Summary: `CheckBufferAccess()` calls `CheckNonNull()`, so there are some calls to `CheckNonNull()` that are useless.
Reviewers: dcoughlin, NoQ, xazax.hun, cfe-commits, george.karpenkov
Reviewed By: NoQ
Subscribers: szepet, rnkovacs, MTC, a.sidorin
Differential Revision: https://reviews.llvm.org/D44075
llvm-svn: 326782
Fix an assertion failure caused by a missing CheckName. The malloc checker
enables "basic" support in the CStringChecker, which causes some CString
bounds checks to be enabled. In this case, make sure that we have a
valid CheckName for the BugType.
llvm-svn: 323052
In most cases using
`N->getState()->getSVal(E, N->getLocationContext())`
is ugly, verbose, and also opens up more surface area for bugs if an
inconsistent location context is used.
This patch introduces a helper on an exploded node, and ensures
consistent usage of either `ExplodedNode::getSVal` or
`CheckContext::getSVal` across the codebase.
As a result, a large number of redundant lines is removed.
Differential Revision: https://reviews.llvm.org/D42155
llvm-svn: 322753
Do not crash when trying to define and call a non-standard
strcpy(unsigned char *, unsigned char *) during analysis.
At the same time, do not try to actually evaluate the call.
Differential Revision: https://reviews.llvm.org/D39422
llvm-svn: 317565
The checker used to crash when a mempcpy's length argument is symbolic. In this
case the cast from 'void *' to 'char *' failed because the respective
ElementRegion that represents cast is hard to add on top of the existing
ElementRegion that represents the offset to the last copied byte, while
preseving a sane memory region structure.
Additionally, a few test cases are added (to casts.c) which demonstrate problems
caused by existing sloppy work we do with multi-layer ElementRegions. If said
cast would be modeled properly in the future, these tests would need to be
taken into account.
Differential Revision: https://reviews.llvm.org/D38797
llvm-svn: 315742
This patch adds LocationContext to checkRegionChanges and removes
wantsRegionChangeUpdate as it was unused.
A patch by Krzysztof Wiśniewski!
Differential Revision: https://reviews.llvm.org/D27090
llvm-svn: 291869
Remove the check::RegionChanges::wantsRegionChangeUpdate callback as it is no
longer used (since checkPointerEscape has been added).
A patch by Krzysztof Wiśniewski!
Differential Revision: https://reviews.llvm.org/D26759
llvm-svn: 287175
Like SymbolConjured, SymbolMetadata also needs to be uniquely
identified by the moment of its birth.
Such moments are coded by the (Statement, LocationContext, Block count) triples.
Each such triple represents the moment of analyzing a statement with a certain
call backtrace, with corresponding CFG block having been entered a given amount
of times during analysis of the current code body.
The LocationContext information was accidentally omitted for SymbolMetadata,
which leads to reincarnation of SymbolMetadata upon re-entering a code body
with a different backtrace; the new symbol is incorrectly unified with
the old symbol, which leads to unsound assumptions.
Patch by Alexey Sidorin!
Differential Revision: https://reviews.llvm.org/D21978
llvm-svn: 278937
The function strcmp() can return any value, not just {-1,0,1} : "The strcmp(const char *s1, const char *s2) function returns an integer greater than, equal to, or less than zero, accordingly as the string pointed to by s1 is greater than, equal to, or less than the string pointed to by s2." [C11 7.24.4.2p3]
https://llvm.org/bugs/show_bug.cgi?id=23790http://reviews.llvm.org/D16317
llvm-svn: 270154
If an address of a field is passed through a const pointer,
the whole structure's base region should receive the
TK_PreserveContents trait and avoid invalidation.
Additionally, include a few FIXME tests shown up during testing.
Differential Revision: http://reviews.llvm.org/D19057
llvm-svn: 267413
Now that the libcpp implementations of these methods has a branch that doesn't call
memmove(), the analyzer needs to invalidate the destination for these methods explicitly.
rdar://problem/23575656
llvm-svn: 260043
The purpose of these changes is to simplify introduction of definition files
for the three hierarchies.
1. For every sub-class C of these classes, its kind in the relevant enumeration
is changed to "CKind" (or C##Kind in preprocessor-ish terms), eg:
MemRegionKind -> MemRegionValKind
RegionValueKind -> SymbolRegionValueKind
CastSymbolKind -> SymbolCastKind
SymIntKind -> SymIntExprKind
2. MemSpaceRegion used to be inconsistently used as both an abstract base and
a particular region. This region class is now an abstract base and no longer
occupies GenericMemSpaceRegionKind. Instead, a new class, CodeSpaceRegion,
is introduced for handling the unique use case for MemSpaceRegion as
"the generic memory space" (when it represents a memory space that holds all
executable code).
3. BEG_ prefixes in memory region kind ranges are renamed to BEGIN_ for
consisitency with symbol kind ranges.
4. FunctionTextRegion and BlockTextRegion are renamed to FunctionCodeRegion and
BlockCodeRegion, respectively. The term 'code' is less jargony than 'text' and
we already refer to BlockTextRegion as a 'code region' in BlockDataRegion.
Differential Revision: http://reviews.llvm.org/D16062
llvm-svn: 257598