Commit Graph

3332 Commits

Author SHA1 Message Date
Kristof Umann 9f7fc9838a [analyzer] Don't display implementation checkers under -analyzer-checker-help, but do under the new flag -analyzer-checker-help-hidden
During my work on analyzer dependencies, I created a great amount of new
checkers that emitted no diagnostics at all, and were purely modeling some
function or another.

However, the user shouldn't really disable/enable these by hand, hence this
patch, which hides these by default. I intentionally chose not to hide alpha
checkers, because they have a scary enough name, in my opinion, to cause no
surprise when they emit false positives or cause crashes.

The patch introduces the Hidden bit into the TableGen files (you may remember
it before I removed it in D53995), and checkers that are either marked as
hidden, or are in a package that is marked hidden won't be displayed under
-analyzer-checker-help. -analyzer-checker-help-hidden, a new flag meant for
developers only, displays the full list.

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

llvm-svn: 359720
2019-05-01 19:56:47 +00:00
Hubert Tong 0b4699b931 [analyzer][tests][NFC] Add EOF newlines, normalize reference expected files
Reference expected files not ending with a newline are normalized to
have said newlines. Additionally `plist-macros-with-expansion.cpp.plist`
is modified to add a line that is ignored by `%diff_plist`, but not by
the more sensitive pattern proposed by
http://lists.llvm.org/pipermail/cfe-dev/2019-April/061904.html for
`%normalize_plist`.

llvm-svn: 359692
2019-05-01 15:57:00 +00:00
Hubert Tong 46e0fc88cc [analyzer][tests] Use diff_plist, correct order of arguments for missed cases; NFC
For various files under `clang/test/Analysis`, D52036 applied
`%diff_plist` to replace `diff` invocations with certain options and
D56340 swapped the order of the arguments so that the reference file
comes first. The tests that used `tail` to filter the test output were
not modified accordingly. This patch applies the corresponding update
to those tests.

llvm-svn: 359691
2019-05-01 15:53:56 +00:00
Kristof Umann c21ec00d28 [analyzer][UninitializedObjectChecker] PR41611: Regard vector types as primitive
https://bugs.llvm.org/show_bug.cgi?id=41611

Similarly to D61106, the checker ran over an llvm_unreachable for vector types:

struct VectorSizeLong {
  VectorSizeLong() {}
  __attribute__((__vector_size__(16))) long x;
};

void __vector_size__LongTest() {
  VectorSizeLong v;
}
Since, according to my short research,

