Commit Graph

178 Commits

Author SHA1 Message Date
Tomasz Kamiński 4ff836a138 [analyzer] Pass correct bldrCtx to computeObjectUnderConstruction
In case when the prvalue is returned from the function (kind is one
of `SimpleReturnedValueKind`, `CXX17ElidedCopyReturnedValueKind`),
then it construction happens in context of the caller.
We pass `BldrCtx` explicitly, as `currBldrCtx` will always refer to callee
context.

In the following example:
```
struct Result {int value; };
Result create() { return Result{10}; }
int accessValue(Result r) { return r.value; }

void test() {
   for (int i = 0; i < 2; ++i)
      accessValue(create());
}
```

In case when the returned object was constructed directly into the
argument to a function call `accessValue(create())`, this led to
inappropriate value of `blockCount` being used to locate parameter region,
and as a consequence resulting object (from `create()`) was constructed
into a different region, that was later read by inlined invocation of
outer function (`accessValue`).
This manifests itself only in case when calling block is visited more
than once (loop in above example), as otherwise there is no difference
in `blockCount` value between callee and caller context.
This happens only in case when copy elision is disabled (before C++17).

Reviewed By: NoQ

Differential Revision: https://reviews.llvm.org/D132030
2022-09-26 11:39:10 +02:00
isuckatcs e3e9082b01 [analyzer] Fix for incorrect handling of 0 length non-POD array construction
Prior to this patch when the analyzer encountered a non-POD 0 length array,
it still invoked the constructor for 1 element, which lead to false positives.
This patch makes sure that we no longer construct any elements when we see a
0 length array.

Differential Revision: https://reviews.llvm.org/D131501
2022-08-25 12:42:02 +02:00
isuckatcs aac73a31ad [analyzer] Process non-POD array element destructors
The constructors of non-POD array elements are evaluated under
certain conditions. This patch makes sure that in such cases
we also evaluate the destructors.

Differential Revision: https://reviews.llvm.org/D130737
2022-08-24 01:28:21 +02:00
isuckatcs c81bf940c7 [analyzer] Handling non-POD multidimensional arrays in ArrayInitLoopExpr
This patch makes it possible for lambdas, implicit copy/move ctors
and structured bindings to handle non-POD multidimensional arrays.

Differential Revision: https://reviews.llvm.org/D131840
2022-08-22 13:53:53 +02:00
isuckatcs 3c482632e6 [analyzer] Remove pattern matching of lambda capture initializers
Prior to this patch we handled lambda captures based on their
initializer expression, which resulted in pattern matching. With
C++17 copy elision the initializer expression can be anything,
and this approach proved to be fragile and a source of crashes.
This patch removes pattern matching and only checks whether the
object is under construction or not.

Differential Revision: https://reviews.llvm.org/D131944
2022-08-22 13:00:31 +02:00
isuckatcs b4e3e3a3eb [analyzer] Fix a crash on copy elided initialized lambda captures
Inside `ExprEngine::VisitLambdaExpr()` we wasn't prepared for a
copy elided initialized capture's `InitExpr`. This patch teaches
the analyzer how to handle such situation.

Differential Revision: https://reviews.llvm.org/D131784
2022-08-13 00:22:01 +02:00
Fangrui Song 3f18f7c007 [clang] LLVM_FALLTHROUGH => [[fallthrough]]. NFC
With C++17 there is no Clang pedantic warning or MSVC C5051.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D131346
2022-08-08 09:12:46 -07:00
David Spickett f3fbbe1cf3 [clang][analyzer][NFC] Use value_or instead of ValueOr
The latter is deprecated.
2022-07-26 09:16:45 +00:00
isuckatcs 996b092c5e [analyzer] Lambda capture non-POD type array
This patch introduces a new `ConstructionContext` for
lambda capture. This `ConstructionContext` allows the
analyzer to construct the captured object directly into
it's final region, and makes it possible to capture
non-POD arrays.

Differential Revision: https://reviews.llvm.org/D129967
2022-07-26 09:40:25 +02:00
isuckatcs 8a13326d18 [analyzer] ArrayInitLoopExpr with array of non-POD type
This patch introduces the evaluation of ArrayInitLoopExpr
in case of structured bindings and implicit copy/move
constructor. The idea is to call the copy constructor for
every element in the array. The parameter of the copy
constructor is also manually selected, as it is not a part
of the CFG.

