373 Commits

Author SHA1 Message Date
Artem Dergachev
e2b5438a73 [analyzer] MallocChecker: Avoid redundant transitions.
Don't generate a checker-tagged node unconditionally on the first
checkDeadSymbols callback when no pointers are tracked.

This is a tiny performance optimization; it may change the behavior slightly
by making Static Analyzer bail out on max-nodes one node later (which is good)
but any test would either break for no good reason or become useless
every time someone sneezes.

Differential Revision: https://reviews.llvm.org/D54013

llvm-svn: 347955
2018-11-30 03:52:42 +00:00
Artem Dergachev
bbc6d68297 [analyzer] Fix the "Zombie Symbols" bug.
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
2018-11-30 03:27:50 +00:00
Kristof Umann
0a1f91c80c [analyzer] Restrict AnalyzerOptions' interface so that non-checker objects have to be registered
One of the reasons why AnalyzerOptions is so chaotic is that options can be
retrieved from the command line whenever and wherever. This allowed for some
options to be forgotten for a looooooong time. Have you ever heard of
"region-store-small-struct-limit"? In order to prevent this in the future, I'm
proposing to restrict AnalyzerOptions' interface so that only checker options
can be retrieved without special getters. I would like to make every option be
accessible only through a getter, but checkers from plugins are a thing, so I'll
have to figure something out for that.

This also forces developers who'd like to add a new option to register it
properly in the .def file.

This is done by

* making the third checker pointer parameter non-optional, and checked by an
  assert to be non-null.
* I added new, but private non-checkers option initializers, meant only for
  internal use,
* Renamed these methods accordingly (mind the consistent name for once with
  getBooleanOption!):
  - getOptionAsString -> getCheckerStringOption,
  - getOptionAsInteger -> getCheckerIntegerOption
* The 3 functions meant for initializing data members (with the not very
  descriptive getBooleanOption, getOptionAsString and getOptionAsUInt names)
  were renamed to be overloads of the getAndInitOption function name.
* All options were in some way retrieved via getCheckerOption. I removed it, and
  moved the logic to getStringOption and getCheckerStringOption. This did cause
  some code duplication, but that's the only way I could do it, now that checker
  and non-checker options are separated. Note that the non-checker version
  inserts the new option to the ConfigTable with the default value, but the
  checker version only attempts to find already existing entries. This is how
  it always worked, but this is clunky and I might end reworking that too, so we
  can eventually get a ConfigTable that contains the entire configuration of the
  analyzer.

Differential Revision: https://reviews.llvm.org/D53483

llvm-svn: 346113
2018-11-05 03:50:37 +00:00
Artem Dergachev
32c0c85382 [analyzer] pr39348: MallocChecker: Realize that sized delete isn't custom delete.
MallocChecker no longer thinks that operator delete() that accepts the size of
the object to delete (available since C++14 or under -fsized-deallocation)
is some weird user-defined operator. Instead, it handles it like normal delete.

Additionally, it exposes a regression in NewDelete-intersections.mm's
testStandardPlacementNewAfterDelete() test, where the diagnostic is delayed
from before the call of placement new into the code of placement new
in the header. This happens because the check for pass-into-function-after-free
for placement arguments is located in checkNewAllocator(), which happens after
the allocator is inlined, which is too late. Move this use-after-free check
into checkPreCall instead, where it works automagically because the guard
that prevents it from working is useless and can be removed as well.

This commit causes regressions under -analyzer-config
c++-allocator-inlining=false but this option is essentially unsupported
because the respective feature has been enabled by default quite a while ago.

Differential Revision: https://reviews.llvm.org/D53543

llvm-svn: 345802
2018-11-01 00:43:35 +00:00
George Karpenkov
d3e7675331 [analyzer] [NFC] Change scanReachableSymbols to use ranges
Remove unused overload. Clean up some usages.

Differential Revision: https://reviews.llvm.org/D53615

llvm-svn: 345101
2018-10-23 23:12:12 +00:00
George Karpenkov
c82d457db5 [analyzer] [NFC] Remove unused parameters, as found by -Wunused-parameter
Differential Revision: https://reviews.llvm.org/D52640

llvm-svn: 343353
2018-09-28 18:49:41 +00:00
Reka Kovacs
bb2749a594 [analyzer] InnerPointerChecker: improve warning messages and notes.
Differential Revision: https://reviews.llvm.org/D49570

