summaryrefslogtreecommitdiff
path: root/clang/test/Analysis/initializer.cpp
AgeCommit message (Collapse)Author
2025-10-02[analyzer] Harden RegionStoreManager::bindArray (#153177)Marco Borgeaud
Fixes https://github.com/llvm/llvm-project/issues/147686 by handling symbolic values similarly to bindStruct and handling constant values. The latter is actually more of a workaround: bindArray should not have to deal with such constants. CPP-6688
2025-02-28[analyzer] Do list initialization for CXXNewExpr with initializer list arg ↵Michael Flanders
(#127702) Fixes #116444. Closed #127700 because I accidentally updated it in github UI. ### Current vs expected behavior Previously, the result of a `CXXNewExpr` was not always list initialized when using an initializer list. In this example: ``` struct S { int x; }; void F() { S *s = new S{1}; delete s; } ``` there would be a binding of `s` to `compoundVal{1}`, but this isn't used during later field binding lookup. After this PR, there is instead a binding of `s->x` to `1`. This is the cause of #116444 since the field binding lookup returns undefined in some cases currently. ### Changes This PR swaps around the handling of typed value regions (seems to be the usual region type when doing non-CXX-new-expr list initialization) and symbolic regions (the result of the CXX new expr), so that symbolic regions also get list initialized. In the below snippet, it swaps the order of the two conditionals. https://github.com/llvm/llvm-project/blob/8529bd7b964cc9fafe8fece84f7bd12dacb09560/clang/lib/StaticAnalyzer/Core/RegionStore.cpp#L2426-L2448 ### Followup work This PR only makes CSA do list init for `CXXNewExpr`s. After this, I would like to make some changes to `RegionStoreMananger::bind` in how it handles list initialization generally. I've added some straightforward test cases here for the `new` expr with a list initializer. I started adding some more before realizing that the current general (not just `new` expr) list initialization could be changed to handle more cases like list initialization of unions and arrays (like https://github.com/llvm/llvm-project/issues/54910). Lmk if it is preferred to then leave these test cases out for now.
2024-11-29[analyzer] Never create Regions wrapping reference TypedValueRegions (NFCI) ↵Balazs Benics
(#118096) Like in the test case: ```c++ struct String { String(const String &) {} }; struct MatchComponent { unsigned numbers[2]; String prerelease; MatchComponent(MatchComponent const &) = default; }; MatchComponent get(); void consume(MatchComponent const &); MatchComponent parseMatchComponent() { MatchComponent component = get(); component.numbers[0] = 10; component.numbers[1] = 20; return component; // We should have no stack addr escape warning here. } void top() { consume(parseMatchComponent()); } ``` When calling `consume(parseMatchComponent())` the `parseMatchComponent()` would return a copy of a temporary of `component`. That copy would invoke the `MatchComponent::MatchComponent(const MatchComponent &)` ctor. That ctor would have a (reference typed) ParamVarRegion, holding the location (lvalue) of the object we are about to copy (&component). So far so good, but just before evaluating the binding operation for initializing the `numbers` field of the temporary, we evaluate the ArrayInitLoopExpr representing the by-value elementwise copy of the array `component.numbers`. This is represented by a LazyCompoundVal, because we (usually) don't just copy large arrays and bind many individual direct bindings. Rather, we take a snapshot by using a LCV. However, notice that the LCV representing this copy would look like this: lazyCompoundVal{ParamVarRegion{"reference param of cctor"}.numbers} Notice that it refers to the numbers field of a reference. It would be much better to desugar the reference to the actual object, thus it should be: `lazyCompoundVal{component.numbers}` Actually, when binding the result of the ArrayInitLoopExpr to the `temp_object.numbers` in the compiler-generated member initializer of the cctor, we should have two individual direct bindings because this is a "small array": ``` binding &Element{temp_object.numbers, 0} <- loadFrom(&Element{component.numbers, 0}) binding &Element{temp_object.numbers, 1} <- loadFrom(&Element{component.numbers, 1}) ``` Where `loadFrom(...)` would be: ``` loadFrom(&Element{component.numbers, 0}): 10 U32b loadFrom(&Element{component.numbers, 1}): 20 U32b ``` So the store should look like this, after PostInitializer of `temp_object.numbers`: ``` temp_object at offset 0: 10 U32b temp_object at offset 32: 20 U32b ``` The lesson is that it's okay to have TypedValueRegions of references as long as we don't form subregions of those. If we ever want to refer to a subregion of a "reference" we actually meant to "desugar" the reference and slice a subregion of the pointee of the reference instead. Once this canonicalization is in place, we can also drop the special handling of references in `ProcessInitializer`, because now reference TypedValueRegions are eagerly desugared into their referee region when forming a subregion of it. There should be no practical differences, but there are of course bugs that this patch may surface.
2019-05-24[CFG] Add branch to skip vbase inits when they're handled by superclass.Artem Dergachev
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-03-26[CFG] [analyzer] pr41142: C++17: Skip transparent InitListExprs in ExprEngine.Artem Dergachev
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-21[CFG] [analyzer] pr41142: C++17: Skip transparent InitListExprs in constructors.Artem Dergachev
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
2018-07-17Restructure checking for, and warning on, lifetime extension.Richard Smith
This change implements C++ DR1696, which makes initialization of a reference member of a class from a temporary object ill-formed. The standard wording here is imprecise, but we interpret it as meaning that any time a mem-initializer would result in lifetime extension, the program is ill-formed. This reinstates r337226, reverted in r337255, with a fix for the InitializedEntity alignment problem that was breaking ARM buildbots. llvm-svn: 337329
2018-07-17Temporarily revert r337226 "Restructure checking for, and warning on, ↵Florian Hahn
lifetime extension." This change breaks on ARM because pointers to clang::InitializedEntity are only 4 byte aligned and do not have 3 bits to store values. A possible solution would be to change the fields in clang::InitializedEntity to enforce a bigger alignment requirement. The error message is llvm/include/llvm/ADT/PointerIntPair.h:132:3: error: static_assert failed "PointerIntPair with integer size too large for pointer" static_assert(IntBits <= PtrTraits::NumLowBitsAvailable, include/llvm/ADT/PointerIntPair.h:73:13: note: in instantiation of template class 'llvm::PointerIntPairInfo<const clang::InitializedEntity *, 3, llvm::PointerLikeTypeTraits<const clang::InitializedEntity *> >' requested here Value = Info::updateInt(Info::updatePointer(0, PtrVal), llvm/include/llvm/ADT/PointerIntPair.h:51:5: note: in instantiation of member function 'llvm::PointerIntPair<const clang::InitializedEntity *, 3, (anonymous namespace)::LifetimeKind, llvm::PointerLikeTypeTraits<const clang::InitializedEntity *>, llvm::PointerIntPairInfo<const clang::InitializedEntity *, 3, llvm::PointerLikeTypeTraits<const clang::InitializedEntity *> > >::setPointerAndInt' requested here setPointerAndInt(PtrVal, IntVal); ^ llvm/tools/clang/lib/Sema/SemaInit.cpp:6237:12: note: in instantiation of member function 'llvm::PointerIntPair<const clang::InitializedEntity *, 3, (anonymous namespace)::LifetimeKind, llvm::PointerLikeTypeTraits<const clang::InitializedEntity *>, llvm::PointerIntPairInfo<const clang::InitializedEntity *, 3, llvm::PointerLikeTypeTraits<const clang::InitializedEntity *> > >::PointerIntPair' requested here return {Entity, LK_Extended}; Full log here: http://lab.llvm.org:8011/builders/clang-cmake-armv7-global-isel/builds/1330 http://lab.llvm.org:8011/builders/clang-cmake-armv7-full/builds/1394 llvm-svn: 337255
2018-07-17Restructure checking for, and warning on, lifetime extension.Richard Smith
This change implements C++ DR1696, which makes initialization of a reference member of a class from a temporary object ill-formed. The standard wording here is imprecise, but we interpret it as meaning that any time a mem-initializer would result in lifetime extension, the program is ill-formed. llvm-svn: 337226
2018-01-24[analyzer] NFC: Run many existing C++ tests with a custom operator new().Artem Dergachev
In order to provide more test coverage for inlined operator new(), add more run-lines to existing test cases, which would trigger our fake header to provide a body for operator new(). Most of the code should still behave reasonably. When behavior intentionally changes, #ifs are provided. Differential Revision: https://reviews.llvm.org/D42221 llvm-svn: 323376
2017-12-20[analyzer] Fix a crash during C++17 aggregate construction of base objects.Artem Dergachev
Since C++17, classes that have base classes can potentially be initialized as aggregates. Trying to construct such objects through brace initialization was causing the analyzer to crash when the base class has a non-trivial constructor, while figuring target region for the base class constructor, because the parent stack frame didn't contain the constructor of the subclass, because there is no constructor for subclass, merely aggregate initialization. This patch avoids the crash, but doesn't provide the actually correct region for the constructor, which still remains to be fixed. Instead, construction goes into a fake temporary region which would be immediately discarded. Similar extremely conservative approach is used for other cases in which the logic for finding the target region is not yet implemented, including aggregate initialization with fields instead of base-regions (which is not C++17-specific but also never worked, just didn't crash). Differential revision: https://reviews.llvm.org/D40841 rdar://problem/35441058 llvm-svn: 321128
2017-11-27[analyzer] pr34766: Fix a crash on explicit std::initializer_list constructor.Artem Dergachev
We didn't support the following syntax: (std::initializer_list<int>){12} which suddenly produces CompoundLiteralExpr that contains CXXStdInitializerListExpr. Lift the assertion and instead pass the value through CompoundLiteralExpr transparently, as it doesn't add much. Differential Revision: https://reviews.llvm.org/D39803 llvm-svn: 319058
2017-10-05[analyzer] Fix leak false positives on stuff put in C++/ObjC initializer lists.Artem Dergachev
The analyzer now realizes that C++ std::initializer_list objects and Objective-C boxed structure/array/dictionary expressions can potentially maintain a reference to the objects that were put into them. This avoids false memory leak posivites and a few other issues. This is a conservative behavior; for now, we do not model what actually happens to the objects after being passed into such initializer lists. rdar://problem/32918288 Differential Revision: https://reviews.llvm.org/D35216 llvm-svn: 314975
2017-03-03Reland 4: [analyzer] NFC: Update test infrastructure to support multiple ↵Dominic Chen
constraint managers Summary: Replace calls to %clang/%clang_cc1 with %clang_analyze_cc1 when invoking static analyzer, and perform runtime substitution to select the appropriate constraint manager, per D28952. Reviewers: xazax.hun, NoQ, zaks.anna, dcoughlin Subscribers: mgorny, rgov, mikhail.ramalho, a.sidorin, cfe-commits Differential Revision: https://reviews.llvm.org/D30373 llvm-svn: 296895
2017-03-02Revert "Reland 3: [analyzer] NFC: Update test infrastructure to support ↵Dominic Chen
multiple constraint managers" This reverts commit ea36f1406e1f36bf456c3f3929839b024128e468. llvm-svn: 296841
2017-03-02Reland 3: [analyzer] NFC: Update test infrastructure to support multiple ↵Dominic Chen
constraint managers Summary: Replace calls to %clang/%clang_cc1 with %clang_analyze_cc1 when invoking static analyzer, and perform runtime substitution to select the appropriate constraint manager, per D28952. Reviewers: xazax.hun, NoQ, zaks.anna, dcoughlin Subscribers: mgorny, rgov, mikhail.ramalho, a.sidorin, cfe-commits Differential Revision: https://reviews.llvm.org/D30373 llvm-svn: 296837
2017-03-02Revert "Reland 2: [analyzer] NFC: Update test infrastructure to support ↵Dominic Chen
multiple constraint managers" This reverts commit f93343c099fff646a2314cc7f4925833708298b1. llvm-svn: 296836
2017-03-02Reland 2: [analyzer] NFC: Update test infrastructure to support multiple ↵Dominic Chen
constraint managers Summary: Replace calls to %clang/%clang_cc1 with %clang_analyze_cc1 when invoking static analyzer, and perform runtime substitution to select the appropriate constraint manager, per D28952. Reviewers: xazax.hun, NoQ, zaks.anna, dcoughlin Subscribers: mgorny, rgov, mikhail.ramalho, a.sidorin, cfe-commits Differential Revision: https://reviews.llvm.org/D30373 llvm-svn: 296835
2017-02-28Revert "Reland: [analyzer] NFC: Update test infrastructure to support ↵Dominic Chen
multiple constraint managers" This reverts commit 1b28d0b10e1c8feccb971abb6ef7a18bee589830. llvm-svn: 296422
2017-02-28Reland: [analyzer] NFC: Update test infrastructure to support multiple ↵Dominic Chen
constraint managers Summary: Replace calls to %clang/%clang_cc1 with %clang_analyze_cc1 when invoking static analyzer, and perform runtime substitution to select the appropriate constraint manager, per D28952. Reviewers: xazax.hun, NoQ, zaks.anna, dcoughlin Subscribers: mgorny, rgov, mikhail.ramalho, a.sidorin, cfe-commits Differential Revision: https://reviews.llvm.org/D30373 llvm-svn: 296414
2017-02-27Revert "[analyzer] NFC: Update test infrastructure to support multiple ↵Dominic Chen
constraint managers" This reverts commit 8e7780b9e59ddaad1800baf533058d2c064d4787. llvm-svn: 296317
2017-02-27[analyzer] NFC: Update test infrastructure to support multiple constraint ↵Dominic Chen
managers Summary: Replace calls to %clang/%clang_cc1 with %clang_analyze_cc1 when invoking static analyzer, and perform runtime substitution to select the appropriate constraint manager, per D28952. Reviewers: xazax.hun, NoQ, zaks.anna, dcoughlin Subscribers: mgorny, rgov, mikhail.ramalho, a.sidorin, cfe-commits Differential Revision: https://reviews.llvm.org/D30373 llvm-svn: 296312
2017-01-12[analyzer] Avoid a crash in DereferenceChecker on string literal initializers.Artem Dergachev
A hotfix for pr31592 that fixes the crash but not the root cause of the problem. We need to update the analyzer engine further to account for AST changes introduced in r289618. At the moment we're erroneously performing a redundant lvalue-to-rvalue cast in this scenario, and squashing the rvalue of the object bound to the reference into the reference itself. rdar://problem/28832541 llvm-svn: 291754
2015-12-17[analyzer] Better detect when C++ object was constructed into existing region.Devin Coughlin
When the analyzer evaluates a CXXConstructExpr, it looks ahead in the CFG for the current block to detect what region the object should be constructed into. If the constructor was directly constructed into a local variable or field region then there is no need to explicitly bind the constructed value to the local or field when analyzing the DeclStmt or CXXCtorInitializer that called the constructor. Unfortunately, there were situations in which the CXXConstructExpr was constructed into a temporary region but when evaluating the corresponding DeclStmt or CXXCtorInitializer the analyzer assumed the object was constructed into the local or field. This led to spurious warnings about uninitialized values (PR25777). To avoid these false positives, this commit factors out the logic for determining when a CXXConstructExpr will be directly constructed into existing storage, adds the inverse logic to detect when the corresponding later bind can be safely skipped, and adds assertions to make sure these two checks are in sync. rdar://problem/21947725 llvm-svn: 255859
2013-07-17[analyzer] Handle C++11 member initializer expressions.Jordan Rose
Previously, we would simply abort the path when we saw a default member initialization; now, we actually attempt to evaluate it. Like default arguments, the contents of these expressions are not actually part of the current function, so we fall back to constant evaluation. llvm-svn: 186521
2013-03-07[analyzer] Warn on passing a reference to null pointer as an argument in a callAnna Zaks
Warn about null pointer dereference earlier when a reference to a null pointer is passed in a call. The idea is that even though the standard might allow this, reporting the issue earlier is better for diagnostics (the error is reported closer to the place where the pointer was set to NULL). This also simplifies analyzer’s diagnostic logic, which has to track “where the null came from”. As a consequence, some of our null pointer warning suppression mechanisms started triggering more often. TODO: Change the name of the file and class to reflect the new check. llvm-svn: 176612
2013-01-26[analyzer] C++ initializers may require cleanups; look through these.Jordan Rose
When the analyzer sees an initializer, it checks if the initializer contains a CXXConstructExpr. If so, it trusts that the CXXConstructExpr does the necessary work to initialize the object, and performs no further initialization. This patch looks through any implicit wrapping expressions like ExprWithCleanups to find the CXXConstructExpr inside. Fixes PR15070. llvm-svn: 173557
2013-01-24[analyzer] Replace "-analyzer-ipa" with "-analyzer-config ipa".Anna Zaks
The idea is to eventually place all analyzer options under "analyzer-config". In addition, this lays the ground for introduction of a high-level analyzer mode option, which will influence the default setting for IPAMode. llvm-svn: 173385
2012-08-31[analyzer] Though C++ inlining is enabled, don't inline ctors and dtors.Jordan Rose
More generally, this adds a new configuration option 'c++-inlining', which controls which C++ member functions can be considered for inlining. This uses the new -analyzer-config table, so the cc1 arguments will look like this: ... -analyzer-config c++-inlining=[none|methods|constructors|destructors] Note that each mode implies that all the previous member function kinds will be inlined as well; it doesn't make sense to inline destructors without inlining constructors, for example. The default mode is 'methods'. llvm-svn: 163004
2012-08-25[analyzer] Use the common evalBind infrastructure for initializers.Jordan Rose
This allows checkers (like the MallocChecker) to process the effects of the bind. Previously, using a memory-allocating function (like strdup()) in an initializer would result in a leak warning. This does bend the expectations of checkBind a bit; since there is no assignment expression, the statement being used is the initializer value. In most cases this shouldn't matter because we'll use a PostInitializer program point (rather than PostStmt) for any checker-generated nodes, though we /will/ generate a PostStore node referencing the internal statement. (In theory this could have funny effects if someone actually does an assignment within an initializer; in practice, that seems like it would be very rare.) <rdar://problem/12171711> llvm-svn: 162637
2012-08-21[analyzer] -analyzer-ipa=inlining is now the default. Remove it from tests.Jordan Rose
The actual change here is a little more complicated than the summary above. What we want to do is have our generic inlining tests run under whatever mode is the default. However, there are some tests that depend on the presence of C++ inlining, which still has some rough edges. These tests have been explicitly marked as -analyzer-ipa=inlining in preparation for a new mode that limits inlining to C functions and blocks. This will be the default until the false positives for C++ have been brought down to manageable levels. llvm-svn: 162317
2012-08-03[analyzer] Update initializer assertion for delegating constructors.Jordan Rose
Like base constructors, delegating constructors require no further processing in the CFGInitializer node. Also, add PrettyStackTraceLoc to the initializer and destructor logic so we can get better stack traces in the future. llvm-svn: 161283
2012-08-02[analyzer] Add a simple check for initializing reference variables with null.Jordan Rose
There's still more work to be done here; this doesn't catch reference parameters or return values. But it's a step in the right direction. Part of <rdar://problem/11212286>. llvm-svn: 161214
2012-07-31[analyzer] Turn -cfg-add-initializers on by default, and remove the flag.Jordan Rose
llvm-svn: 161060
2012-07-26[analyzer] Handle C++ member initializers and destructors.Jordan Rose
This uses CFG to tell if a constructor call is for a member, and uses the member's region appropriately. llvm-svn: 160808
2012-05-16[analyzer] Convert many existing tests to use clang_analyzer_eval.Jordy Rose
llvm-svn: 156920
2011-02-28[analyzer] Remove '-analyzer-check-objc-mem' flag, the nominee for best ↵Argyrios Kyrtzidis
misnomer award. llvm-svn: 126676
2010-11-16Handle member initializer in C++ ctor. Zhongxing Xu
- Add a new Kind of ProgramPoint: PostInitializer. - Still use GRStmtNodeBuilder. But special handling PostInitializer in GRStmtNodeBuilder::GenerateAutoTransition(). - Someday we should clean up the interface of GRStmtNodeBuilder. llvm-svn: 119335