Differential Revision: https://reviews.llvm.org/D129496
2022-07-26 09:07:22 +02:00
Kazu Hirata ae002f8bca Use isa instead of dyn_cast (NFC) 2022-07-25 23:00:58 -07:00
Fangrui Song 3c849d0aef Modernize Optional::{getValueOr,hasValue} 2022-07-15 01:20:39 -07:00
isuckatcs b032e3ff61 [analyzer] Evaluate construction of non-POD type arrays
Introducing the support for evaluating the constructor
of every element in an array. The idea is to record the
index of the current array member being constructed and
create a loop during the analysis. We looping over the
same CXXConstructExpr as many times as many elements
the array has.

Differential Revision: https://reviews.llvm.org/D127973
2022-07-14 23:30:21 +02:00
Fred Tingaud 1ec1cdcfb4 [analyzer] Inline operator delete when MayInlineCXXAllocator is set.
This patch restores the symmetry between how operator new and operator delete
are handled by also inlining the content of operator delete when possible.

Patch by Fred Tingaud.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D124845
2022-05-09 15:44:33 +02:00
Simon Pilgrim ca94f28d15 [clang] ExprEngine::VisitCXXNewExpr - remove superfluous nullptr tests
FD has already been dereferenced
2022-03-02 15:59:10 +00:00
Kazu Hirata d0ac215dd5 [clang] Use isa instead of dyn_cast (NFC) 2021-11-14 09:32:40 -08:00
Benjamin Kramer 6a1bca8798 [Analyzer] Fix unused variable warning in Release builds
clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp:377:19: warning: unused variable 'Init'
2020-09-25 14:09:43 +02:00
Adam Balogh facad21b29 [Analyzer] Fix for `ExprEngine::computeObjectUnderConstruction()` for base and delegating consturctor initializers
For /C++/ constructor initializers `ExprEngine:computeUnderConstruction()`
asserts that they are all member initializers. This is not neccessarily
true when this function is used to get the return value for the
construction context thus attempts to fetch return values of base and
delegating constructor initializers result in assertions. This small
patch fixes this issue.

Differential Revision: https://reviews.llvm.org/D85351
2020-09-25 13:28:22 +02:00
Nithin Vadukkumchery Rajendrakumar b34b1e3838 [Analysis] Bug fix for exploded graph branching in evalCall for constructor
Summary:
Make exactly single NodeBuilder exists at any given time

Reviewers: NoQ, Szelethus, vsavchenko, xazax.hun

Reviewed By: NoQ

Subscribers: martong, cfe-commits
Tags: #clang

Differential Revision: https://reviews.llvm.org/D85796
2020-08-19 00:03:31 +02:00
Nithin Vadukkumchery Rajendrakumar 37c1bf21d1 [analyzer] Enable constructor support in evalCall event.
Pass EvalCallOptions via runCheckersForEvalCall into defaultEvalCall.
Update the AnalysisOrderChecker to support evalCall for testing.

Differential Revision: https://reviews.llvm.org/D82256
2020-06-25 09:47:13 -07:00
Adam Balogh 98db1f990f [Analyzer] [NFC] Parameter Regions
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
2020-06-09 12:08:56 +02:00
Adam Balogh 813734dad7 [Analyzer] Add `getReturnValueUnderConstruction()` to `CallEvent`
Checkers should be able to get the return value under construction for a
`CallEvenet`. This patch adds a function to achieve this which retrieves
the return value from the construction context of the call.

Differential Revision: https://reviews.llvm.org/D80366
2020-06-09 12:08:56 +02:00
Kirstóf Umann f2be30def3 [analyzer][NFC] Merge checkNewAllocator's paramaters into CXXAllocatorCall
Party based on this thread:
http://lists.llvm.org/pipermail/cfe-dev/2020-February/064754.html.

This patch merges two of CXXAllocatorCall's parameters, so that we are able to
supply a CallEvent object to check::NewAllocatorCall (see the description of
D75430 to see why this would be great).

One of the things mentioned by @NoQ was the following:

  I think at this point we might actually do a good job sorting out this
  check::NewAllocator issue because we have a "separate" "Environment" to hold
  the other SVal, which is "objects under construction"! - so we should probably
  simply teach CXXAllocatorCall to extract the value from the
  objects-under-construction trait of the program state and we're good.

I had MallocChecker in my crosshair for now, so I admittedly threw together
something as a proof of concept. Now that I know that this effort is worth
pursuing though, I'll happily look for a solution better then demonstrated in
this patch.