llvm-svn: 339489
2018-08-10 23:56:57 +00:00
Reka Kovacs
d9f66ba340 [analyzer] InnerPointerChecker: fix displayed checker name.
For InnerPointerChecker to function properly, both the checker itself
and parts of MallocChecker that handle relevant use-after-free problems
need to be turned on. So far, the latter part has been developed within
MallocChecker's NewDelete sub-checker, often causing warnings to appear
under that name. This patch defines a new CheckKind within MallocChecker
for the inner pointer checking functionality, so that the correct name
is displayed in warnings and in the ExplodedGraph.

Tested on clang-tidy.

Differential Review: https://reviews.llvm.org/D50211

llvm-svn: 339067
2018-08-06 22:03:42 +00:00
Reka Kovacs
122171e235 [analyzer] Detect pointers escaped after ReturnStmt execution in MallocChecker.
Objects local to a function are destroyed right after the statement returning
(part of) them is executed in the analyzer. This patch enables MallocChecker to
warn in these cases.

Differential Revision: https://reviews.llvm.org/D49361

llvm-svn: 338780
2018-08-02 23:02:08 +00:00
Fangrui Song
6907ce2f8f Remove trailing space
sed -Ei 's/[[:space:]]+$//' include/**/*.{def,h,td} lib/**/*.{cpp,h}

llvm-svn: 338291
2018-07-30 19:24:48 +00:00
Reka Kovacs
c74cfc4215 [analyzer] Add support for more invalidating functions in InnerPointerChecker.
According to the standard, pointers referring to the elements of a
`basic_string` may be invalidated if they are used as an argument to
any standard library function taking a reference to non-const
`basic_string` as an argument. This patch makes InnerPointerChecker warn
for these cases.

Differential Revision: https://reviews.llvm.org/D49656

llvm-svn: 338259
2018-07-30 15:43:45 +00:00
Reka Kovacs
88ad704b5b [analyzer] Rename DanglingInternalBufferChecker to InnerPointerChecker.
Differential Revision: https://reviews.llvm.org/D49553

llvm-svn: 337559
2018-07-20 15:14:49 +00:00
Reka Kovacs
a14a2fed38 [analyzer] Fix memory sanitizer error in MallocChecker.
StringRef's data() returns a string that may be non-null-terminated.
Switch to using StringRefs from const char pointers in visitor notes
to avoid problems.

llvm-svn: 337474
2018-07-19 17:43:09 +00:00
Reka Kovacs
52dd98bd1e [analyzer] Fix disappearing notes in DanglingInternalBufferChecker tests
Correct a mistake of the exact same kind I am writing this checker for.

llvm-svn: 337466
2018-07-19 15:44:46 +00:00
Reka Kovacs
c18ecc8489 [analyzer] Add support for more basic_string API in
DanglingInternalBufferChecker.

A pointer referring to the elements of a basic_string may be invalidated
by calling a non-const member function, except operator[], at, front,
back, begin, rbegin, end, and rend. The checker now warns if the pointer
is used after such operations.

Differential Revision: https://reviews.llvm.org/D49360

llvm-svn: 337463
2018-07-19 15:10:06 +00:00
Reka Kovacs
e453e60d08 [analyzer] Highlight c_str() call in DanglingInternalBufferChecker.
Add a bug visitor to DanglingInternalBufferChecker that places a note
at the point where the dangling pointer was obtained. The visitor is
handed over to MallocChecker and attached to the report there.

Differential Revision: https://reviews.llvm.org/D48522

llvm-svn: 336495
2018-07-07 19:27:18 +00:00
Reka Kovacs
e0dae15d91 [analyzer] Fix -Wcovered-switch-default warning in MallocChecker.
Remove unnecessary default case that caused buildbot failures.

llvm-svn: 336493
2018-07-07 18:37:37 +00:00
Reka Kovacs
8707cd1d1b [analyzer] Highlight container object destruction in MallocChecker.
Extend MallocBugVisitor to place a note at the point where objects with
AF_InternalBuffer allocation family are destroyed.

Differential Revision: https://reviews.llvm.org/D48521

llvm-svn: 336489
2018-07-07 17:22:45 +00:00
George Karpenkov
dd18b11b8e [analyzer] [NFC] A convenient getter for getting a current stack frame
Differential Revision: https://reviews.llvm.org/D44756