"The vector_size attribute is only applicable to integral and float scalars,
although arrays, pointers, and function return values are allowed in conjunction
with this construct."
[src: https://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Vector-Extensions.html#Vector-Extensions]

vector types are safe to regard as primitive.

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

llvm-svn: 359539
2019-04-30 08:47:56 +00:00
Artem Dergachev ab7747b727 [analyzer] Treat functions without run-time branches as "small".
Currently we always inline functions that have no branches, i.e. have exactly
three CFG blocks: ENTRY, some code, EXIT. This makes sense because when there
are no branches, it means that there's no exponential complexity introduced
by inlining such function. Such functions also don't trigger various fundamental
problems with our inlining mechanism, such as the problem of inlined
defensive checks.

Sometimes the CFG may contain more blocks, but in practice it still has
linear structure because all directions (except, at most, one) of all branches
turned out to be unreachable. When this happens, still treat the function
as "small". This is useful, in particular, for dealing with C++17 if constexpr.

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

llvm-svn: 359531
2019-04-30 03:01:02 +00:00
Artem Dergachev eb71c0c961 [analyzer] SmartPtrModeling: Fix a null dereference.
Don't crash when trying to model a call in which the callee is unknown
in compile time, eg. a pointer-to-member call.

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

llvm-svn: 359530
2019-04-30 03:00:57 +00:00
Artem Dergachev 48e7a2fa8c [analyzer] RetainCount: Add a suppression for "the Matching rule".
In the OSObject universe there appears to be another slightly popular contract,
apart from "create" and "get", which is "matching". It optionally consumes
a "table" parameter and if a table is passed, it fills in the table and
returns it at +0; otherwise, it creates a new table, fills it in and
returns it at +1.

For now suppress false positives by doing a conservative escape on all functions
that end with "Matching", which is the naming convention that seems to be
followed by all such methods.

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

llvm-svn: 359264
2019-04-26 02:05:18 +00:00
Artem Dergachev e264ac6ae1 [analyzer] RetainCount: Allow offsets in return values.
Because RetainCountChecker has custom "local" reasoning about escapes,
it has a separate facility to deal with tracked symbols at end of analysis
and check them for leaks regardless of whether they're dead or not.
This facility iterates over the list of tracked symbols and reports
them as leaks, but it needs to treat the return value specially.

Some custom allocators tend to return the value with an offset, storing
extra metadata at the beginning of the buffer. In this case the return value
would be a non-base region. In order to avoid false positives, we still need to
find the original symbol within the return value, otherwise it'll be unable
to match it to the item in the list of tracked symbols.

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

llvm-svn: 359263
2019-04-26 02:05:15 +00:00
Artem Dergachev b591845f4b [analyzer] Fix crash when returning C++ objects from ObjC messages-to-nil.
the assertion is in fact incorrect: there is a cornercase in Objective-C++
in which a C++ object is not constructed with a constructor, but merely
zero-initialized. Namely, this happens when an Objective-C message is sent
to a nil and it is supposed to return a C++ object.

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

llvm-svn: 359262
2019-04-26 02:05:12 +00:00
Artem Dergachev ecefce6a49 [analyzer] Add FIXMEs for alpha.unix.cstring.OutOfBounds false positives.
Caused by incorrect strlcat() modeling in r332303,
cf. https://bugs.llvm.org/show_bug.cgi?id=37687#c8

llvm-svn: 359237
2019-04-25 20:30:14 +00:00
Kristof Umann f46c58e0c6 [analyzer][UninitializedObjectChecker] PR41590: Regard _Atomic types as primitive
https://bugs.llvm.org/show_bug.cgi?id=41590

For the following code snippet, UninitializedObjectChecker crashed:

struct MyAtomicInt {
  _Atomic(int) x;
  MyAtomicInt() {}
};

void entry() {
  MyAtomicInt b;
}

The problem was that _Atomic types were not regular records, unions,
dereferencable or primitive, making the checker hit the llvm_unreachable at
lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp:347.
The solution is to regard these types as primitive as well. The test case shows
that with this addition, not only are we able to get rid of the crash, but we
can identify x as uninitialized.

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

llvm-svn: 359230
2019-04-25 20:00:51 +00:00
Richard Smith 3ac3e9ce04 Add missing diagnostic for anonymous struct/union definitions that don't
introduce any names.

llvm-svn: 359051
2019-04-24 00:08:02 +00:00
Artem Dergachev a746f2b73c [analyzer] Fix macro names in diagnostics within bigger macros.
If macro "CHECK_X(x)" expands to something like "if (x != NULL) ...",
the "Assuming..." note no longer says "Assuming 'x' is equal to CHECK_X".

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

llvm-svn: 359037
2019-04-23 21:30:30 +00:00
Rafael Stahl 850361f6c1 [analyzer][CrossTU] Extend CTU to VarDecls with initializer
Summary:
The existing CTU mechanism imports `FunctionDecl`s where the definition is available in another TU. This patch extends that to VarDecls, to bind more constants.

- Add VarDecl importing functionality to CrossTranslationUnitContext
- Import Decls while traversing them in AnalysisConsumer
- Add VarDecls to CTU external mappings generator
- Name changes from "external function map" to "external definition map"

Reviewers: NoQ, dcoughlin, xazax.hun, george.karpenkov, martong

Reviewed By: xazax.hun

Subscribers: Charusso, baloghadamsoftware, mikhail.ramalho, Szelethus, donat.nagy, dkrupp, george.karpenkov, mgorny, whisperity, szepet, rnkovacs, a.sidorin, cfe-commits

Tags: #clang

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

llvm-svn: 358968
2019-04-23 11:04:41 +00:00
Artem Dergachev 727d6ca3f0 [analyzer] Unbreak body farms in presence of multiple declarations.
When growing a body on a body farm, it's essential to use the same redeclaration
of the function that's going to be used during analysis. Otherwise our
ParmVarDecls won't match the ones that are used to identify argument regions.

This boils down to trusting the reasoning in AnalysisDeclContext. We shouldn't
canonicalize the declaration before farming the body because it makes us not
obey the sophisticated decision-making process of AnalysisDeclContext.

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

llvm-svn: 358946
2019-04-23 02:56:00 +00:00
Artem Dergachev e2a8e43160 [analyzer] PR41335: Fix crash when no-store event is in a body-farmed function.
Stuffing invalid source locations (such as those in functions produced by
body farms) into path diagnostics causes crashes.

Fix a typo in a nearby function name.

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

llvm-svn: 358945
2019-04-23 02:50:38 +00:00
Artem Dergachev 8c6119a442 [analyzer] PR41269: Add a bit of C++ smart pointer modeling.
Implement cplusplus.SmartPtrModeling, a new checker that doesn't
emit any warnings but models methods of smart pointers more precisely.

For now the only thing it does is make `(bool) P` return false when `P`
is a freshly moved pointer. This addresses a false positive in the
use-after-move-checker.

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

llvm-svn: 358944
2019-04-23 02:45:42 +00:00
Kristof Umann 85e0ff752c [analyzer] Move UninitializedObjectChecker out of alpha
Moved UninitializedObjectChecker from the 'alpha.cplusplus' to the
'optin.cplusplus' package.

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

llvm-svn: 358797
2019-04-19 23:33:50 +00:00
Artem Dergachev 0a7dd5a2a4 Reapply "[analyzer] Introduce a simplified API for adding custom path notes."
This reapplies commit r357323, fixing memory leak found by LSan.

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

llvm-svn: 358781
2019-04-19 20:23:29 +00:00
Kristof Umann b4788b26e2 [analyzer][NFC] Reimplement checker options
TL;DR:

* Add checker and package options to the TableGen files
* Added a new class called CmdLineOption, and both Package and Checker recieved
   a list<CmdLineOption> field.
* Added every existing checker and package option to Checkers.td.
* The CheckerRegistry class
  * Received some comments to most of it's inline classes
  * Received the CmdLineOption and PackageInfo inline classes, a list of
     CmdLineOption was added to CheckerInfo and PackageInfo
  * Added addCheckerOption and addPackageOption
  * Added a new field called Packages, used in addPackageOptions, filled up in
     addPackage

Detailed description:

In the last couple months, a lot of effort was put into tightening the
analyzer's command line interface. The main issue is that it's spectacularly
easy to mess up a lenghty enough invocation of the analyzer, and the user was
given no warnings or errors at all in that case.

We can divide the effort of resolving this into several chapters:

* Non-checker analyzer configurations:
    Gather every analyzer configuration into a dedicated file. Emit errors for
    non-existent configurations or incorrect values. Be able to list these
    configurations. Tighten AnalyzerOptions interface to disallow making such
    a mistake in the future.

* Fix the "Checker Naming Bug" by reimplementing checker dependencies:
    When cplusplus.InnerPointer was enabled, it implicitly registered
    unix.Malloc, which implicitly registered some sort of a modeling checker
    from the CStringChecker family. This resulted in all of these checker
    objects recieving the name "cplusplus.InnerPointer", making AnalyzerOptions
    asking for the wrong checker options from the command line:
      cplusplus.InnerPointer:Optimisic
    istead of
      unix.Malloc:Optimistic.
    This was resolved by making CheckerRegistry responsible for checker
    dependency handling, instead of checkers themselves.

* Checker options: (this patch included!)
    Same as the first item, but for checkers.

(+ minor fixes here and there, and everything else that is yet to come)

There were several issues regarding checker options, that non-checker
configurations didn't suffer from: checker plugins are loaded runtime, and they
could add new checkers and new options, meaning that unlike for non-checker
configurations, we can't collect every checker option purely by generating code.
Also, as seen from the "Checker Naming Bug" issue raised above, they are very
rarely used in practice, and all sorts of skeletons fell out of the closet while
working on this project.

They were extremely problematic for users as well, purely because of how long
they were. Consider the following monster of a checker option:

  alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=false

While we were able to verify whether the checker itself (the part before the
colon) existed, any errors past that point were unreported, easily resulting
in 7+ hours of analyses going to waste.

This patch, similarly to how dependencies were reimplemented, uses TableGen to
register checker options into Checkers.td, so that Checkers.inc now contains
entries for both checker and package options. Using the preprocessor,
Checkers.inc is converted into code in CheckerRegistry, adding every builtin
(checkers and packages that have an entry in the Checkers.td file) checker and
package option to the registry. The new addPackageOption and addCheckerOption
functions expose the same functionality to statically-linked non-builtin and
plugin checkers and packages as well.

Emitting errors for incorrect user input, being able to list these options, and
some other functionalies will land in later patches.

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

llvm-svn: 358752
2019-04-19 12:32:10 +00:00
Kristof Umann cd3f147439 [analyzer] Fix an assertion failure if plugins added dependencies
Ideally, there is no reason behind not being able to depend on checkers that
come from a different plugin (or on builtin checkers) -- however, this is only
possible if all checkers are added to the registry before resolving checker
dependencies. Since I used a binary search in my addDependency method, this also
resulted in an assertion failure (due to CheckerRegistry::Checkers not being
sorted), since the function used by plugins to register their checkers
(clang_registerCheckers) calls addDependency.

This patch resolves this issue by only noting which dependencies have to
established when addDependency is called, and resolves them at a later stage
when no more checkers are added to the registry, by which point
CheckerRegistry::Checkers is already sorted.

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

llvm-svn: 358750
2019-04-19 11:01:35 +00:00
Artem Dergachev 9b02a9b401 [analyzer] Make default bindings to variables actually work.
Default RegionStore bindings represent values that can be obtained by loading
from anywhere within the region, not just the specific offset within the region
that they are said to be bound to. For example, default-binding a character \0
to an int (eg., via memset()) means that the whole int is 0, not just
that its lower byte is 0.

Even though memset and bzero were modeled this way, it didn't work correctly
when applied to simple variables. Eg., in

  int x;
  memset(x, 0, sizeof(x));

we did produce a default binding, but were unable to read it later, and 'x'
was perceived as an uninitialized variable even after memset.

At the same time, if we replace 'x' with a variable of a structure or array
type, accessing fields or elements of such variable was working correctly,
which was enough for most cases. So this was only a problem for variables of
simple integer/enumeration/floating-point/pointer types.

Fix loading default bindings from RegionStore for regions of simple variables.

Add a unit test to document the API contract as well.

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

llvm-svn: 358722
2019-04-18 23:35:56 +00:00
Artem Dergachev 6b71e27c94 [analyzer] NFC: MoveChecker: Refactor tests to use -verify=prefix.
This -verify=prefix feature is quite underrated.

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

llvm-svn: 358719
2019-04-18 23:17:58 +00:00
Douglas Yung 3333cc6643 Fix test on PS4 which defaults to gnu99 which does not emit the expected warnings.
llvm-svn: 358626
2019-04-18 00:00:06 +00:00
Kristof Umann 25e592e522 [analyzer] PR41185: Fix regression where __builtin_* functions weren't recognized
For the following code snippet:

void builtin_function_call_crash_fixes(char *c) {
  __builtin_strncpy(c, "", 6);
  __builtin_memset(c, '\0', (0));
  __builtin_memcpy(c, c, 0);
}
security.insecureAPI.DeprecatedOrUnsafeBufferHandling caused a regression, as it
didn't recognize functions starting with __builtin_. Fixed exactly that.

I wanted to modify an existing test file, but the two I found didn't seem like
perfect candidates. While I was there, I prettified their RUN: lines.

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

llvm-svn: 358609
2019-04-17 19:56:40 +00:00
Artem Dergachev 7d4694547a [analyzer] Escape pointers stored into top-level parameters with destructors.
Writing stuff into an argument variable is usually equivalent to writing stuff
to a local variable: it will have no effect outside of the function.
There's an important exception from this rule: if the argument variable has
a non-trivial destructor, the destructor would be invoked on
the parent stack frame, exposing contents of the otherwise dead
argument variable to the caller.

If such argument is the last place where a pointer is stored before the function
exits and the function is the one we've started our analysis from (i.e., we have
no caller context for it), we currently diagnose a leak. This is incorrect
because the destructor of the argument still has access to the pointer.
The destructor may deallocate the pointer or even pass it further.