Differential Revision: https://reviews.llvm.org/D75431
2020-05-20 00:56:10 +02:00
Kirstóf Umann 9d69072fb8 [analyzer][NFC] Introduce CXXDeallocatorCall, deploy it in MallocChecker
One of the pain points in simplifying MallocCheckers interface by gradually
changing to CallEvent is that a variety of C++ allocation and deallocation
functionalities are modeled through preStmt<...> where CallEvent is unavailable,
and a single one of these callbacks can prevent a mass parameter change.

This patch introduces a new CallEvent, CXXDeallocatorCall, which happens after
preStmt<CXXDeleteExpr>, and can completely replace that callback as
demonstrated.

Differential Revision: https://reviews.llvm.org/D75430
2020-05-19 00:18:38 +02:00
Artem Dergachev a82ffe9d93 [analyzer] Add support for CXXInheritedCtorInitExpr.
So far we've been dropping coverage every time we've encountered
a CXXInheritedCtorInitExpr. This patch attempts to add some
initial support for it.

Constructors for arguments of a CXXInheritedCtorInitExpr are still
not fully supported.

Differential Revision: https://reviews.llvm.org/D74735
2020-02-25 18:37:23 +03:00
Tyker b0561b3346 [NFC] Refactor representation of materialized temporaries
Summary:
this patch refactor representation of materialized temporaries to prevent an issue raised by rsmith in https://reviews.llvm.org/D63640#inline-612718

Reviewers: rsmith, martong, shafik

Reviewed By: rsmith

Subscribers: thakis, sammccall, ilya-biryukov, rnkovacs, arphaman, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D69360
2019-11-19 18:20:45 +01:00
Nico Weber c9276fbfdf Revert "[NFC] Refactor representation of materialized temporaries"
This reverts commit 08ea1ee2db.
It broke ./ClangdTests/FindExplicitReferencesTest.All
on the bots, see comments on https://reviews.llvm.org/D69360
2019-11-17 02:09:25 -05:00
Tyker 08ea1ee2db [NFC] Refactor representation of materialized temporaries
Summary:
this patch refactor representation of materialized temporaries to prevent an issue raised by rsmith in https://reviews.llvm.org/D63640#inline-612718

Reviewers: rsmith, martong, shafik

Reviewed By: rsmith

Subscribers: rnkovacs, arphaman, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D69360
2019-11-16 17:56:09 +01:00
Kristof Umann 72649423c0 [analyzer][NFC] Fix inconsistent references to checkers as "checks"
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
2019-09-12 19:09:24 +00:00
Artem Dergachev 630f7daf80 [analyzer] Fix analyzer warnings on analyzer.
Write tests for the actual crash that was found. Write comments and refactor
code around 17 style bugs and suppress 3 false positives.

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

llvm-svn: 370246
2019-08-28 18:44:38 +00:00
Artem Dergachev 8eb7a74b78 [analyzer] Fix a crash when destroying a non-region.
Add defensive check that prevents a crash when we try to evaluate a destructor
whose this-value is a concrete integer that isn't a null.

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

llvm-svn: 369450
2019-08-20 21:41:17 +00:00
Csaba Dabis 7740c6d643 [analyzer] StackFrameContext: Add NodeBuilderContext::blockCount() to its profile
Summary:
It allows discriminating between stack frames of the same call that is
called multiple times in a loop.

Thanks to Artem Dergachev for the great idea!

Reviewed By: NoQ

Tags: #clang

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

llvm-svn: 367608
2019-08-01 20:41:13 +00:00
Artem Dergachev 192a7474d6 [CFG] Add branch to skip vbase inits when they're handled by superclass.
This patch adds the run-time CFG branch that would skip initialization of
virtual base classes depending on whether the constructor is called from a
superclass constructor or not. Previously the Static Analyzer was already
skipping virtual base-class initializers in such constructors, but it wasn't
skipping their arguments and their potential side effects, which was causing
pr41300 (and was generally incorrect). The previous skipping behavior is
now replaced with a hard assertion that we're not even getting there due
to how our CFG works.

The new CFG element is under a CFG build option so that not to break other
consumers of the CFG by this change. Static Analyzer support for this change
is implemented.

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

llvm-svn: 361681
2019-05-24 23:37:08 +00:00
Artem Dergachev b3fc9df481 [analyzer] Fix a crash when doing RVO from within blocks.
When looking for the location context of the call site, unwrap block invocation
contexts because they are attached to the current AnalysisDeclContext
while what we need is the previous AnalysisDeclContext.

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