llvm-svn: 335701
2018-06-27 01:51:55 +00:00
George Karpenkov
70ec1dd14d [analyzer] Do not run visitors until the fixpoint, run only once.
In the current implementation, we run visitors until the fixed point is
reached.
That is, if a visitor adds another visitor, the currently processed path
is destroyed, all diagnostics is discarded, and it is regenerated again,
until it's no longer modified.
This pattern has a few negative implications:

 - This loop does not even guarantee to terminate.
   E.g. just imagine two visitors bouncing a diagnostics around.
 - Performance-wise, e.g. for sqlite3 all visitors are being re-run at
   least 10 times for some bugs.
   We have already seen a few reports where it leads to timeouts.
 - If we want to add more computationally intense visitors, this will
   become worse.
 - From architectural standpoint, the current layout requires copying
   visitors, which is conceptually wrong, and can be annoying (e.g. no
   unique_ptr on visitors allowed).

The proposed change is a much simpler architecture: the outer loop
processes nodes upwards, and whenever the visitor is added it only
processes current nodes and above, thus guaranteeing termination.

Differential Revision: https://reviews.llvm.org/D47856

llvm-svn: 335666
2018-06-26 21:12:08 +00:00
Reka Kovacs
18775fc9b7 [analyzer] Add dangling internal buffer check.
This check will mark raw pointers to C++ standard library container internal
buffers 'released' when the objects themselves are destroyed. Such information
can be used by MallocChecker to warn about use-after-free problems.

In this first version, 'std::basic_string's are supported.

Differential Revision: https://reviews.llvm.org/D47135

llvm-svn: 334348
2018-06-09 13:03:49 +00:00
Adrian Prantl
9fc8faf9e6 Remove \brief commands from doxygen comments.
This is similar to the LLVM change https://reviews.llvm.org/D46290.

We've been running doxygen with the autobrief option for a couple of
years now. This makes the \brief markers into our comments
redundant. Since they are a visual distraction and we don't want to
encourage more \brief markers in new code either, this patch removes
them all.

Patch produced by

for i in $(git grep -l '\@brief'); do perl -pi -e 's/\@brief //g' $i & done
for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done

Differential Revision: https://reviews.llvm.org/D46320

llvm-svn: 331834
2018-05-09 01:00:01 +00:00
Artem Dergachev
806486c781 [analyzer] pr18953: Split C++ zero-initialization from default initialization.
The bindDefault() API of the ProgramState allows setting a default value
for reads from memory regions that were not preceded by writes.

It was used for implementing C++ zeroing constructors (i.e. default constructors
that boil down to setting all fields of the object to 0).

Because differences between zeroing consturctors and other forms of default
initialization have been piling up (in particular, zeroing constructors can be
called multiple times over the same object, probably even at the same offset,
requiring a careful and potentially slow cleanup of previous bindings in the
RegionStore), we split the API in two: bindDefaultInitial() for modeling
initial values and bindDefaultZero() for modeling zeroing constructors.

This fixes a few assertion failures from which the investigation originated.

The imperfect protection from both inability of the RegionStore to support
binding extents and lack of information in ASTRecordLayout has been loosened
because it's, well, imperfect, and it is unclear if it fixing more than it
was breaking.

Differential Revision: https://reviews.llvm.org/D46368

llvm-svn: 331561
2018-05-04 21:56:51 +00:00
Joel E. Denny
a6555114c8 [Attr] [NFC] Revert accidental change from r327405
llvm-svn: 329005
2018-04-02 19:43:34 +00:00
Artem Dergachev
ff1fc21e8a [analyzer] Suppress more MallocChecker positives in smart pointer destructors.
r326249 wasn't quite enough because we often run out of inlining stack depth
limit and for that reason fail to see the atomics we're looking for.

Add a more straightforward false positive suppression that is based on the name
of the class. I.e. if we're releasing a pointer in a destructor of a "something
shared/intrusive/reference/counting something ptr/pointer something", then any
use-after-free or double-free that occurs later would likely be a false
positive.

rdar://problem/38013606

Differential Revision: https://reviews.llvm.org/D44281

llvm-svn: 328066
2018-03-21 00:49:47 +00:00
Joel E. Denny
8150810556 Reland "[Attr] Fix parameter indexing for several attributes"
Relands r326602 (reverted in r326862) with new test and fix for
PR36620.

Differential Revision: https://reviews.llvm.org/D43248

llvm-svn: 327405
2018-03-13 14:51:22 +00:00
Nico Weber
bbf648253d Revert r326602, it caused PR36620.
llvm-svn: 326862
2018-03-07 02:22:41 +00:00
Joel E. Denny
4925445958 [Attr] Fix parameter indexing for several attributes
The patch fixes a number of bugs related to parameter indexing in
attributes:

* Parameter indices in some attributes (argument_with_type_tag,
  pointer_with_type_tag, nonnull, ownership_takes, ownership_holds,
  and ownership_returns) are specified in source as one-origin
  including any C++ implicit this parameter, were stored as
  zero-origin excluding any this parameter, and were erroneously
  printing (-ast-print) and confusingly dumping (-ast-dump) as the
  stored values.

* For alloc_size, the C++ implicit this parameter was not subtracted
  correctly in Sema, leading to assert failures or to silent failures
  of __builtin_object_size to compute a value.

* For argument_with_type_tag, pointer_with_type_tag, and
  ownership_returns, the C++ implicit this parameter was not added
  back to parameter indices in some diagnostics.

This patch fixes the above bugs and aims to prevent similar bugs in
the future by introducing careful mechanisms for handling parameter
indices in attributes.  ParamIdx stores a parameter index and is
designed to hide the stored encoding while providing accessors that
require each use (such as printing) to make explicit the encoding that
is needed.  Attribute declarations declare parameter index arguments
as [Variadic]ParamIdxArgument, which are exposed as ParamIdx[*].  This
patch rewrites all attribute arguments that are processed by
checkFunctionOrMethodParameterIndex in SemaDeclAttr.cpp to be declared
as [Variadic]ParamIdxArgument.  The only exception is xray_log_args's
argument, which is encoded as a count not an index.

Differential Revision: https://reviews.llvm.org/D43248

llvm-svn: 326602
2018-03-02 19:03:22 +00:00
Artem Dergachev
5337efc69c [analyzer] MallocChecker: Suppress false positives in shared pointers.
Throw away MallocChecker warnings that occur after releasing a pointer within a
destructor (or its callees) after performing C11 atomic fetch_add or fetch_sub
within that destructor (or its callees).

This is an indication that the destructor's class is likely a
reference-counting pointer. The analyzer is not able to understand that the
original reference count is usually large enough to avoid most use-after-frees.

Even when the smart pointer is a local variable, we still have these false
positives that this patch suppresses, because the analyzer doesn't currently
support atomics well enough.

Differential Revision: https://reviews.llvm.org/D43791

llvm-svn: 326249
2018-02-27 21:19:33 +00:00
Artem Dergachev
9849f595b9 [analyzer] MallocChecker: Fix one more bug category.
Even though most of the inconsistencies in MallocChecker's bug categories were
fixed in r302016, one more was introduced in r301913 which was later missed.

Patch by Henry Wong!

Differential Revision: https://reviews.llvm.org/D43074

llvm-svn: 324680
2018-02-08 23:28:29 +00:00
Artem Dergachev
13b2026ba4 [analyzer] operator new: Add a new checker callback, check::NewAllocator.
The callback runs after operator new() and before the construction and allows
the checker to access the casted return value of operator new() (in the
sense of r322780) which is not available in the PostCall callback for the
allocator call.

Update MallocChecker to use the new callback instead of PostStmt<CXXNewExpr>,
which gets called after the constructor.

Differential Revision: https://reviews.llvm.org/D41406
rdar://problem/12180598

llvm-svn: 322787
2018-01-17 23:46:13 +00:00
George Karpenkov
d703ec94a9 [analyzer] introduce getSVal(Stmt *) helper on ExplodedNode, make sure the helper is used consistently
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
2018-01-17 20:27:29 +00:00
Gabor Horvath
b77bc6bb8b [analyzer] Fix some check's output plist not containing the check name
Differential Revision: https://reviews.llvm.org/D41538

llvm-svn: 321933
2018-01-06 10:51:00 +00:00
Artem Dergachev
b6a513d1b2 [analyzer] Fix memory error bug category capitalization.
It was written as "Memory Error" in most places and as "Memory error" in a few
other places, however it is the latter that is more consistent with
other categories (such as "Logic error").

rdar://problem/31718115

Differential Revision: https://reviews.llvm.org/D32702

llvm-svn: 302016
2017-05-03 11:47:13 +00:00
Daniel Marjamaki
a43a8f5c5e [analyzer] Detect bad free of function pointers
Differential Revision: https://reviews.llvm.org/D31650

llvm-svn: 301913
2017-05-02 11:46:12 +00:00
Leslie Zhai
e3986c544d [analyzer] Teach the MallocChecker about Glib API for two arguments
Reviewers: zaks.anna, NoQ, danielmarjamaki

Reviewed By: zaks.anna, NoQ, danielmarjamaki

Subscribers: cfe-commits, kalev, pwithnall