Treat writes into such argument regions as "escapes" instead, suppressing
spurious memory leak reports but not messing with dead symbol removal.

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

llvm-svn: 358321
2019-04-13 02:01:45 +00:00
Artem Dergachev 5c6fc36de8 [analyzer] NoStoreFuncVisitor: Suppress reports with no-store in system headers.
The idea behind this heuristic is that normally the visitor is there to
inform the user that a certain function may fail to initialize a certain
out-parameter. For system header functions this is usually dictated by the
contract, and it's unlikely that the header function has accidentally
forgot to put the value into the out-parameter; it's more likely
that the user has intentionally skipped the error check.

Warnings on skipped error checks are more like security warnings;
they aren't necessarily useful for all users, and they should instead
be introduced on a per-API basis.

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

llvm-svn: 357810
2019-04-05 20:18:53 +00:00
Artem Dergachev 3d90e7e8db Revert "[analyzer] Toning down invalidation a bit".
This reverts commit r352473.

The overall idea is great, but it seems to cause unintented consequences
when not only Region Store invalidation but also pointer escape mechanism
was accidentally affected.

Based on discussions in https://reviews.llvm.org/D58121#1452483
and https://reviews.llvm.org/D57230#1434161

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

llvm-svn: 357620
2019-04-03 18:21:16 +00:00
Xing GUO 884c29e9ae Fix typos in tests. NFC.
Reviewers: Higuoxing