llvm-svn: 360202
2019-05-07 22:33:13 +00:00
Chandler Carruth 2946cd7010 Update the file headers across all of the LLVM projects in the monorepo
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
2019-01-19 08:50:56 +00:00
Artem Dergachev 097a049740 [analyzer] pr37688: Fix a crash upon evaluating a deleted destructor of a union.
Add a defensive check against an invalid destructor in the CFG.

Unions with fields with destructors have their own destructor implicitly
deleted. Due to a bug in the CFG we're still trying to evaluate them
at the end of the object's lifetime and crash because we are unable
to find the destructor's declaration.

rdar://problem/47362608

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

llvm-svn: 351610
2019-01-18 23:05:07 +00:00
Artem Dergachev 179064983a [analyzer] Improve modeling for returning an object from the top frame with RVO.
Static Analyzer processes the program function-by-function, sometimes diving
into other functions ("inlining" them). When an object is returned from an
inlined function, Return Value Optimization is modeled, and the returned object
is constructed at its return location directly.

When an object is returned from the function from which the analysis has started
(the top stack frame of the analysis), the return location is unknown. Model it
with a SymbolicRegion based on a conjured symbol that is specifically tagged for
that purpose, because this is generally the correct way to symbolicate
unknown locations in Static Analyzer.

Fixes leak false positives when an object is returned from top frame in C++17:
objects that are put into a SymbolicRegion-based memory region automatically
"escape" and no longer get reported as leaks. This only applies to C++17 return
values with destructors, because it produces a redundant CXXBindTemporaryExpr
in the call site, which confuses our liveness analysis. The actual fix
for liveness analysis is still pending, but it is no longer causing problems.

Additionally, re-enable temporary destructor tests in C++17.

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

rdar://problem/46217550

llvm-svn: 349696
2018-12-19 23:14:06 +00:00
Kristof Umann 549f9cd46f [analyzer] Evaluate all non-checker config options before analysis
In earlier patches regarding AnalyzerOptions, a lot of effort went into
gathering all config options, and changing the interface so that potential
misuse can be eliminited.

Up until this point, AnalyzerOptions only evaluated an option when it was
querried. For example, if we had a "-no-false-positives" flag, AnalyzerOptions
would store an Optional field for it that would be None up until somewhere in
the code until the flag's getter function is called.

However, now that we're confident that we've gathered all configs, we can
evaluate off of them before analysis, so we can emit a error on invalid input
even if that prticular flag will not matter in that particular run of the
analyzer. Another very big benefit of this is that debug.ConfigDumper will now
show the value of all configs every single time.

Also, almost all options related class have a similar interface, so uniformity
is also a benefit.

The implementation for errors on invalid input will be commited shorty.

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

llvm-svn: 348031
2018-11-30 20:44:00 +00:00
Reid Kleckner 4dc0b1ac60 Fix clang -Wimplicit-fallthrough warnings across llvm, NFC
This patch should not introduce any behavior changes. It consists of
mostly one of two changes:
1. Replacing fall through comments with the LLVM_FALLTHROUGH macro
2. Inserting 'break' before falling through into a case block consisting
   of only 'break'.

We were already using this warning with GCC, but its warning behaves
slightly differently. In this patch, the following differences are
relevant:
1. GCC recognizes comments that say "fall through" as annotations, clang
   doesn't
2. GCC doesn't warn on "case N: foo(); default: break;", clang does
3. GCC doesn't warn when the case contains a switch, but falls through
   the outer case.

I will enable the warning separately in a follow-up patch so that it can
be cleanly reverted if necessary.

Reviewers: alexfh, rsmith, lattner, rtrieu, EricWF, bollu

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

llvm-svn: 345882
2018-11-01 19:54:45 +00:00
Artem Dergachev 3ccf14eb8e [analyzer] Add support for constructors of arguments.
Once CFG-side support for argument construction contexts landed in r338436,
the analyzer could make use of them to evaluate argument constructors properly.

When evaluated as calls, constructors of arguments now use the variable region
of the parameter as their target. The corresponding stack frame does not yet
exist when the parameter is constructed, and this stack frame is created
eagerly.

Construction of functions whose body is unavailable and of virtual functions
is not yet supported. Part of the reason is the analyzer doesn't consistently
use canonical declarations o identify the function in these cases, and every
re-declaration or potential override comes with its own set of parameter
declarations. Also it is less important because if the function is not
inlined, there's usually no benefit in inlining the argument constructor.

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

llvm-svn: 339745
2018-08-15 00:33:55 +00:00
Stephen Kelly a6e4358f07 Port getStartLoc -> getBeginLoc
Reviewers: teemperor!