Differential Revision: https://reviews.llvm.org/D30771

llvm-svn: 301384
2017-04-26 05:33:14 +00:00
Anna Zaks
bbec97ca2c [analyzer] Teach the MallocChecker about about Glib API
A patch by Leslie Zhai!

Differential Revision: https://reviews.llvm.org/D28348

llvm-svn: 297323
2017-03-09 00:01:01 +00:00
Anna Zaks
b570195c3a [analyzer] Add LocationContext as a parameter to checkRegionChanges
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
2017-01-13 00:50:57 +00:00
David Blaikie
0a0c275ffd Migrate PathDiagnosticPiece to std::shared_ptr
Simplifies and makes explicit the memory ownership model rather than
implicitly passing/acquiring ownership.

llvm-svn: 291143
2017-01-05 17:26:53 +00:00
Devin Coughlin
e3b75ded98 [analyzer] Fix crash in MallocChecker.
Fix a crash in the MallocChecker when the extent size for the argument
to new[] is not known.

A patch by Abramo Bagnara and Dániel Krupp!

https://reviews.llvm.org/D27849

Differential Revision: https://reviews.llvm.org/D27849

llvm-svn: 289970
2016-12-16 18:41:40 +00:00
Artem Dergachev
85c9211043 [analyzer] Add another exception for Qt in MallocChecker
Treat pointers passed to QObject::connectImpl() as escaping.

rdar://problem/29550440

Differential Revision: https://reviews.llvm.org/D27717

llvm-svn: 289939
2016-12-16 12:21:55 +00:00
Devin Coughlin
684d19d879 Revert "Revert "[analyzer] Make MallocChecker more robust against custom redeclarations""
This reverts commit r284340 to reapply r284335. The bot breakage was due to
an unrelated change in the polybench test suite.

llvm-svn: 284351
2016-10-16 22:19:03 +00:00
Devin Coughlin
eeb8d20db4 Revert "[analyzer] Make MallocChecker more robust against custom redeclarations"
This reverts commit r284335.

It appears to be causing test-suite compile-time and execution-time
performance measurements to take longer than expected on several bots.
This is surprising, because r284335 is a static-analyzer-only change.

llvm-svn: 284340
2016-10-16 19:26:07 +00:00
Devin Coughlin
62ce463a35 [analyzer] Make MallocChecker more robust against custom redeclarations
Add additional checking to MallocChecker to avoid crashing when memory
routines have unexpected numbers of arguments. You wouldn't expect to see much
of this in normal code (-Wincompatible-library-redeclaration warns on this),
but, for example, CMake tests can generate these.

This is PR30616.

rdar://problem/28631974

llvm-svn: 284335
2016-10-16 17:26:06 +00:00
Gabor Horvath
7304027c6d [analyzer] Calculate extent size for memory regions allocated by new expression.
ArrayBoundChecker did not detect out of bounds memory access errors in case an
array was allocated by the new expression. This patch resolves this issue.

Patch by Daniel Krupp!

Differential Revision: https://reviews.llvm.org/D24307

llvm-svn: 281934
2016-09-19 20:39:52 +00:00
Gabor Horvath
6ee4f905dc [analyzer] Small cleanups when checkers retrieving statements from exploded
nodes.

Differential Revision: https://reviews.llvm.org/D23550

llvm-svn: 279037
2016-08-18 07:54:50 +00:00
Mehdi Amini
9670f847b8 [NFC] Header cleanup
Summary: Removed unused headers, replaced some headers with forward class declarations

Patch by: Eugene <claprix@yandex.ru>

Differential Revision: https://reviews.llvm.org/D20100

llvm-svn: 275882
2016-07-18 19:02:11 +00:00
David Majnemer
59f7792136 Use more ArrayRefs
No functional change is intended, just a small refactoring.

llvm-svn: 273647
2016-06-24 04:05:48 +00:00
Benjamin Kramer
cfeacf56f0 Apply clang-tidy's misc-move-constructor-init throughout Clang.
No functionality change intended, maybe a tiny performance improvement.

llvm-svn: 270996
2016-05-27 14:27:13 +00:00
Anna Zaks
30d4668774 [analyzer] Fix missed leak from MSVC specific allocation functions
Add the wide character strdup variants (wcsdup, _wcsdup) and the MSVC
version of alloca (_alloca) and other differently named function used
by the Malloc checker.

A patch by Alexander Riccio!

Differential Revision: http://reviews.llvm.org/D17688

llvm-svn: 262894
2016-03-08 01:21:51 +00:00