Reviewed By: Higuoxing

Subscribers: kubamracek, cfe-commits, #sanitizers, llvm-commits

Tags: #clang, #sanitizers, #llvm

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

llvm-svn: 357577
2019-04-03 13:15:09 +00:00
Artem Dergachev f7887d41cb [analyzer] When failing to evaluate a __builtin_constant_p, presume it's false.
__builtin_constant_p(x) is a compiler builtin that evaluates to 1 when
its argument x is a compile-time constant and to 0 otherwise. In CodeGen
it is simply lowered to the respective LLVM intrinsic. In the Analyzer
we've been trying to delegate modeling to Expr::EvaluateAsInt, which is
allowed to sometimes fail for no apparent reason.

When it fails, let's conservatively return false. Modeling it as false
is pretty much never wrong, and it is only required to return true
on a best-effort basis, which every user should expect.

Fixes VLAChecker false positives on code that tries to emulate
static asserts in C by constructing a VLA of dynamic size -1 under the
assumption that this dynamic size is actually a constant
in the sense of __builtin_constant_p.

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

llvm-svn: 357557
2019-04-03 01:53:40 +00:00
Artem Dergachev a3c9d88233 [analyzer] MIGChecker: Add support for more deallocator APIs.
Differential Revision: https://reviews.llvm.org/D59914