Subscribers: cfe-commits

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

llvm-svn: 339384
2018-08-09 21:05:56 +00:00
Simon Pilgrim 080b8709d0 Add missing semicolon.
llvm-svn: 338510
2018-08-01 10:34:13 +00:00
Simon Pilgrim 3c6cb40598 Replace 'FALL-THROUGH' comment with LLVM_FALLTHROUGH to silence warning. NFCI.
llvm-svn: 338508
2018-08-01 10:26:04 +00:00
Artem Dergachev a657a32cc8 [CFG] [analyzer] Implement function argument construction contexts.
In r330377 and r338425 we have already identified what constitutes function
argument constructors and added stubs in order to prevent confusing them
with other temporary object constructors.

Now we implement a ConstructionContext sub-class to carry all the necessary
information about the construction site, namely call expression and argument
index.

On the analyzer side, the patch interacts with the recently implemented
pre-C++17 copy elision support in an interesting manner. If on the CFG side we
didn't find a construction context for the elidable constructor, we build
the CFG as if the elidable constructor is not elided, and the non-elided
constructor within it is a simple temporary. But the same problem may occur
in the analyzer: if the elidable constructor has a construction context but
the analyzer doesn't implement such context yet, the analyzer should also
try to skip copy elision and still inline the non-elided temporary constructor.
This was implemented by adding a "roll back" mechanism: when elision fails,
roll back the changes and proceed as if it's a simple temporary. The approach
is wonky, but i'm fine with that as long as it's merely a defensive mechanism
that should eventually go away once all construction contexts become supported.

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

llvm-svn: 338436
2018-07-31 20:45:53 +00:00
Artem Dergachev 9a209ad1d8 [analyzer] Add support for pre-C++17 copy elision.
r335795 adds copy elision information to CFG. This commit allows static analyzer
to elide elidable copy constructors by constructing the objects that were
previously subject to elidable copy directly in the target region of the copy.

The chain of elided constructors may potentially be indefinitely long. This
only happens when the object is being returned from a function which in turn is
returned from another function, etc.

NRVO is not supported yet.

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

llvm-svn: 335800
2018-06-28 00:30:18 +00:00
Artem Dergachev d18639bd13 [CFG] [analyzer] Simplify lifetime-extended temporary construction contexts.
When a temporary object is materialized and through that obtain lifetime that
is longer than the duration of the full-expression, it does not require a
temporary object destructor; it will be destroyed in a different manner.

Therefore it's not necessary to include CXXBindTemporaryExpr into the
construction context for such temporary in the CFG only to make clients
throw it away.

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

llvm-svn: 335798
2018-06-28 00:18:52 +00:00
Artem Dergachev 4fb586c349 [analyzer] Re-enable lifetime extension for temporaries without destructors.
When an object's class provides no destructor, it's less important to
materialize that object properly because we don't have to model the destructor
correctly, so previously we skipped the support for these syntax patterns.

Additionally, fix support for construction contexts of "static temporaries"
(temporaries that are lifetime-extended by static references) because
it turned out that we only had tests for them without destructors, which caused
us to regress when we re-introduced the construction context for such
temporaries.

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

llvm-svn: 335796
2018-06-28 00:11:42 +00:00
Artem Dergachev ff267df0de [CFG] [analyzer] Add construction contexts that explain pre-C++17 copy elision.
Before C++17 copy elision was optional, even if the elidable copy/move
constructor had arbitrary side effects. The elidable constructor is present
in the AST, but marked as elidable.

In these cases CFG now contains additional information that allows its clients
to figure out if a temporary object is only being constructed so that to pass
it to an elidable constructor. If so, it includes a reference to the elidable
constructor's construction context, so that the client could elide the
elidable constructor and construct the object directly at its final destination.

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

llvm-svn: 335795
2018-06-28 00:04:54 +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
Artem Dergachev f28d7f1721 [analyzer] Re-enable C++17-specific RVO construction contexts.
Not contexts themselves, but rather support for them in the analyzer.

Such construction contexts appear when C++17 mandatory copy elision occurs
while returning an object from a function, and presence of a destructor causes
a CXXBindTemporaryExpr to appear in the AST.

Additionally, such construction contexts may be chained, because a return-value
construction context doesn't really explain where the object is being returned
into, but only points to the parent stack frame, where the object may be
consumed by literally anything including another return statement. This
behavior is now modeled correctly by the analyzer as long as the object is not
returned beyond the boundaries of the analysis.

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

llvm-svn: 334684
2018-06-14 01:59:35 +00:00