4742 Commits

Author SHA1 Message Date
Ziqing Luo
8094454ea1
[StaticAnalyzer] Fix tryExpandAsInteger's failures on PCH macros (#142722)
The function `tryExpandAsInteger` attempts to extract an integer from a
macro definition. Previously, the attempt would fail when the macro is
from a PCH, because the function tried to access the text buffer of the
source file, which does not exist in case of PCHs. The fix uses
`Preprocessor::getSpelling`, which works in either cases.

rdar://151403070

---------

Co-authored-by: Balazs Benics <benicsbalazs@gmail.com>
2025-06-05 11:28:16 +02:00
Donát Nagy
6833076a5d
[analyzer][NFC] Introduce framework for checker families (#139256)
The checker classes (i.e. classes derived from `CheckerBase` via the
utility template `Checker<...>`) act as intermediates between the user
and the analyzer engine, so they have two interfaces:
- On the frontend side, they have a public name, can be enabled or
disabled, can accept checker options and can be reported as the source
of bug reports.
- On the backend side, they can handle various checker callbacks and
they "leave a mark" on the `ExplodedNode`s that are created by them.
(These `ProgramPointTag` marks are internal: they appear in debug logs
and can be queried by checker logic; but the user doesn't see them.)

In a significant majority of the checkers there is 1:1 correspondence
between these sides, but there are also many checker classes where
several related user-facing checkers share the same backend class.
Historically each of these "multi-part checker" classes had its own
hacks to juggle its multiple names, which led to lots of ugliness like
lazy initialization of `mutable std::unique_ptr<BugType>` members and
redundant data members (when a checker used its custom `CheckNames`
array and ignored the inherited single `Name`).

My recent commit 27099982da2f5a6c2d282d6b385e79d080669546 tried to unify
and standardize these existing solutions to get rid of some of the
technical debt, but it still used enum values to identify the checker
parts within a "multi-part" checker class, which led to some ugliness.

This commit introduces a new framework which takes a more direct,
object-oriented approach: instead of identifying checker parts with
`{parent checker object, index of part}` pairs, the parts of a
multi-part checker become stand-alone objects that store their own name
(and enabled/disabled status) as a data member.

This is implemented by separating the functionality of `CheckerBase`
into two new classes: `CheckerFrontend` and `CheckerBackend`. The name
`CheckerBase` is kept (as a class derived from both `CheckerFrontend`
and `CheckerBackend`), so "simple" checkers that use `CheckerBase` and
`Checker<...>` continues to work without changes. However we also get
first-class support for the "many frontends - one backend" situation:
- The class `CheckerFamily<...>` works exactly like `Checker<...>` but
inherits from `CheckerBackend` instead of `CheckerBase`, so it won't
have a superfluous single `Name` member.
- Classes deriving from `CheckerFamily` can freely own multiple
`CheckerFrontend` data members, which are enabled within the
registration methods corresponding to their name and can be used to
initialize the `BugType`s that they can emit.

In this scheme each `CheckerFamily` needs to override the pure virtual
method `ProgramPointTag::getTagDescription()` which returns a string
which represents that class for debugging purposes. (Previously this
used the name of one arbitrary sub-checker, which was passable for
debugging purposes, but not too elegant.)

I'm planning to implement follow-up commits that convert all the
"multi-part" checkers to this `CheckerFamily` framework.
2025-05-26 20:27:42 +02:00
Balazs Benics
9a440f8477
[analyzer] Ignore [[clang::flag_enum]] enums in the EnumCastOutOfRange checker (#141232)
Resolves
https://github.com/llvm/llvm-project/issues/76208#issuecomment-2830854351

Quoting the docs of `[[clang::flag_enum]]`:
https://clang.llvm.org/docs/AttributeReference.html#flag-enum

> This attribute can be added to an enumerator to signal to the compiler that it
> is intended to be used as a flag type. This will cause the compiler to assume
> that the range of the type includes all of the values that you can get by
> manipulating bits of the enumerator when issuing warnings.

Ideally, we should still check the upper bounds but for simplicity let's not bother for now.
2025-05-25 11:59:50 +02:00
Balázs Kéri
be50ada9d0
[clang][analyzer] Refine modeling of 'getcwd' in StdCLibraryFunctions checker (#141076)
Add extra branches for the case when the buffer argument is NULL.

Fixes #135720
2025-05-23 09:26:31 +02:00
Balázs Benics
8818728962
[analyzer] Add previous CFG block to BlockEntrance ProgramPoints (#140861)
This helps to gain contextual information about how we entered a CFG block.

The `noexprcrash.c` test probably changed due to the fact that now
BlockEntrance ProgramPoint Profile also hashes the pointer of the
previous CFG block. I didn't investigate.

CPP-6483
2025-05-21 13:33:51 +02:00
Prabhu Rajasekaran
1a9377bef3
[clang][analysis] Thread Safety Analysis: Handle parenthesis (#140656) 2025-05-20 07:45:14 -07:00
Fangyi Zhou
81d48e0f61
[clang][analyzer] Fix a nullptr dereference when -ftime-trace is used (Reland) (#139980)
Fixes #139779.

The bug was introduced in #137355 in `SymbolConjured::getStmt`, when
trying to obtain a statement for a CFG initializer without an
initializer.  This commit adds a null check before access.

Previous PR #139820, Revert #139936

Additional notes since previous PR:

When conjuring a symbol, sometimes there is no valid CFG element, e.g.
in the file causing the crash, there is no element at all in the CFG. In
these cases, the CFG element reference in the expression engine will be
invalid. As a consequence, there needs to be extra checks to ensure the
validity of the CFG element reference.
2025-05-15 19:29:58 +02:00
Fangyi Zhou
baf2cfa299
Revert "[clang][analyzer] Fix a nullptr dereference when -ftime-trace is used" (#139936)
Reverts llvm/llvm-project#139820

Reverting due to buildbot failures in asan
2025-05-14 13:45:05 -04:00
Donát Nagy
899f26315c
[NFC][analyzer] Document configuration options (#135169)
This commit documents the process of specifying values for the analyzer
options and checker options implemented in the static analyzer, and adds
a script which includes the documentation of the analyzer options (which
was previously only available through a command-line flag) in the
RST-based web documentation.
2025-05-14 18:28:44 +02:00
Fangyi Zhou
440e510b89
[clang][analyzer] Fix a nullptr dereference when -ftime-trace is used (#139820)
Fixes #139779.

The bug was introduced in #137355 in `SymbolConjured::getStmt`, when
trying to obtain a statement for a CFG initializer without an
initializer. This commit adds a null check before access.
2025-05-14 16:35:57 +02:00
Ziqing Luo
41229581a4
[analyzer] Fix crashing __builtin_bit_cast (#139188)
Previously, CSA did not handle __builtin_bit_cast correctly. It
evaluated the LvalueToRvalue conversion for the casting expression,
but did not actually convert the value of the expression to be of the
destination type.
This commit fixes the problem.

rdar://149987320
2025-05-13 10:24:02 -07:00
Fangyi Zhou
6078f5eb21
Reland [Clang][analyzer] replace Stmt* with ConstCFGElement in SymbolConjured (#137355)
Closes #57270.

This PR changes the `Stmt *` field in `SymbolConjured` with
`CFGBlock::ConstCFGElementRef`. The motivation is that, when conjuring a
symbol, there might not always be a statement available, causing
information to be lost for conjured symbols, whereas the CFGElementRef
can always be provided at the callsite.

Following the idea, this PR changes callsites of functions to create
conjured symbols, and replaces them with appropriate `CFGElementRef`s.

There is a caveat at loop widening, where the correct location is the
CFG terminator (which is not an element and does not have a ref). In
this case, the first element in the block is passed as a location.

Previous PR #128251, Reverted at #137304.
2025-05-12 14:19:44 +02:00
Donát Nagy
9600a12f0d
[analyzer] Workaround for slowdown spikes (unintended scope increase) (#136720)
Recently some users reported that they observed large increases of
runtime (up to +600% on some translation units) when they upgraded to a
more recent (slightly patched, internal) clang version. Bisection
revealed that the bulk of this increase was probably caused by my
earlier commit bb27d5e5c6b194a1440b8ac4e5ace68d0ee2a849 ("Don't assume
third iteration in loops").

As I evaluated that earlier commit on several open source project, it
turns out that on average it's runtime-neutral (or slightly helpful: it
reduced the total analysis time by 1.5%) but it can cause runtime spikes
on some code: in particular it more than doubled the time to analyze
`tmux` (one of the smaller test projects).

Further profiling and investigation proved that these spikes were caused
by an _increase of analysis scope_ because there was an heuristic that
placed functions on a "don't inline this" blacklist if they reached the
`-analyzer-max-loop` limit (anywhere, on any one execution path) --
which became significantly rarer when my commit ensured the analyzer no
longer "just assumes" four iterations. (With more inlining significantly
more entry points use up their allocated budgets, which leads to the
increased runtime.)

I feel that this heuristic for the "don't inline" blacklist is
unjustified and arbitrary, because reaching the "retry without inlining"
limit on one path does not imply that inlining the function won't be
valuable on other paths -- so I hope that we can eventually replace it
with more "natural" limits of the analysis scope.

However, the runtime increases are annoying for the users whose project
is affected, so I created this quick workaround commit that approximates
the "don't inline" blacklist effects of ambiguous loops (where the
analyzer doesn't understand the loop condition) without fully reverting
the "Don't assume third iteration" commit (to avoid reintroducing the
false positives that were eliminated by it).

Investigating this issue was a team effort: I'm grateful to Endre Fülöp
(gamesh411) who did the bisection and shared his time measurement setup,
and Gábor Tóthvári (tigbr) who helped me in profiling.
2025-05-12 10:56:29 +02:00
Ryosuke Niwa
436504c3b9
[webkit.UncountedLambdaCapturesChecker] Treat every argument of std::ranges functions as noescape. (#138995)
Functions in std::ranges namespace does not store the lambada passed-in
as an arugment in heap so treat such an argument as if it has
[[noescape]] in the WebKit lambda capture checker so that we don't emit
warnings for capturing raw pointers or references to smart-pointer
capable objects.
2025-05-09 17:44:36 -07:00
Ryosuke Niwa
984475d82d
[RawPtrRefMemberChecker] Add the support for union and pointers to unsafe pointers. (#138042)
This PR adds support for detecting unsafe union members and pointers to
unsafe pointers (e.g. T** where T* is an unsafe pointer type).
2025-05-09 17:44:13 -07:00
Ziqing Luo
b756c82bfa
Re-land "[analyzer] Make it a noop when initializing a field of empty record" (#138951)
The original commit assumes that
`CXXConstructExpr->getType()->getAsRecordDecl()` is always a
`CXXRecordDecl` but it is not true for ObjC programs.

This relanding changes
`cast<CXXRecordDecl>(CXXConstructExpr->getType()->getAsRecordDecl())`
to
`dyn_cast_or_null<CXXRecordDecl>(CXXConstructExpr->getType()->getAsRecordDecl())`

This reverts commit 9048c2d4f239cb47fed17cb150e2bbf3934454c2.
rdar://146753089
2025-05-07 15:55:52 -07:00
Ryosuke Niwa
5d7e8ac53b
[webkit.UncountedLambdaCapturesChecker] Treat a copy capture of a CheckedPtr object as safe (#138068)
Allow copy capture of a reference to a CheckedPtr capable object since
such a capture will copy the said object instead of keeping a dangling
reference to the object.
2025-05-07 15:07:41 -07:00
Balazs Benics
9048c2d4f2
Revert "[analyzer] Make it a noop when initializing a field of empty record" (#138951)
Reverts llvm/llvm-project#138594

Crashes, see: https://lab.llvm.org/buildbot/#/builders/144/builds/24534
2025-05-07 21:52:21 +02:00
Ziqing Luo
db38cc27bc
[analyzer] Make it a noop when initializing a field of empty record (#138594)
Previously, Static Analyzer initializes empty type fields with zeroes.
This can cause problems when those fields have no unique addresses. For
example, https://github.com/llvm/llvm-project/issues/137252.

rdar://146753089
2025-05-07 21:32:08 +02:00
Ryosuke Niwa
e6a5d73f4d
[WebKit checkers] Treat std::bit_cast as a pointer conversion (#137476)
WebKit repalced its use of WTF::bitwise_cast with std::bit_cast. Add the
support for recognizing it as a pointer conversion.
2025-04-30 17:59:31 -07:00
Ryosuke Niwa
16e5c3ddad
[alpha.webkit.RetainPtrCtorAdoptChecker] An assortment of small enhancements (#135329)
This PR implements various small enhancements to
alpha.webkit.RetainPtrCtorAdoptChecker:
 - Detect leaks from [[X alloc] init] when ARC is disabled.
 - Detect leaks from calling Create, Copy, and other +1 CF functions.
 - Recognize [allocX() init] pattern where allocX is a C/C++ function.
 - Recognize _init in addition to init as an init function.
 - Recognize [[[X alloc] init] autorelease].
 - Recognize CFBridgingRelease.
 - Support CF_RETRUNS_RETAINED on out arguments of a C function.
- Support returning +1 object in Create, Copy, and other +1 functions or
+1 selectors.
 - Support variadic Create, Copy, and other +1 C/C++ functions.

To make these enhancements, this PR introduces new visit functions for
ObjCMessageExpr, ReturnStmt, VarDecl, and BinaryOperator. These
functions look for a specific construct mentioned above and adds an
expression such as [[X alloc] init] or CreateX to a DenseSet
CreateOrCopyFnCall when the expression does not result in leaks. When
the code to detect leaks such as the one in visitObjCMessageExpr later
encounters this expression, it can bail out early if the expression is
in the set.
2025-04-27 14:24:32 -07:00
Balazs Benics
6171e4b34b
Revert "[Clang][analyzer] replace Stmt* with ConstCFGElementRef in SymbolConjured" (#137304)
Reverts llvm/llvm-project#128251

ASAN bots reported some errors:
https://lab.llvm.org/buildbot/#/builders/55/builds/10398
Reverting for investigation.

```
Failed Tests (6):
  Clang :: Analysis/loop-widening-ignore-static-methods.cpp
  Clang :: Analysis/loop-widening-notes.cpp
  Clang :: Analysis/loop-widening-preserve-reference-type.cpp
  Clang :: Analysis/loop-widening.c
  Clang :: Analysis/loop-widening.cpp
  Clang :: Analysis/this-pointer.cpp
Testing Time: 411.55s
Total Discovered Tests: 118563
  Skipped          :     33 (0.03%)
  Unsupported      :   2015 (1.70%)
  Passed           : 116291 (98.08%)
  Expectedly Failed:    218 (0.18%)
  Failed           :      6 (0.01%)
FAILED: CMakeFiles/check-all /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/CMakeFiles/check-all 
cd /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan && /usr/bin/python3 /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/./bin/llvm-lit -sv --param USE_Z3_SOLVER=0 /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/utils/mlgo-utils /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/tools/lld/test /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/tools/mlir/test /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/tools/clang/test /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/utils/lit /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/test
ninja: build stopped: subcommand failed.
```

```
/home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/bin/clang -cc1 -internal-isystem /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/lib/clang/21/include -nostdsysteminc -analyze -analyzer-constraints=range -setup-static-analyzer -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify -analyzer-config eagerly-assume=false /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/test/Analysis/loop-widening.c # RUN: at line 1
+ /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/bin/clang -cc1 -internal-isystem /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/lib/clang/21/include -nostdsysteminc -analyze -analyzer-constraints=range -setup-static-analyzer -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify -analyzer-config eagerly-assume=false /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/test/Analysis/loop-widening.c
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/bin/clang -cc1 -internal-isystem /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/lib/clang/21/include -nostdsysteminc -analyze -analyzer-constraints=range -setup-static-analyzer -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify -analyzer-config eagerly-assume=false /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/test/Analysis/loop-widening.c
1.	<eof> parser at end of file
2.	While analyzing stack: 
	#0 Calling nested_loop_inner_widen
 #0 0x0000c894cca289cc llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/llvm/lib/Support/Unix/Signals.inc:804:13
 #1 0x0000c894cca23324 llvm::sys::RunSignalHandlers() /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/llvm/lib/Support/Signals.cpp:106:18
 #2 0x0000c894cca29bbc SignalHandler(int, siginfo_t*, void*) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/llvm/lib/Support/Unix/Signals.inc:0:3
 #3 0x0000f6898da4a8f8 (linux-vdso.so.1+0x8f8)
 #4 0x0000f6898d377608 (/lib/aarch64-linux-gnu/libc.so.6+0x87608)
 #5 0x0000f6898d32cb3c raise (/lib/aarch64-linux-gnu/libc.so.6+0x3cb3c)
 #6 0x0000f6898d317e00 abort (/lib/aarch64-linux-gnu/libc.so.6+0x27e00)
 #7 0x0000c894c5e77fec __sanitizer::Atexit(void (*)()) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp:168:10
 #8 0x0000c894c5e76680 __sanitizer::Die() /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_termination.cpp:52:5
 #9 0x0000c894c5e69650 Unlock /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/compiler-rt/lib/hwasan/../sanitizer_common/sanitizer_mutex.h:250:16
#10 0x0000c894c5e69650 ~GenericScopedLock /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/compiler-rt/lib/hwasan/../sanitizer_common/sanitizer_mutex.h:386:51
#11 0x0000c894c5e69650 __hwasan::ScopedReport::~ScopedReport() /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/compiler-rt/lib/hwasan/hwasan_report.cpp:54:5
#12 0x0000c894c5e68de0 __hwasan::(anonymous namespace)::BaseReport::~BaseReport() /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/compiler-rt/lib/hwasan/hwasan_report.cpp:476:7
#13 0x0000c894c5e66b74 __hwasan::ReportTagMismatch(__sanitizer::StackTrace*, unsigned long, unsigned long, bool, bool, unsigned long*) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/compiler-rt/lib/hwasan/hwasan_report.cpp:1091:1
#14 0x0000c894c5e52cf8 Destroy /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/compiler-rt/lib/hwasan/../sanitizer_common/sanitizer_common.h:532:31
#15 0x0000c894c5e52cf8 ~InternalMmapVector /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/compiler-rt/lib/hwasan/../sanitizer_common/sanitizer_common.h:642:56
#16 0x0000c894c5e52cf8 __hwasan::HandleTagMismatch(__hwasan::AccessInfo, unsigned long, unsigned long, void*, unsigned long*) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/compiler-rt/lib/hwasan/hwasan.cpp:245:1
#17 0x0000c894c5e551c8 __hwasan_tag_mismatch4 /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/compiler-rt/lib/hwasan/hwasan.cpp:764:1
#18 0x0000c894c5e6a2f8 __interception::InterceptFunction(char const*, unsigned long*, unsigned long, unsigned long) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/compiler-rt/lib/interception/interception_linux.cpp:60:0
#19 0x0000c894d166f664 getBlock /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h:217:45
#20 0x0000c894d166f664 getCFGElementRef /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h:230:59
#21 0x0000c894d166f664 clang::ento::ExprEngine::processCFGBlockEntrance(clang::BlockEdge const&, clang::ento::NodeBuilderWithSinks&, clang::ento::ExplodedNode*) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:2570:45
#22 0x0000c894d15f3a1c hasGeneratedNodes /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h:333:37
#23 0x0000c894d15f3a1c clang::ento::CoreEngine::HandleBlockEdge(clang::BlockEdge const&, clang::ento::ExplodedNode*) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:319:20
#24 0x0000c894d15f2c34 clang::ento::CoreEngine::dispatchWorkItem(clang::ento::ExplodedNode*, clang::ProgramPoint, clang::ento::WorkListUnit const&) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:220:7
#25 0x0000c894d15f2398 operator-> /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/libcxx_install_hwasan/include/c++/v1/__memory/unique_ptr.h:267:101
#26 0x0000c894d15f2398 clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*, unsigned int, llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>)::$_0::operator()(unsigned int) const /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:140:12
#27 0x0000c894d15f14b4 clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*, unsigned int, llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:165:7
#28 0x0000c894d0ebb9dc release /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h:232:9
#29 0x0000c894d0ebb9dc ~IntrusiveRefCntPtr /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h:196:27
#30 0x0000c894d0ebb9dc ExecuteWorkList /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h:192:5
#31 0x0000c894d0ebb9dc RunPathSensitiveChecks /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:772:7
#32 0x0000c894d0ebb9dc (anonymous namespace)::AnalysisConsumer::HandleCode(clang::Decl*, unsigned int, clang::ento::ExprEngine::InliningModes, llvm::DenseSet<clang::Decl const*, llvm::DenseMapInfo<clang::Decl const*, void>>*) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:741:5
#33 0x0000c894d0eb6ee4 begin /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/llvm/include/llvm/ADT/DenseMap.h:0:0
#34 0x0000c894d0eb6ee4 begin /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/llvm/include/llvm/ADT/DenseSet.h:187:45
#35 0x0000c894d0eb6ee4 HandleDeclsCallGraph /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:516:29
#36 0x0000c894d0eb6ee4 runAnalysisOnTranslationUnit /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:584:5
#37 0x0000c894d0eb6ee4 (anonymous namespace)::AnalysisConsumer::HandleTranslationUnit(clang::ASTContext&) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:647:3
#38 0x0000c894d18a7a38 clang::ParseAST(clang::Sema&, bool, bool) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/Parse/ParseAST.cpp:0:13
#39 0x0000c894ce81ed70 clang::FrontendAction::Execute() /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/Frontend/FrontendAction.cpp:1231:10
#40 0x0000c894ce6f2144 getPtr /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/llvm/include/llvm/Support/Error.h:278:42
#41 0x0000c894ce6f2144 operator bool /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/llvm/include/llvm/Support/Error.h:241:16
#42 0x0000c894ce6f2144 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/Frontend/CompilerInstance.cpp:1058:23
#43 0x0000c894cea718cc operator-> /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/libcxx_install_hwasan/include/c++/v1/__memory/shared_ptr.h:635:12
#44 0x0000c894cea718cc getFrontendOpts /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/include/clang/Frontend/CompilerInstance.h:307:12
#45 0x0000c894cea718cc clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:301:14
#46 0x0000c894c5e9cf28 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/tools/driver/cc1_main.cpp:294:15
#47 0x0000c894c5e92a9c ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/tools/driver/driver.cpp:223:12
#48 0x0000c894c5e902ac clang_main(int, char**, llvm::ToolContext const&) /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/tools/driver/driver.cpp:0:12
#49 0x0000c894c5eb2e34 main /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/tools/clang/tools/driver/clang-driver.cpp:17:3
#50 0x0000f6898d3184c4 (/lib/aarch64-linux-gnu/libc.so.6+0x284c4)
#51 0x0000f6898d318598 __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x28598)
#52 0x0000c894c5e52a30 _start (/home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/bin/clang+0x6512a30)
/home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/tools/clang/test/Analysis/Output/loop-widening.c.script: line 2: 2870204 Aborted                 /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/bin/clang -cc1 -internal-isystem /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build_hwasan/lib/clang/21/include -nostdsysteminc -analyze -analyzer-constraints=range -setup-static-analyzer -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify -analyzer-config eagerly-assume=false /home/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/clang/test/Analysis/loop-widening.c
```
2025-04-25 11:56:38 +02:00
Fangyi Zhou
ec936b3186
[Clang][analyzer] Replace Stmt* with ConstCFGElementRef in SymbolConjured (#128251)
This PR changes the `Stmt *` field in `SymbolConjured` with
`CFGBlock::ConstCFGElementRef`. The motivation is that, when conjuring a
symbol, there might not always be a statement available, causing
information to be lost for conjured symbols, whereas the CFGElementRef
can always be provided at the callsite.

Following the idea, this PR changes callsites of functions to create
conjured symbols, and replaces them with appropriate `CFGElementRef`s.

Closes #57270
2025-04-25 10:39:45 +02:00
Ryosuke Niwa
70e303f11e
[webkit.UncountedLambdaCapturesChecker] Treat a call to lambda function via a variable as safe. (#135688)
This PR makes the checker ignore a function call to lambda via a local
variable.
2025-04-24 17:10:05 -07:00
Ryosuke Niwa
a7e53124eb
[alpha.webkit.UncheckedCallArgsChecker] Checker fails to recognize CanMakeCheckedPtrBase (#136500)
This PR fixes the bug that alpha.webkit.UncheckedCallArgsChecker did not
recognize CanMakeCheckedPtrBase due to getAsCXXRecordDecl returning
nullptr for it in hasPublicMethodInBase. Manually grab getTemplatedDecl
out of TemplateSpecializationType then CXXRecordDecl to workaround this
bug in clang frontend.
2025-04-24 13:15:27 -07:00
Ryosuke Niwa
a05aeda305
[RawPtrRefMemberChecker] Member variable checker should allow T* in smart pointer classes (#136503)
This PR fixes member variable checker to allow the usage of T* in smart
pointer classes. e.g. alpha.webkit.NoUncheckedPtrMemberChecker should
allow T* to appear within RefPtr.
2025-04-23 12:41:56 -07:00
Aaron Ballman
71ce9e26ae
Control analysis-based diagnostics with #pragma (#136323)
Previously, analysis-based diagnostics (like -Wconsumed) had to be
enabled at file scope in order to be run at the end of each function
body. This meant that they did not respect #pragma clang diagnostic
enabling or disabling the diagnostic.

Now, these pragmas can control the diagnostic emission.

Fixes #42199
2025-04-23 06:55:10 -04:00
Ryosuke Niwa
8ca8c404d3
[WebKit checkers] Treat global const variables as safe (#136170)
This PR makes WebKit checkers treat a variable with global storage as
safe instead of constraining to ones that start with k or _k.
2025-04-22 16:15:26 -07:00
Fangyi Zhou
461168a3d3
[clang][analyzer] Handle CXXParenInitListExpr alongside InitListExpr (#136041)
As reported in #135665, C++20 parenthesis initializer list expressions
are not handled correctly and were causing crashes. This commit attempts
to fix the issue by handing parenthesis initializer lists along side
existing initializer lists.

Fixes #135665.
2025-04-20 17:32:42 +02:00
Pavel Skripkin
060f9556a2
[clang][analyzer] Fix error path of builtin overflow (#136345)
According to
https://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins,
result of builtin_*_overflow functions will be initialized even in case
of overflow. Align analyzer logic to docs and always initialize 3rd
argument of such builtins.

Closes #136292
2025-04-20 16:14:41 +02:00
Matheus Izvekov
fe94f11407
[clang] Fix elaborated keyword canonicalization (#135916) 2025-04-16 16:27:24 -03:00
Ryosuke Niwa
517605c20e
[alpha.webkit.UnretainedCallArgsChecker] Add the support for RetainPtrArc (#135532)
WebKit uses #define to rename RetainPtr to RetainPtrArc so add the
support for it.
2025-04-15 20:00:51 -07:00
Connector Switch
cc354d6a6d
[NFC] Fix destroy typo. (#135640) 2025-04-15 08:20:44 +08:00
Ryosuke Niwa
2206e15e78
[alpha.webkit.UnretainedCallArgsChecker] Don't emit a warning for RetainPtr::operator= (#135526)
Generalize the check for operator= so that it works for RetainPtr and
CheckedPtr instead of just RefPtr.
2025-04-14 15:03:21 -07:00
Ryosuke Niwa
6136019780
[alpha.webkit.ForwardDeclChecker] Recognize a forward declared template specialization (#134545)
This PR fixes a bug that when a template specialization is declared with
a forward declaration of a template, the checker fails to find its
definition in the same translation unit and erroneously emit an unsafe
forward declaration warning.
2025-04-10 15:28:36 -07:00
Ryosuke Niwa
c26d097d0c
[alpha.webkit.RetainPtrCtorAdoptChecker] Support adopt(cast(copy(~)) (#132316)
This PR adds the support for recognizing calling adoptCF/adoptNS on the
result of a cast operation on the return value of a function which
creates NS or CF types. It also fixes a bug that we weren't reporting
memory leaks when CF types are created without ever calling RetainPtr's
constructor, adoptCF, or adoptNS.

To do this, this PR adds a new mechanism to report a memory leak
whenever create or copy CF functions are invoked unless this CallExpr
has already been visited while validating a call to adoptCF. Also added
an early exit when isOwned returns IsOwnedResult::Skip due to an
unresolved template argument.
2025-04-10 15:26:10 -07:00
Ryosuke Niwa
2c31403f4f
[alpha.webkit.UnretainedLambdaCapturesChecker] Add the support for protectedSelf (#132518)
This PR adds the support for treating capturing of "self" as safe if the
lambda simultaneously captures "protectedSelf", which is a RetainPtr of
"self".

This PR also fixes a bug that the checker wasn't generating a warning
when "self" is implicitly captured. Note when "self" is implicitly
captured, we use the lambda's getBeginLoc as a fallback source location.
2025-04-09 11:52:36 -07:00
Ryosuke Niwa
c8d49e9dd2
[alpha.webkit.RetainPtrCtorAdoptChecker] Recognize mutableCopy from literal as +1 (#132350)
This PR adds the support for recognizing the return value of copy /
mutableCopy as +1. isAllocInit and isOwned now traverses
PseudoObjectExpr to its last semantic expression.
2025-04-09 10:33:08 -07:00
Balázs Kéri
31ef7acf12
[clang][analyzer] Fix a possible crash in CastSizeChecker (#134387) 2025-04-07 09:46:03 +02:00
Ryosuke Niwa
d8fd665960
[alpha.webkit.ForwardDeclChecker] Ignore forward declared struct. (#133804)
There are some system libraries such as sqlite3 which forward declare a
struct then use a pointer to that forward declared type in various APIs.
Ignore these types ForwardDeclChecker like other pointer types.
2025-04-04 12:04:20 -07:00
Ryosuke Niwa
bf1d27889b
[WebKit checkers] Treat Objective-C message send return value as safe (#133605)
Objective-C selectors are supposed to return autoreleased object. Treat
these return values as safe.
2025-04-04 11:25:24 -07:00
Nikolas Klauser
04676c6160
Revert "Enable unnecessary-virtual-specifier by default" (#134105)
Reverts llvm/llvm-project#133265

This causes the whole libc++ CI to fail, since we're not building
against a compiler built from current trunk. Specifically, the CMake
changes causes some feature detection to fail, resulting in CMake
being unable to configure libc++.
2025-04-02 17:59:08 +02:00
Ryosuke Niwa
6ff33edcdc
[alpha.webkit.NoUnretainedMemberChecker] Ignore system-header-defined ivar / property of a forward declared type (#133755)
Prior to this PR, we were emitting warnings for Objective-C ivars and
properties if the forward declaration of the type appeared first in a
non-system header. This PR fixes the checker so tha we'd ignore ivars
and properties defined for a forward declared type.
2025-03-31 14:59:41 -07:00
Devon Loehr
4007de00a0
Enable unnecessary-virtual-specifier by default (#133265)
This turns on the unnecessary-virtual-specifier warning in general, but
disables it when building LLVM. It also tweaks the warning description
to be slightly more accurate.

Background: I've been working on cleaning up this warning in two
codebases: LLVM and chromium (plus its dependencies). The chromium
cleanup has been straightforward. Git archaeology shows that there are
two reasons for the warnings: classes to which `final` was added after
they were initially committed, and classes with virtual destructors that
nobody remarks on. Presumably the latter case is because people are just
very used to destructors being virtual.

The LLVM cleanup was more surprising: I discovered that we have an [old
policy](https://llvm.org/docs/CodingStandards.html#provide-a-virtual-method-anchor-for-classes-in-headers)
about including out-of-line virtual functions in every class with a
vtable, even `final` ones. This means our codebase has many virtual
"anchor" functions which do nothing except control where the vtable is
emitted, and which trigger the warning. I looked into alternatives to
satisfy the policy, such as using destructors instead of introducing a
new function, but it wasn't clear if they had larger implications.

Overall, it seems like the warning is genuinely useful in most codebases
(evidenced by chromium and its dependencies), and LLVM is an unusual
case. Therefore we should enable the warning by default, and turn it off
only for LLVM builds.
2025-03-31 16:28:53 +02:00
T-Gruber
d63cc4c876
[analyzer] Unknown array lvalue element in Store (#133381)
Remove the early return for BaseRegions of type ElementRegion. Return
meaningful MemRegionVal for these cases as well.
Previous discussion:
https://discourse.llvm.org/t/lvalueelement-returns-unknownval-for-multi-dimensional-arrays/85476
2025-03-31 08:44:28 +02:00
Ryosuke Niwa
304b3c5000
[alpha.webkit.RawPtrRefMemberChecker] The checker doesn't warn Objective-C types in ivars. (#132833)
This PR fixes the bug that we weren't generating warnings when a raw
poiner is used to point to a NS type in Objective-C ivars. Also fix the
bug that we weren't suppressing this warning in system headers.
2025-03-28 17:34:51 -07:00
Balázs Benics
319045d8c4
[analyzer] Add metrics tracking time spent in Z3 solver (#133236)
These metrics would turn out to be useful for verifying an upgrade of Z3.
2025-03-28 11:26:28 +01:00
Donát Nagy
50d4ae4a62
[analyzer] Fix format attribute handling in GenericTaintChecker (#132765)
Previously `optin.taint.GenericTaint` misinterpreted the parameter
indices and produced false positives in situations when a [format
attribute](https://clang.llvm.org/docs/AttributeReference.html#format)
is applied on a non-static method. This commit fixes this bug
2025-03-28 10:20:26 +01:00
Ryosuke Niwa
a285be320a
[WebKit Checkers] Recognize Objective-C and CF pointer conversion functions. (#132784)
Recognize dynamic_objc_cast, checked_objc_cast, dynamic_cf_cast, and
checked_cf_cast.
2025-03-27 15:47:38 -07:00
Ryosuke Niwa
2b43ecd27b
[webkit.RefCntblBaseVirtualDtor] Add support for NoVirtualDestructorBase. (#132497)
This PR adds the support for WTF::NoVirtualDestructorBase, which
signifies to the checker that the class is exempt from having a virtual
destructor.
2025-03-26 16:57:49 -07:00