2640 Commits

Author SHA1 Message Date
Balázs Kéri
854cbbf4a8
[clang][analyzer] Split NullDereferenceChecker into modeling and reporting (#122139)
The checker currently reports beneath the null dereference dereferences
of undefined value and of label addresses. If we want to add more kinds
of invalid dereferences (or split the existing functionality) it is more
useful to make it separate checkers.
To make this possible the existing checker is split into a
DereferenceModeling part and a NullDereference checker that actually
only switches on the check of null dereference. This is similar
architecture as in MallocChecker and CStringChecker.

The change is almost NFC but a new (modeling) checker is added. If the
NullDereference checker is turned off the found invalid dereferences
will still stop the analysis without emitted warning (this is different
compared to the old behavior).
2025-01-10 11:17:06 +01:00
Ryosuke Niwa
5162fde6ee
[webkit.UncountedLambdaCapturesChecker] Fix a nullptr deference. (#120702)
Added a nullptr check.
2024-12-20 10:18:08 -08:00
Ryosuke Niwa
a71f9e6986
[webkit.UncountedLambdaCapturesChecker] Detect protectedThis pattern. (#120528)
In WebKit, we often capture this as Ref or RefPtr in addition to this
itself so that the object lives as long as a capturing lambda stays
alive.

Detect this pattern and treat it as safe. This PR also makes the check
for a lambda being passed as a function argument more robust by handling
CXXBindTemporaryExpr, CXXConstructExpr, and DeclRefExpr referring to the
lambda.
2024-12-19 18:11:28 -08:00
Ryosuke Niwa
d3c4637cbb
[WebKit checkers] Recognize adoptRef as a safe function (#120629)
adoptRef in WebKit constructs Ref/RefPtr so treat it as such in
isCtorOfRefCounted.
Also removed the support for makeRef and makeRefPtr as they don't exist
any more.
2024-12-19 18:08:24 -08:00
Ryosuke Niwa
b5d02786be
Revert "[WebKit checkers] Recognize adoptRef as a safe function" (#120626)
Reverts llvm/llvm-project#119846. Introduced a failing test.
2024-12-19 11:42:17 -08:00
Ryosuke Niwa
98c97d4a19
[WebKit checkers] Recognize adoptRef as a safe function (#119846)
adoptRef in WebKit constructs Ref/RefPtr so treat it as such in
isCtorOfRefCounted. Also removed the support for makeRef and makeRefPtr
as they don't exist any more.
2024-12-19 11:09:36 -08:00
Balazs Benics
23377890d0
[analyzer][NFC] Migrate {SymInt,IntSym}Expr to use APSIntPtr (4/4) (#120438) 2024-12-19 13:01:38 +01:00
Balazs Benics
d0d5101f99
[analyzer][NFC] Migrate nonloc::ConcreteInt to use APSIntPtr (2/4) (#120436) 2024-12-19 12:51:40 +01:00
Balazs Benics
b41240be6b
[analyzer][NFC] Introduce APSIntPtr, a safe wrapper of APSInt (1/4) (#120435)
One could create dangling APSInt references in various ways in the past, that were sometimes assumed to be persisted in the BasicValueFactor.

One should always use BasicValueFactory to create persistent APSInts, that could be used by ConcreteInts or SymIntExprs and similar long-living objects.
If one used a temporary or local variables for this, these would dangle.
To enforce the contract of the analyzer BasicValueFactory and the uses of APSInts, let's have a dedicated strong-type for this.

The idea is that APSIntPtr is always owned by the BasicValueFactory, and that is the only component that can construct it.

These PRs are all NFC - besides fixing dangling APSInt references.
2024-12-19 12:04:04 +01:00
Mariya Podchishchaeva
e5a6f1c779
[NFC][webkit.UncountedLambdaCapturesChecker] Remove unnecessary check (#120069)
CXXMD is checked for null, but it can't be null inside of a visitor's
method. Found by a static analyzer tool.
2024-12-17 10:45:10 +01:00
Ryosuke Niwa
e86910337f
[webkit.UncountedLambdaCapturesChecker] Add a fallback for checking lambda captures (#119800) 2024-12-15 13:32:29 -08:00
Ryosuke Niwa
05860f9b38
[WebKit checkers] Recognize ensureFoo functions (#119681)
In WebKit, we often write Foo::ensureBar function which lazily
initializes m_bar and returns a raw pointer or a raw reference to m_bar.
Such a return value is safe to use for the duration of a member function
call in Foo so long as m_bar is const so that it never gets unset or
updated with a new value once it's initialized.

This PR adds support for recognizing these types of functions and
treating its return value as a safe origin of a function argument
(including "this") or a local variable.
2024-12-13 01:48:29 -08:00
Ryosuke Niwa
f7e868fe43
Fix a bug that CXXConstructExpr wasn't recognized by tryToFindPtrOrigin (#119336)
Prior to this PR, only CXXTemporaryObjectExpr, not CXXConstructExpr was
recognized in tryToFindPtrOrigin.
2024-12-12 09:37:04 -08:00
Ryosuke Niwa
377d1f0a6b
UncountedLocalVarsChecker and UncheckedLocalVarsChecker should recognize signletons. (#119339)
It's safe to have a raw pointer or a raw reference to a singleton
object. Explicitly allow this in UncountedLocalVarsChecker and
UncheckedLocalVarsChecker.
2024-12-10 15:57:58 -08:00
Rashmi Mudduluru
51a5b77b57
[Webkit Checkers] Introduce a Webkit checker for memory unsafe casts (#114606)
This PR introduces a new checker
`[alpha.webkit.MemoryUnsafeCastChecker]` that warns all downcasts from a base type to a derived type.

rdar://137766829
2024-12-05 11:01:27 -08:00
Kazu Hirata
a9bf16d961
[StaticAnalyzer] Migrate away from PointerUnion::{is,get} (NFC) (#118421)
Note that PointerUnion::{is,get} have been soft deprecated in
PointerUnion.h:

  // FIXME: Replace the uses of is(), get() and dyn_cast() with
  //        isa<T>, cast<T> and the llvm::dyn_cast<T>

I'm not touching PointerUnion::dyn_cast for now because it's a bit
complicated; we could blindly migrate it to dyn_cast_if_present, but
we should probably use dyn_cast when the operand is known to be
non-null.
2024-12-03 13:53:20 -08:00
vabridgers
8ac2b77a11
[analyzer] Remove alpha.core.IdenticalExpr Checker (#114715)
This change removes the alpha.core.IdenticalExpr static analysis checker
since it's checks are present in the clang-tidy checks
misc-redundant-expression and bugprone-branch-clone. This check was
implemented as a static analysis check using AST matching, and since
alpha and duplicated in 2 clang-tidy checks may be removed.

Co-authored-by: Vince Bridgers <vince.a.bridgers@ericsson.com>
2024-11-29 17:38:59 -06:00
vabridgers
e034c4ef7b
[analyzer] Modernize, improve and promote chroot checker (#117791)
This change modernizes, improves and promotes the chroot checker from
alpha to the Unix family of checkers. This checker covers the POS05
recommendations for use of chroot.

The improvements included modeling of a success or failure from chroot
and not falsely reporting a warning along an error path. This was made
possible through modernizing the checker to be flow sensitive.

---------

Co-authored-by: einvbri <vince.a.bridgers@ericsson.com>
Co-authored-by: Balazs Benics <benicsbalazs@gmail.com>
2024-11-29 08:23:08 +01:00
Ryosuke Niwa
dd8d85dba6
[webkit.UncountedLambdaCapturesChecker] Ignore lambda invocation with arguments (#117394)
Fixed a bug that UncountedLambdaCapturesChecker would emit a warning on
a lambda capture when the lambda is invoked with arguments.
LocalVisitor::VisitCallExpr was not tolerating a lambda invocation with
more than 1 arguments.
2024-11-22 16:42:39 -08:00
Ryosuke Niwa
9492744dc3
[webkit.UncountedLambdaCapturesChecker] Fix debug assertion failure. (#117090)
Only call getThisType() on an instance method.
2024-11-21 13:29:15 -08:00
Balazs Benics
e5ac9145ba
[analyzer][taint] Recognize tainted LazyCompoundVals (4/4) (#115919)
returned by-value from opaque function calls.
If a struct is returned by-value from an opaque call, the "value" of the
whole struct is represented by a Conjured symbol.
Later fields may slice off smaller subregions by creating Derived
symbols of that Conjured symbol, but those are handled well, and
"isTainted" returns true as expected.

However, passing the whole struct to "isTainted" would be false, because
LazyCompoundVals and CompoundVals are not handled.
This patch addresses this.

Fixes #114270

Split from #114835
2024-11-15 10:56:04 +01:00
Balazs Benics
8d43c880a5
Revert "[analyzer][Solver] Early return if sym is concrete on assuming" (#116362)
Reverts llvm/llvm-project#115579

This introduced a breakage:
https://lab.llvm.org/buildbot/#/builders/46/builds/7928
2024-11-15 10:28:40 +01:00
Ding Fei
4163136e2e
[analyzer][Solver] Early return if sym is concrete on assuming (#115579)
This could deduce some complex syms derived from simple ones whose
values could be constrainted to be concrete during execution, thus
reducing some overconstrainted states.

This commit also fix `unix.StdCLibraryFunctions` crash due to these
overconstrainted states being added to the graph, which is marked as
sink node (PosteriorlyOverconstrained). The 'assume' API is used in
non-dual style so the checker should protectively test whether these
newly added nodes are actually impossible.

1. The crash: https://godbolt.org/z/8KKWeKb86
2. The solver needs to solve equivalent: https://godbolt.org/z/ed8WqsbTh
2024-11-15 16:43:32 +08:00
Sirraide
dde802b153
[Clang] [NFC] Refactor AST visitors in Sema and the static analyser to use 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-11-15 08:04:08 +01:00
Ryosuke Niwa
6be567bfc2
[Webkit Checkers] Treat const member variables as a safe origin (#115594)
Treat const Ref, RefPtr, CheckedRef, CheckedPtr member variables as safe
pointer origin in WebKit's local variable and call arguments checkers.
2024-11-14 21:11:08 -08:00
Ryosuke Niwa
73b577cc8c
[WebKit checkers] Treat ref() and incrementCheckedPtrCount() as trivial (#115695)
Treat member function calls to ref() and incrementCheckedPtrCount() as
trivial so that a function which returns RefPtr/Ref out of a raw
reference / pointer is also considered trivial.
2024-11-13 16:28:01 -08:00
Ryosuke Niwa
2c6424e691
[webkit.UncountedLambdaCapturesChecker] Ignore trivial functions and [[clang::noescape]]. (#114897)
This PR makes webkit.UncountedLambdaCapturesChecker ignore trivial
functions as well as the one being passed to an argument with
[[clang::noescape]] attribute. This dramatically reduces the false
positive rate for this checker.

To do this, this PR replaces VisitLambdaExpr in favor of checking
lambdas via VisitDeclRefExpr and VisitCallExpr. The idea is that if a
lambda is defined but never called or stored somewhere, then capturing
whatever variable in such a lambda is harmless.

VisitCallExpr explicitly looks for direct invocation of lambdas and
registers its DeclRefExpr to be ignored in VisitDeclRefExpr. If a lambda
is being passed to a function, it checks whether its argument is
annotated with [[clang::noescape]]. If it's not annotated such, it
checks captures for their safety.

Because WTF::switchOn could not be annotated with [[clang::noescape]] as
function type parameters are variadic template function so we hard-code
this function into the checker.

In order to check whether "this" pointer is ref-counted type or not, we
override TraverseDecl and record the most recent method's declaration.

In addition, this PR fixes a bug in isUnsafePtr that it was erroneously
checking whether std::nullopt was returned by isUncounted and
isUnchecked as opposed to the actual boolean value.

Finally, this PR also converts the accompanying test to use -verify and
adds a bunch of tests.
2024-11-12 09:46:28 -08:00
Ryosuke Niwa
ef353b02b0
Introduce a new WebKit checker for a unchecked call arguments (#113708) (#114522)
This PR introduces alpha.webkit.UncheckedCallArgsChecker which detects a
function argument which is a raw reference or a raw pointer to a
CheckedPtr capable object.
2024-11-07 08:34:37 -08:00
Donát Nagy
e40a31b7ba
[analyzer][NFC] Remove check::BranchCondition from debug.DumpTraversal (#113906)
This commit removes the `check::BranchCondition` callback of the debug
checker `debug.DumpTraversal` (in `TraversalChecker.cpp`) and the single
broken testcase that was referring to it.

The testcase `traversal-algorithm.mm` was added in 2012 to verify that
we're using DFS traversal -- however it failed to detect that we're no
longer using DFS traversal and in fact it continues to pass even if I
remove large random portions of its code.

This change was motivated by the plan discussed at

https://discourse.llvm.org/t/fixing-or-removing-check-branchcondition/82738

I also added some TODO notes to mark the rest of `TraversalChecker.cpp`
for removal in follow-up commits.
2024-11-07 13:18:55 +01:00
Kazu Hirata
18d2539ce6
[StaticAnalyzer] Simplify code with DenseMap::operator[] (NFC) (#115116) 2024-11-06 08:36:18 -08:00
Chris Cotter
2bbb6c0670
[clang][NFC] Spell out DynTypedNode instead of auto (#114427) 2024-11-06 12:15:11 +01:00
Ryosuke Niwa
847d4eb427
Update clang static analyzers per rename of member functions in CanMakeCheckedPtr. (#114636)
The member functions that define CheckedPtr capable type is
incrementCheckedPtrCount and decrementCheckedPtrCount after the rename.
2024-11-04 22:26:02 -08:00
Ryosuke Niwa
61a6439f35
Introduce a new WebKit checker for a unchecked local variable (#113708)
This PR introduces alpha.webkit.UncheckedLocalVarsChecker which detects
a raw reference or a raw pointer local, static, or global variable to a
CheckedPtr capable object without a guardian variable in an outer scope.
2024-10-31 23:53:07 -07:00
Ella Ma
f4af60dfbb
[analyzer] Fix false double free when including 3rd-party headers with overloaded delete operator as system headers (#85224)
Fixes #62985
Fixes #58820

When 3rd-party header files are included as system headers, their
overloaded `new` and `delete` operators are also considered as the std
ones. However, those overloaded operator functions will also be inlined.
This makes the same
symbolic memory marked as released twice: during `checkPreCall` of the
overloaded `delete` operator and when calling `::operator delete` after
inlining the overloaded operator function (if it has).

This patch attempts to fix this bug by adjusting the strategy of
verifying whether the callee is a standard `new` or `delete` operator in
the `isStandardNewDelete` function.
2024-10-31 17:02:28 +01:00
Ryosuke Niwa
dadfd4a288
Revert "[webkit.UncountedLambdaCapturesChecker] Ignore trivial functions and [[clang::noescape]]." (#114372)
Reverts llvm/llvm-project#113845. Introduced a test failure.
2024-10-31 00:30:18 -07:00
Ryosuke Niwa
287781c7c9
[webkit.UncountedLambdaCapturesChecker] Ignore trivial functions and [[clang::noescape]]. (#113845)
This PR makes webkit.UncountedLambdaCapturesChecker ignore trivial
functions as well as the one being passed to an argument with
[[clang::noescape]] attribute. This dramatically reduces the false
positive rate for this checker.

To do this, this PR replaces VisitLambdaExpr in favor of checking
lambdas via VisitDeclRefExpr and VisitCallExpr. The idea is that if a
lambda is defined but never called or stored somewhere, then capturing
whatever variable in such a lambda is harmless.

VisitCallExpr explicitly looks for direct invocation of lambdas and
registers its DeclRefExpr to be ignored in VisitDeclRefExpr. If a lambda
is being passed to a function, it checks whether its argument is
annotated with [[clang::noescape]]. If it's not annotated such, it
checks captures for their safety.

Because WTF::switchOn could not be annotated with [[clang::noescape]] as
function type parameters are variadic template function so we hard-code
this function into the checker.

Finally, this PR also converts the accompanying test to use -verify and
adds a bunch of tests.
2024-10-31 00:14:24 -07:00
Ryosuke Niwa
b47e2316bf
[alpha.webkit.UncountedLocalVarsChecker] Warn the use of a raw pointer/reference when the guardian variable gets mutated. (#113859)
This checker has a notion of a guardian variable which is a variable and
keeps the object pointed to by a raw pointer / reference in an inner
scope alive long enough to "guard" it from use-after-free. But such a
guardian variable fails to flawed to keep the object alive if it ever
gets mutated within the scope of a raw pointer / reference.

This PR fixes this bug by introducing a new AST visitor class,
GuardianVisitor, which traverses the compound statements of a guarded
variable (raw pointer / reference) and looks for any operator=, move
constructor, or calls to "swap", "leakRef", or "releaseNonNull"
functions.
2024-10-29 23:13:23 -07:00
vabridgers
3d6923dbac
RFC: [clang-tidy] [analyzer] Move nondeterministic pointer usage check to tidy (#110471)
This change moves the `alpha.nondeterministic.PointerSorting` and
`alpha.nondeterministic.PointerIteration` static analyzer checkers to a
single `clang-tidy` check. Those checkers were implemented as simple
`clang-tidy` check-like code, wrapped in the static analyzer framework.
The documentation was updated to describe what the checks can and cannot
do, and testing was completed on a broad set of open-source projects.

Co-authored-by: Vince Bridgers <vince.a.bridgers@ericsson.com>
2024-10-28 03:53:36 -05:00
Ryosuke Niwa
5c20891b2b
[WebKit Checkers] Allow a guardian CheckedPtr/CheckedRef (#110222)
This PR makes WebKit checkers allow a guardian variable which is
CheckedPtr or CheckedRef as in addition to RefPtr or Ref.
2024-10-25 08:52:56 -07:00
Rashmi Mudduluru
a291f00eda
[WebKit Checkers] Make TrivialFunctionAnalysis recognize std::array::operator[] as trivial (#113377)
TFA wasn't recognizing `__libcpp_verbose_abort` as trivial causing `std::array::operator[]` also not being recognized as trivial.
2024-10-24 14:23:29 -07:00
z1nke
684c26c89b
[analyzer] Remove redundant "returned to caller" suffix for compound literal in StackAddressEscape
This patch simplifies the diagnostic message in the core.StackAddrEscape
for stack memory associated with compound literals by removing the
redundant "returned to caller" suffix.
Example: https://godbolt.org/z/KxM67vr7c

```c
// clang --analyze -Xanalyzer -analyzer-checker=core.StackAddressEscape
void* compound_literal() {
  return &(unsigned short){((unsigned short)0x22EF)};
}
```

warning: Address of stack memory associated with a compound literal
declared on line 2 **returned to caller returned to caller**
[core.StackAddressEscape]
2024-10-23 10:46:36 +02:00
Balazs Benics
4995d09355
[analyzer][Solver] Improve getSymVal and friends (1/2) (#112583) 2024-10-18 13:51:20 +02:00
Ryosuke Niwa
71b81e93d2
[alpha.webkit.UncountedLocalVarsChecker] Recursive functions are erroneously treated as non-trivial (#110973)
This PR fixes the bug that alpha.webkit.UncountedLocalVarsChecker
erroneously treats a trivial recursive function as non-trivial. This was
caused by TrivialFunctionAnalysis::isTrivialImpl which takes a statement
as an argument populating the cache with "false" while traversing the
statement to determine its triviality within a recursive function in
TrivialFunctionAnalysisVisitor's WithCachedResult. Because
IsFunctionTrivial honors an entry in the cache, this resulted in the
whole function to be treated as non-trivial.

Thankfully, TrivialFunctionAnalysisVisitor::IsFunctionTrivial already
handles recursive functions correctly so this PR applies the same logic
to TrivialFunctionAnalysisVisitor::WithCachedResult by sharing code
between the two functions. This avoids the cache to be pre-populated
with "false" while traversing statements in a recurisve function.
2024-10-17 16:52:31 -07:00
Balázs Kéri
f74f568b29
[clang][analyzer] PointerSubChecker should not warn on pointers converted to numerical type (#111846)
Pointer values casted to integer (non-pointer) type should be able to be
subtracted as usual.
2024-10-11 11:58:14 +02:00
Ryosuke Niwa
39a91413c3
isUncountedPtr should take QualType as an argument. (#110213)
Make isUncountedPtr take QualType as an argument instead of Type*. This
simplifies some code.
2024-10-10 10:02:07 -07:00
Ryosuke Niwa
820bab8fb5
[alpha.webkit.UncountedCallArgsChecker] Add the support for trivial CXXInheritedCtorInitExpr. (#111198) 2024-10-10 10:01:35 -07:00
Ryosuke Niwa
0fc3e4093c
[alpha.webkit.UncountedCallArgsChecker] Skip std::forward in tryToFindPtrOrigin. (#111222)
Ignore std::forward when it appears while looking for the pointer
origin.
2024-10-10 10:00:42 -07:00
Pavel Skripkin
fba6c887c1
[analyzer] Fix wrong builtin_*_overflow return type (#111253)
`builtin_*_overflow` functions return `_Bool` according to [1].
`BuiltinFunctionChecker` was using `makeTruthVal` w/o specifying
explicit type, which creates an `int` value, since it's the type of any
compassion according to C standard.

Fix it by directly passing `BoolTy` to `makeTruthVal`

Closes: #111147

[1]
https://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins
2024-10-05 17:21:31 +02:00
Pavel Skripkin
a017ed04cc
[analyzer] Model overflow builtins (#102602)
Add basic support for `builtin_*_overflow`  primitives.
 
These helps a lot for checking custom calloc-like functions with
inlinable body. Without such support code like

```c
#include <stddef.h>
#include <stdlib.h>

static void *myMalloc(size_t a1, size_t a2)
{
    size_t res;

    if (__builtin_mul_overflow(a1, a2, &res))
        return NULL;
    return malloc(res);
}

void test(void)
{
    char *ptr = myMalloc(10, 1);
    ptr[20] = 10;
}
````

does not trigger any warnings.
2024-10-03 12:27:25 +02:00
Balázs Kéri
1701895c36
[clang][analyzer] Less redundant warnings from FixedAddressChecker (#110458)
If a fixed value is assigned to a pointer variable, the checker did emit
a warning. If the pointer variable is assigned to another pointer
variable, this resulted in another warning. The checker now emits
warning only if a value with non-pointer type is assigned (to a pointer
variable).
2024-10-03 09:17:51 +02:00