aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/FlowSensitive
AgeCommit message (Collapse)AuthorFilesLines
11 daysReland [clang][dataflow] Transfer more cast expressions. (#157535)Samira Bakon2-19/+94
Reverts llvm/llvm-project#157148 Adds fixes to `TransferVisitor::VisitCXXConstructExpr` and `copyRecord` to avoid crashing on base class initialization from sibling-derived class instances. I believe this is the only use of copyRecord where we need this special handling for a shared base class.
11 days[clang-tidy] `bugprone-unchecked-optional-access`: handle ↵Valentyn Yukhymenko1-0/+14
`BloombergLP::bdlb:NullableValue::makeValue` to prevent false-positives (#144313) https://github.com/llvm/llvm-project/pull/101450 added support for `BloombergLP::bdlb::NullableValue`. However, `NullableValue::makeValue` and `NullableValue::makeValueInplace` have been missed which impacts code like this: ```cpp if (opt.isNull()) { opt.makeValue(42); } opt.value(); // triggers false positive warning from `bugprone-unchecked-optional-access` ``` My patch addresses this issue. [Docs that I used for methods mocks](https://bloomberg.github.io/bde-resources/doxygen/bde_api_prod/classbdlb_1_1NullableValue.html) --------- Co-authored-by: Baranov Victor <bar.victor.2002@gmail.com>
2025-09-05Revert "[clang][dataflow] Transfer more cast expressions." (#157148)Samira Bakon1-59/+12
Reverts llvm/llvm-project#153066 copyRecord crashes if copying from the RecordStorageLocation shared by the base/derived objects after a DerivedToBase cast because the source type is still `Derived` but the copy destination could be of a sibling type derived from Base that has children not present in `Derived`. For example, running the dataflow analysis over the following produces UB by nullptr deref, or fails asserts if enabled: ```cc struct Base {}; struct DerivedOne : public Base { int DerivedOneField; }; struct DerivedTwo : public Base { int DerivedTwoField; DerivedTwo(const DerivedOne& d1) : Base(d1), DerivedTwoField(d1.DerivedOneField) {} }; ``` The constructor initializer for `DerivedTwoField` serves the purpose of forcing `DerivedOneField` to be modeled, which is necessary to trigger the crash but not the assert failure.
2025-08-27[clang] NFC: reintroduce clang/include/clang/AST/Type.h (#155050)Matheus Izvekov5-5/+5
This reintroduces `Type.h`, having earlier been renamed to `TypeBase.h`, as a redirection to `TypeBase.h`, and redirects most users to include the former instead. This is a preparatory patch for being able to provide inline definitions for `Type` methods which would otherwise cause a circular dependency with `Decl{,CXX}.h`. Doing these operations into their own NFC patch helps the git rename detection logic work, preserving the history. This patch makes clang just a little slower to build (~0.17%), just because it makes more code indirectly include `DeclCXX.h`.
2025-08-27[clang] NFC: rename clang/include/clang/AST/Type.h to TypeBase.h (#155049)Matheus Izvekov5-5/+5
This is a preparatory patch, to be able to provide inline definitions for `Type` functions which depend on `Decl{,CXX}.h`. As the latter also depends on `Type.h`, this would not be possible without some reorganizing. Splitting this rename into its own patch allows git to track this as a rename, and preserve all git history, and not force any code reformatting. A later NFC patch will reintroduce `Type.h` as redirection to `TypeBase.h`, rewriting most places back to directly including `Type.h` instead of `TypeBase.h`, leaving only a handful of places where this is necessary. Then yet a later patch will exploit this by making more stuff inline.
2025-08-20[clang][dataflow] Fix uninitialized memory bug. (#154575)Yitzhak Mandelbaum1-3/+3
Commit #3ecfc03 introduced a bug involving an uninitialized field in `exportLogicalContext`. This patch initializes the field properly.
2025-08-20[clang][dataflow] Transfer more cast expressions. (#153066)Samira Bakon1-12/+59
Transfer all casts by kind as we currently do implicit casts. This obviates the need for specific handling of static casts. Also transfer CK_BaseToDerived and CK_DerivedToBase and add tests for these and missing tests for already-handled cast types. Ensure that CK_BaseToDerived casts result in modeling of the fields of the derived class.
2025-08-18[clang][dataflow] Add support for serialization and deserialization. (#152487)Yitzhak Mandelbaum3-0/+233
Adds support for compact serialization of Formulas, and a corresponding parse function. Extends Environment and AnalysisContext with necessary functions for serializing and deserializing all formula-related parts of the environment.
2025-08-09[clang] Improve nested name specifier AST representation (#147835)Matheus Izvekov1-2/+4
This is a major change on how we represent nested name qualifications in the AST. * The nested name specifier itself and how it's stored is changed. The prefixes for types are handled within the type hierarchy, which makes canonicalization for them super cheap, no memory allocation required. Also translating a type into nested name specifier form becomes a no-op. An identifier is stored as a DependentNameType. The nested name specifier gains a lightweight handle class, to be used instead of passing around pointers, which is similar to what is implemented for TemplateName. There is still one free bit available, and this handle can be used within a PointerUnion and PointerIntPair, which should keep bit-packing aficionados happy. * The ElaboratedType node is removed, all type nodes in which it could previously apply to can now store the elaborated keyword and name qualifier, tail allocating when present. * TagTypes can now point to the exact declaration found when producing these, as opposed to the previous situation of there only existing one TagType per entity. This increases the amount of type sugar retained, and can have several applications, for example in tracking module ownership, and other tools which care about source file origins, such as IWYU. These TagTypes are lazily allocated, in order to limit the increase in AST size. This patch offers a great performance benefit. It greatly improves compilation time for [stdexec](https://github.com/NVIDIA/stdexec). For one datapoint, for `test_on2.cpp` in that project, which is the slowest compiling test, this patch improves `-c` compilation time by about 7.2%, with the `-fsyntax-only` improvement being at ~12%. This has great results on compile-time-tracker as well: ![image](https://github.com/user-attachments/assets/700dce98-2cab-4aa8-97d1-b038c0bee831) This patch also further enables other optimziations in the future, and will reduce the performance impact of template specialization resugaring when that lands. It has some other miscelaneous drive-by fixes. About the review: Yes the patch is huge, sorry about that. Part of the reason is that I started by the nested name specifier part, before the ElaboratedType part, but that had a huge performance downside, as ElaboratedType is a big performance hog. I didn't have the steam to go back and change the patch after the fact. There is also a lot of internal API changes, and it made sense to remove ElaboratedType in one go, versus removing it from one type at a time, as that would present much more churn to the users. Also, the nested name specifier having a different API avoids missing changes related to how prefixes work now, which could make existing code compile but not work. How to review: The important changes are all in `clang/include/clang/AST` and `clang/lib/AST`, with also important changes in `clang/lib/Sema/TreeTransform.h`. The rest and bulk of the changes are mostly consequences of the changes in API. PS: TagType::getDecl is renamed to `getOriginalDecl` in this patch, just for easier to rebasing. I plan to rename it back after this lands. Fixes #136624 Fixes https://github.com/llvm/llvm-project/issues/43179 Fixes https://github.com/llvm/llvm-project/issues/68670 Fixes https://github.com/llvm/llvm-project/issues/92757
2025-06-26[clang] Use llvm::is_contained instead of llvm::all_of (NFC) (#145843)Kazu Hirata1-3/+2
llvm::is_contained is shorter than llvm::all_of plus a lambda.
2025-06-06[clang] Ensure newline at the end of files (NFC) (#143154)Kazu Hirata1-1/+1
2025-05-31[Analysis] Remove unused includes (NFC) (#142255)Kazu Hirata8-14/+0
These are identified by misc-include-cleaner. I've filtered out those that break builds. Also, I'm staying away from llvm-config.h, config.h, and Compiler.h, which likely cause platform- or compiler-specific build failures.
2025-04-27[clang] Use range constructors of *Set (NFC) (#137574)Kazu Hirata1-1/+1
2025-04-19[clang] llvm::append_range (NFC) (#136440)Kazu Hirata1-1/+1
2025-04-02[EquivalenceClasses] Use SmallVector for deterministic iteration order. ↵Florian Hahn1-4/+4
(#134075) Currently iterators over EquivalenceClasses will iterate over std::set, which guarantees the order specified by the comperator. Unfortunately in many cases, EquivalenceClasses are used with pointers, so iterating over std::set of pointers will not be deterministic across runs. There are multiple places that explicitly try to sort the equivalence classes before using them to try to get a deterministic order (LowerTypeTests, SplitModule), but there are others that do not at the moment and this can result at least in non-determinstic value naming in Float2Int. This patch updates EquivalenceClasses to keep track of all members via a extra SmallVector and removes code from LowerTypeTests and SplitModule to sort the classes before processing. Overall it looks like compile-time slightly decreases in most cases, but close to noise: https://llvm-compile-time-tracker.com/compare.php?from=7d441d9892295a6eb8aaf481e1715f039f6f224f&to=b0c2ac67a88d3ef86987e2f82115ea0170675a17&stat=instructions PR: https://github.com/llvm/llvm-project/pull/134075
2025-04-01[EquivalenceClasses] Update member_begin to take ECValue (NFC).Florian Hahn1-4/+3
Remove a level of indirection and update code to use range-based for loops.
2025-04-01[EquivalenceClasses] Return ECValue directly from insert (NFC).Florian Hahn1-1/+1
Removes a redundant lookup in the mapping.:
2025-03-31Reapply "[EquivalenceClasses] Replace findValue with contains (NFC)."Florian Hahn1-7/+5
This reverts the revert commit 616f447fc84bdc7655117f1b303d895dc3b93e4d. It includes updates to remaining users in Polly and Clang, to avoid failures when building those projects.
2025-03-28[NFC] [dataflow] generalize smart pointer caching (#133350)Florian Mayer1-72/+72
This allows us to use it for classes that use other names than get / value.
2025-03-27[clang] Use *Set::insert_range (NFC) (#133357)Kazu Hirata1-6/+3
We can use *Set::insert_range to collapse: for (auto Elem : Range) Set.insert(E); down to: Set.insert_range(Range); In some cases, we can further fold that into the set declaration.
2025-03-26Reland [clang][dataflow] Fix unsupported types always being equal (#131575)Discookie1-1/+8
Relands #129502. Previously when the framework encountered unsupported values (such as enum classes), they were always treated as equal when comparing with `==`, regardless of their actual values being different. Now the two sides are only equal if there's a Value assigned to them. Added handling for the special case of `nullptr == nullptr`, to preserve the behavior of untyped `nullptr` having no value.
2025-03-21[clang][dataflow] Add matcher for pointer-like types to be cached (#132314)Florian Mayer1-0/+24
This is used e.g. for iterators.
2025-03-17[clang][dataflow] For bugprone-unchecked-optional-access report range (#131055)Jan Voung1-7/+8
Report the range in diagnostics, in addition to the location in case the range helps disambiguate a little in chained `->` expressions. ``` b->a->f->x = 1; ^~~~~~~ ``` instead of just: ``` b->a->f->x = 1; ^ ``` As a followup we should probably also report the location/range of an `->` if that operator is used. Like: ``` b->a->f->x = 1; ^~ ```
2025-03-07[clang][dataflow] Add test for crash repro and clean up const accessor ↵Jan Voung1-53/+62
handling (#129930) Add test for https://github.com/llvm/llvm-project/issues/125589 The crash is actually incidentally fixed by https://github.com/llvm/llvm-project/pull/128437 since it added a branch for the reference case and would no longer fall through when the return type is a reference to a pointer. Clean up a bit as well: - make the fallback for early returns more consistent (check if returning optional and call transfer function for that case) - check RecordLoc == nullptr in one place - clean up extra spaces in test - clean up parameterization in test of `std::` vs `$ns::$`
2025-03-04Revert "[clang][dataflow] Fix unsupported types always being equal" (#129761)Jan Voung1-11/+1
Reverts llvm/llvm-project#129502 seeing new crashes around https://github.com/google/crubit/blob/859520eca82d60a169fb85cdbf648c57d0a14a99/nullability/test/smart_pointers_diagnosis.cc#L57 Would like some time to investigate.
2025-03-04[clang][dataflow] Fix unsupported types always being equal (#129502)Discookie1-1/+11
Previously when the framework encountered unsupported values (such as enum classes), they were always treated as equal when comparing with `==`, regardless of their actual values being different. Now the two sides are only equal if there's a Value assigned to them. Added a Value assignment for `nullptr`, to handle the special case of `nullptr == nullptr`.
2025-02-28[clang-tidy] [dataflow] Cache reference accessors for ↵Valentyn Yukhymenko1-0/+16
`bugprone-unchecked-optional-access` (#128437) Fixes https://github.com/llvm/llvm-project/issues/126283 Extending https://github.com/llvm/llvm-project/pull/112605 to cache const getters which return references. Fixes false positives from const reference accessors to object containing optional member
2025-02-05[clang] [dataflow] use unqualified type for smart pointer matching (#125958)Florian Mayer1-4/+8
one would assume that `getCanonicalTypeUnqualified` returns an unqualified type, but sadly one would be wrong. the current logic fails for std::optional as implemented in libcxx, because Star and Arrow types mismatch in their const qualification. there are other places in clang that use getCanonicalTypeUnqualified().getUnqualifiedType().
2025-02-01[clang][dataflow][NFC] Remove double lookup (#125282)Balazs Benics1-2/+3
2025-01-30[clang][dataflow] Fix smart pointer accessor caching to handle aliases (#124964)Jan Voung1-8/+11
Check the canonical type in the matchers to handle aliases. For example std::optional uses add_pointer_t<...>.
2025-01-08[clang][dataflow] Use smart pointer caching in unchecked optional accessor ↵Jan Voung2-6/+72
(#120249) Part 2 (and final part) following https://github.com/llvm/llvm-project/pull/120102 Allows users to do things like: ``` if (o->x.has_value()) { ((*o).x).value(); } ``` where the `->` and `*` are operator overload calls. A user could instead extract the nested optional into a local variable once instead of doing two accessor calls back to back, but currently they are unsure why the code is flagged.
2024-12-20[clang][dataflow] Fix a missing break from a switch case ↵Jan Voung1-1/+1
-Wimplicit-fallthrough (#120739) Missed when changing code in https://github.com/llvm/llvm-project/pull/120102
2024-12-20[clang][dataflow] Add matchers for smart pointer accessors to be cached ↵Jan Voung2-0/+148
(#120102) This is part 1 of caching for smart pointer accessors, building on top of the CachedConstAccessorsLattice, which caches "normal" accessors. Smart pointer accessors are a bit different in that they may: - have aliases to access the same underlying data (but potentially returning slightly different types like `&` vs `*`). Within a "checked" sequence users may mix uses of the different aliases and the check should apply to any of the spellings. - may have non-const overloads in addition to the const version, where the non-const doesn't actually modify the container Part 2 will follow and add transfer functions utilities. It will also add a user UncheckedOptionalAccessModel. We'd seen false positives when nesting StatusOr<optional<T>> and optional<StatusOr<T>>, etc. which this can help address.
2024-11-27[clang][dataflow] Add captured parameters to ReferencedDecls for lamb… ↵Samira Bazuzi1-0/+23
(#117771) …da call operators. This doesn't require that they be used in the operator's body, unlike other ReferencedDecls. This is most obviously different from captured local variables, which can be captured but will not appear in ReferencedDecls unless they appear in the operator's body. This difference simplifies the collection of the captured parameters, but probably could be eliminated if desirable.
2024-11-26[clang][analysis][NFC]add static for internal linkage function (#117481)Congcong Cai3-10/+13
Detected by misc-use-internal-linkage
2024-11-15[Clang] [NFC] Refactor AST visitors in Sema and the static analyser to use ↵Sirraide2-17/+16
DynamicRecursiveASTVisitor (#115144) This pr refactors all recursive AST visitors in `Sema`, `Analyze`, and `StaticAnalysis` to inherit from DRAV instead. This is over half of the visitors that inherit from RAV directly. See also #115132, #110040, #93462 LLVM Compile-Time Tracker link for this branch: https://llvm-compile-time-tracker.com/compare.php?from=5adb5c05a2e9f31385fbba8b0436cbc07d91a44d&to=b58e589a86c06ba28d4d90613864d10be29aa5ba&stat=instructions%3Au
2024-10-28[clang][dataflow] Cache accessors returning pointers in ↵Jan Voung1-2/+18
bugprone-unchecked-optional-access (#113922) Previously, we covered returning refs, or copies of optional, and bools. Now cover returning pointers (to any type). This is useful for cases like operator-> of smart pointers. Addresses more of issue llvm#58510
2024-10-28[clang][dataflow] Don't clear cached field state if field is const (#113698)Jan Voung1-2/+6
... in the unchecked optional access model.
2024-10-24[FlowSensitive] Allow to dump nested RecordStorageLocation (#112457)Florian Mayer1-2/+1
We have an internal analysis that uses them, and the HTML dump would fail on the assertion.
2024-10-24[llvm] Support llvm::Any across shared libraries on windows (#108051)Thomas Fransham1-0/+15
This is part of the effort to support for enabling plugins on windows by adding better support for building llvm as a DLL. The export macros used here were added in #96630 Since shared library symbols aren't deduplicated across multiple libraries on windows like Linux we have to manually explicitly import and export `Any::TypeId` template instantiations for the uses of `llvm::Any` in the LLVM codebase to support LLVM Windows shared library builds. This change ensures that external code, including LLVM's own tests, can use PassManager callbacks when LLVM is built as a DLL. I also removed the only use of llvm::Any for LoopNest that only existed in debug code and there also doesn't seem to be any code creating `Any<LoopNest>`
2024-10-22[clang][dataflow] Cache accessors for bugprone-unchecked-optional-access ↵Jan Voung1-5/+131
(#112605) Treat calls to zero-param const methods as having stable return values (with a cache) to address issue #58510. The cache is invalidated when non-const methods are called. This uses the infrastructure from PR #111006. For now we cache methods returning: - ref to optional - optional by value - booleans We can extend that to pointers to optional in a next change.
2024-09-25[clang-tidy] Add support for bsl::optional (#101450)Chris Cotter1-13/+54
2024-08-19[clang][dataflow] Collect local variables referenced within a functio… ↵Samira Bazuzi1-0/+9
(#104459) …n/statement. We don't need these for the same in-tree purposes as the other sets, i.e. for making sure we model these Decls that are declared outside the function, but we have an out-of-tree use for these sets that would benefit from this simple addition and would avoid duplicating so much of this code.
2024-08-02[clang][dataflow] Fix casting in `ChromiumCheckModel`. (#101640)Pasquale Riello1-1/+2
`getDirectCallee()` may return a null pointer if the callee is not a `FunctionDecl` (for example when using function pointers), this requires to use `dyn_cast_or_null` instead of `dyn_cast`.
2024-07-29[clang][dataflow] Fix bug in `buildContainsExprConsumedInDifferentBlock()`. ↵martinboehme3-15/+21
(#100874) This was missing a call to `ignoreCFGOmittedNodes()`. As a result, the function would erroneously conclude that a block did not contain an expression consumed in a different block if the expression in question was surrounded by a `ParenExpr` in the consuming block. The patch adds a test that triggers this scenario (and fails without the fix). To prevent this kind of bug in the future, the patch also adds a new method `blockForStmt()` to `AdornedCFG` that calls `ignoreCFGOmittedNodes()` and is preferred over accessing `getStmtToBlock()` directly.
2024-07-26[clang][dataflow] Handle CXXInheritedCtorInitExpr in ResultObjectVisitor. ↵Pasquale Riello1-1/+1
(#99616) `CXXInheritedCtorInitExpr` is another of the node kinds that should be considered an "original initializer". An assertion failure in `assert(Children.size() == 1)` happens without this fix. --------- Co-authored-by: martinboehme <mboehme@google.com>
2024-07-22[clang][dataflow] Handle this-capturing lambdas in field initializers. (#99519)Samira Bazuzi1-6/+15
We previously would assume these lambdas appeared inside a method definition and end up crashing.
2024-07-13[clang][dataflow]Propagate the result object location for ↵Samira Bazuzi1-2/+8
CXXDefaultInitExpr. (#98490) These are not "original initializers"; the single node underneath represents the initializing node.
2024-06-26[clang][nullability] Improve modeling of `++`/`--` operators. (#96601)martinboehme1-6/+11
We definitely know that these operations change the value of their operand, so clear out any value associated with it. We don't create a new value, instead leaving it to the analysis to do this if desired.
2024-06-21[clang][dataflow] Add a callback run on the pre-transfer state. (#96140)martinboehme1-12/+14
At the same time, rename `PostVisitCFG` to the more descriptive `PostAnalysisCallbacks` (which emphasizes the fact that these callbacks are run after the dataflow analysis itself has converged). Before this patch, it was only possible to run a callback on the state _after_ the transfer function had been applied, but for many analyses, it's more natural to to check the state _before_ the transfer function has been applied, because we are usually checking the preconditions for some operation. Some checks are impossible to perform on the "after" state because we can no longer check the precondition; for example, the `++` / `--` operators on raw pointers require the operand to be nonnull, but after the transfer function for the operator has been applied, the original value of the pointer can no longer be accessed. `UncheckedOptionalAccessModelTest` has been modified to run the diagnosis callback on the "before" state. In this particular case, diagnosis can be run unchanged on either the "before" or "after" state, but we want this test to demonstrate that running diagnosis on the "before" state is usually the preferred approach. This change is backwards-compatible; all existing analyses will continue to run the callback on the "after" state.