llvm-svn: 357335
2019-03-29 23:56:53 +00:00
Artem Dergachev 4d6fb5789f Revert "[analyzer] Introduce a simplified API for adding custom path notes."
This reverts commit r357323.

ASan leaks found by a buildbot :)

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

llvm-svn: 357332
2019-03-29 23:11:10 +00:00
Artem Dergachev 388e19ff1f [analyzer] PR41239: Fix a crash on invalid source location in NoStoreFuncVisitor.
It turns out that SourceManager::isInSystemHeader() crashes when an invalid
source location is passed into it. Invalid source locations are relatively
common: not only they come from body farms, but also, say, any function in C
that didn't come with a forward declaration would have an implicit
forward declaration with invalid source locations.

There's a more comfy API for us to use in the Static Analyzer:
CallEvent::isInSystemHeader(), so just use that.

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

llvm-svn: 357329
2019-03-29 22:57:49 +00:00
Artem Dergachev 44551cf693 [analyzer] Move taint API from ProgramState to a separate header. NFC.
It is now an inter-checker communication API, similar to the one that
connects MallocChecker/CStringChecker/InnerPointerChecker: simply a set of
setters and getters for a state trait.

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

llvm-svn: 357326
2019-03-29 22:49:30 +00:00
Artem Dergachev 60cde76f70 [analyzer] PR37501: Disable assertion for logical op short circuit evaluation.
The transfer function for the CFG element that represents a logical operation
computes the value of the operation and does nothing else. The element
appears after all the short circuit decisions were made, so they don't need
to be made again at this point.

Because our expression evaluation is imprecise, it is often hard to
discriminate between:

  (1) we don't know the value of the RHS because we failed to evaluate it

and

  (2) we don't know the value of the RHS because it didn't need to be evaluated.

This is hard because it depends on our knowledge about the value of the LHS
(eg., if LHS is true, then RHS in (LHS || RHS) doesn't need to be computed)
but LHS itself may have been evaluated imprecisely and we don't know whether
it is true or not. Additionally, the Analyzer wouldn't necessarily even remember
what the value of the LHS was because theoretically it's not really necessary
to know it for any future evaluations.

In order to work around these issues, the transfer function for logical
operations consists in looking at the ExplodedGraph we've constructed so far
in order to figure out from which CFG direction did we arrive here.
Such post-factum backtracking that doesn't involve looking up LHS and RHS values
is usually possible. However sometimes it fails because when we deduplicate
exploded nodes with the same program point and the same program state we may end
up in a situation when we reached the same program point from two or more
different directions.

By removing the assertion, we admit that the procedure indeed sometimes fails to
work. When it fails, we also admit that we don't know the value of the logical
operator.

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

llvm-svn: 357325
2019-03-29 22:43:34 +00:00
Artem Dergachev 6b39f10a00 [analyzer] Introduce a simplified API for adding custom path notes.
Almost all path-sensitive checkers need to tell the user when something specific
to that checker happens along the execution path but does not constitute a bug
on its own. For instance, a call to operator delete in C++ has consequences
that are specific to a use-after-free bug. Deleting an object is not a bug
on its own, but when the Analyzer finds an execution path on which a deleted
object is used, it'll have to explain to the user when exactly during that path
did the deallocation take place.

Historically such custom notes were added by implementing "bug report visitors".
These visitors were post-processing bug reports by visiting every ExplodedNode
along the path and emitting path notes whenever they noticed that a change that
is relevant to a bug report occurs within the program state. For example,
it emits a "memory is deallocated" note when it notices that a pointer changes
its state from "allocated" to "deleted".

The "visitor" approach is powerful and efficient but hard to use because
such preprocessing implies that the developer first models the effects
of the event (say, changes the pointer's state from "allocated" to "deleted"
as part of operator delete()'s transfer function) and then forgets what happened
and later tries to reverse-engineer itself and figure out what did it do
by looking at the report.

The proposed approach tries to avoid discarding the information that was
available when the transfer function was evaluated. Instead, it allows the
developer to capture all the necessary information into a closure that
will be automatically invoked later in order to produce the actual note.

This should reduce boilerplate and avoid very painful logic duplication.

On the technical side, the closure is a lambda that's put into a special kind of
a program point tag, and a special bug report visitor visits all nodes in the
report and invokes all note-producing closures it finds along the path.

For now it is up to the lambda to make sure that the note is actually relevant
to the report. For instance, a memory deallocation note would be irrelevant when
we're reporting a division by zero bug or if we're reporting a use-after-free
of a different, unrelated chunk of memory. The lambda can figure these thing out
by looking at the bug report object that's passed into it.

A single checker is refactored to make use of the new functionality: MIGChecker.
Its program state is trivial, making it an easy testing ground for the first
version of the API.

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

llvm-svn: 357323
2019-03-29 22:21:00 +00:00
Adam Balogh a19c985f8a [Analyzer] Constraint Manager - Calculate Effective Range for Differences
Since rL335814, if the constraint manager cannot find a range set for `A - B`
(where `A` and `B` are symbols) it looks for a range for `B - A` and returns
it negated if it exists. However, if a range set for both `A - B` and `B - A`
is stored then it only returns the first one. If we both use `A - B` and
`B - A`, these expressions behave as two totally unrelated symbols. This way
we miss some useful deductions which may lead to false negatives or false
positives.

This tiny patch changes this behavior: if the symbolic expression the
constraint manager is looking for is a difference `A - B`, it tries to
retrieve the range for both `A - B` and `B - A` and if both exists it returns
the intersection of range `A - B` and the negated range of `B - A`. This way
every time a checker applies new constraints to the symbolic difference or to
its negated it always affects both the original difference and its negated.

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

llvm-svn: 357167
2019-03-28 13:05:59 +00:00
Artem Dergachev bef9f8aac3 [CFG] [analyzer] pr41142: C++17: Skip transparent InitListExprs in ExprEngine.
r356634 didn't fix all the problems caused by r356222 - even though simple
constructors involving transparent init-list expressions are now evaluated
precisely, many more complicated constructors aren't, for other reasons.

The attached test case is an example of a constructor that will never be
evaluated precisely - simply because there isn't a constructor there (instead,
the program invokes run-time undefined behavior by returning without a return
statement that should have constructed the return value).

Fix another part of the problem for such situations: evaluate transparent
init-list expressions transparently, so that to avoid creating ill-formed
"transparent" nonloc::CompoundVals.

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

llvm-svn: 356969
2019-03-26 00:36:53 +00:00
Artem Dergachev aa40315c69 [CFG] [analyzer] pr41142: C++17: Skip transparent InitListExprs in constructors.
When searching for construction contexts, i.e. figuring out which statements
define the object that is constructed by each construct-expression, ignore
transparent init-list expressions because they don't add anything to the
context. This allows the Static Analyzer to model construction, destruction,
materialization, lifetime extension correctly in more cases. Also fixes
a crash caused by incorrectly evaluating initial values of variables
initialized with such expressions.

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

llvm-svn: 356634
2019-03-21 00:15:07 +00:00
Erik Pilkington b6e16ea006 [Sema] Add some compile time _FORTIFY_SOURCE diagnostics
These diagnose overflowing calls to subset of fortifiable functions. Some
functions, like sprintf or strcpy aren't supported right not, but we should
probably support these in the future. We previously supported this kind of
functionality with -Wbuiltin-memcpy-chk-size, but that diagnostic doesn't work
with _FORTIFY implementations that use wrapper functions. Also unlike that
diagnostic, we emit these warnings regardless of whether _FORTIFY_SOURCE is
actually enabled, which is nice for programs that don't enable the runtime
checks.

Why not just use diagnose_if, like Bionic does? We can get better diagnostics in
the compiler (i.e. mention the sizes), and we have the potential to diagnose
sprintf and strcpy which is impossible with diagnose_if (at least, in languages
that don't support C++14 constexpr). This approach also saves standard libraries
from having to add diagnose_if.

rdar://48006655

Differential revision: https://reviews.llvm.org/D58797

llvm-svn: 356397
2019-03-18 19:23:45 +00:00
Csaba Dabis 9ea2f9079d [analyzer] ConditionBRVisitor: Unknown condition evaluation support
Summary:
If the constraint information is not changed between two program states the
analyzer has not learnt new information and made no report. But it is
possible to happen because we have no information at all. The new approach
evaluates the condition to determine if that is the case and let the user
know we just `Assuming...` some value.

Reviewers: NoQ, george.karpenkov

Reviewed By: NoQ

Subscribers: llvm-commits, xazax.hun, baloghadamsoftware, szepet, a.sidorin,
mikhail.ramalho, Szelethus, donat.nagy, dkrupp, gsd, gerazo

Tags: #clang, #llvm

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

llvm-svn: 356323
2019-03-16 13:47:55 +00:00
Csaba Dabis e282b30c58 Revert "[analyzer] ConditionBRVisitor: Unknown condition evaluation support"
This reverts commit 0fe67a61cd.

llvm-svn: 356320
2019-03-16 10:06:06 +00:00
Csaba Dabis 0fe67a61cd [analyzer] ConditionBRVisitor: Unknown condition evaluation support
Summary: If the constraint information is not changed between two program states the analyzer has not learnt new information and made no report. But it is possible to happen because we have no information at all. The new approach evaluates the condition to determine if that is the case and let the user know we just 'Assuming...' some value.

Reviewers: NoQ, george.karpenkov

Reviewed By: NoQ

Subscribers: xazax.hun, baloghadamsoftware, szepet, a.sidorin, mikhail.ramalho, Szelethus, donat.nagy, dkrupp, gsd, gerazo

Tags: #clang

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

llvm-svn: 356319
2019-03-16 09:24:30 +00:00
Artem Dergachev f2192b204f [analyzer] RetainCount: A function isn't a CFRetain if it takes no arguments.
Don't crash when a function has a name that starts with "CF" and ends with
"Retain" but takes 0 arguments. In particular, don't try to treat it as if
it returns its first argument.

These problems are inevitable because the checker is naming-convention-based,
but at least we shouldn't crash.

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

llvm-svn: 356223
2019-03-15 00:26:17 +00:00
Artem Dergachev 06451368d2 [analyzer] Support C++17 aggregates with bases without constructors.
RegionStore now knows how to bind a nonloc::CompoundVal that represents the
value of an aggregate initializer when it has its initial segment of sub-values
correspond to base classes.

Additionally, fixes the crash from pr40022.

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

llvm-svn: 356222
2019-03-15 00:22:59 +00:00
Kristof Umann 4962816e72 [analyzer] Fix an assertation failure for invalid sourcelocation, add a new debug checker
For a rather short code snippet, if debug.ReportStmts (added in this patch) was
enabled, a bug reporter visitor crashed:

struct h {
  operator int();
};

int k() {
  return h();
}

Ultimately, this originated from PathDiagnosticLocation::createMemberLoc, as it
didn't handle the case where it's MemberExpr typed parameter returned and
invalid SourceLocation for MemberExpr::getMemberLoc. The solution was to find
any related valid SourceLocaion, and Stmt::getBeginLoc happens to be just that.

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

llvm-svn: 356161
2019-03-14 16:10:29 +00:00
Kristof Umann 7b907bed3c [analyzer] Fix function macro crash
Re-commit D57893.

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

llvm-svn: 356142
2019-03-14 13:38:16 +00:00
Mandeep Singh Grang 6952b82c67 [Analyzer] Clean up test/Analysis/ptr-sort.cpp
llvm-svn: 356088
2019-03-13 19:21:11 +00:00
Adam Balogh d703305e40 [Analyzer] Skip symbolic regions based on conjured symbols in comparison of the containers of iterators
Checking whether two regions are the same is a partially decidable problem:
either we know for sure that they are the same or we cannot decide. A typical
case for this are the symbolic regions based on conjured symbols. Two
different conjured symbols are either the same or they are different. Since
we cannot decide this and want to reduce false positives as much as possible
we exclude these regions whenever checking whether two containers are the
same at iterator mismatch check.

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

llvm-svn: 356049
2019-03-13 13:55:11 +00:00
Kristof Umann e58dde2a80 Revert "[analyzer] Fix function macro crash"
Buildbot breaks when LLVm is compiled with memory sanitizer.

WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0xa3d16d8 in getMacroNameAndPrintExpansion(blahblah)
                             lib/StaticAnalyzer/Core/PlistDiagnostics.cpp:903:11
llvm-svn: 355911
2019-03-12 11:22:30 +00:00