https://github.com/rniwa updated https://github.com/llvm/llvm-project/pull/200309
>From 7413e02b13e4426a5a80ed93f845531f91a235e6 Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa <[email protected]> Date: Thu, 28 May 2026 17:38:48 -0700 Subject: [PATCH 1/3] [alpha.webkit.UncountedLocalVarsChecker] Check uninitialized raw pointer. Emit a warning for a uninitialized local pointer variable. --- .../StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp | 5 +++++ .../Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp | 4 ++-- .../Analysis/Checkers/WebKit/unchecked-local-vars.cpp | 9 +++++++-- .../Analysis/Checkers/WebKit/uncounted-local-vars.cpp | 9 +++++++-- .../Checkers/WebKit/unretained-local-vars-arc.mm | 4 ++++ 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index f1515701cc6f3..b0e81d7d4ffe6 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -566,6 +566,11 @@ class TrivialFunctionAnalysisVisitor if (Ty->isPointerOrReferenceType()) return true; + // T* is safe even in ARC-enabled Objective-C since [[retain x] autorelease] will not dealloc. + // FIXME: Handle a case when there is a local autorelease pool. + if (Ty->isObjCObjectPointerType()) + return true; + // Fundamental types (integral, nullptr_t, etc...) don't have destructors. if (Ty->isFundamentalType() || Ty->isIntegralOrEnumerationType()) return true; diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp index 56df6742eda9c..97404298a956c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp @@ -244,7 +244,7 @@ class RawPtrRefLocalVarsChecker bool VisitVarDecl(VarDecl *V) override { auto *Init = V->getInit(); - if (Init && V->isLocalVarDecl()) + if (V->isLocalVarDecl()) Checker->visitVarDecl(V, Init, DeclWithIssue); return true; } @@ -329,7 +329,7 @@ class RawPtrRefLocalVarsChecker std::optional<bool> IsUncountedPtr = isUnsafePtr(V->getType()); if (IsUncountedPtr && *IsUncountedPtr) { - if (isPtrOriginSafe(V, Value, DeclWithIssue)) + if (Value && isPtrOriginSafe(V, Value, DeclWithIssue)) return; reportBug(V, Value, nullptr, DeclWithIssue); } diff --git a/clang/test/Analysis/Checkers/WebKit/unchecked-local-vars.cpp b/clang/test/Analysis/Checkers/WebKit/unchecked-local-vars.cpp index 2984f8ba4eefa..f74e5abffea74 100644 --- a/clang/test/Analysis/Checkers/WebKit/unchecked-local-vars.cpp +++ b/clang/test/Analysis/Checkers/WebKit/unchecked-local-vars.cpp @@ -7,11 +7,16 @@ void someFunction(); namespace raw_ptr { void foo() { - CheckedObj *bar; - // FIXME: later on we might warn on uninitialized vars too + CheckedObj *bar; // A local variable in a trivial context is ignored. } void bar(CheckedObj *) {} + +void baz() { + CheckedObj *bar; + // expected-warning@-1{{Local variable 'bar' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} + someFunction(); +} } // namespace raw_ptr namespace reference { diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp index d87e076cb4096..4bf0b3793f85e 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp @@ -7,11 +7,16 @@ void someFunction(); namespace raw_ptr { void foo() { - RefCountable *bar; - // FIXME: later on we might warn on uninitialized vars too + RefCountable *bar; // A local variable in a trivial context is ignored. } void bar(RefCountable *) {} + +void baz() { + RefCountable *bar; + // expected-warning@-1{{Local variable 'bar' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}} + someFunction(); +} } // namespace raw_ptr namespace reference { diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm index 3d256f1599f04..faebdf4235085 100644 --- a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm +++ b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm @@ -17,6 +17,10 @@ void foo2() { [bar doWork]; } +void foo3() { + SomeObj *bar = provide(); +} + void bar() { CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 10); // expected-warning@-1{{Local variable 'array' is unretained and unsafe [alpha.webkit.UnretainedLocalVarsChecker]}} >From 0c2a18ee005c17e1e9c1f210c9fd58588a502e1b Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa <[email protected]> Date: Thu, 28 May 2026 17:44:24 -0700 Subject: [PATCH 2/3] Fix formatting. --- clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index b0e81d7d4ffe6..c0d80128fbaa6 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -566,7 +566,8 @@ class TrivialFunctionAnalysisVisitor if (Ty->isPointerOrReferenceType()) return true; - // T* is safe even in ARC-enabled Objective-C since [[retain x] autorelease] will not dealloc. + // T* is safe even in Objective-C with ARC since [[retain x] autorelease] + // will not dealloc. // FIXME: Handle a case when there is a local autorelease pool. if (Ty->isObjCObjectPointerType()) return true; >From 0761c4ef538a595b39da9d65b41d248b085e5fce Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa <[email protected]> Date: Thu, 28 May 2026 18:52:45 -0700 Subject: [PATCH 3/3] A strong reference in ARC could trigger dealloc. Amend the PR accordingly. --- .../Checkers/WebKit/PtrTypesSemantics.cpp | 10 ++++++---- .../Checkers/WebKit/unretained-local-vars-arc.mm | 8 +++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index c0d80128fbaa6..2ca34ff0587e1 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -566,11 +566,13 @@ class TrivialFunctionAnalysisVisitor if (Ty->isPointerOrReferenceType()) return true; - // T* is safe even in Objective-C with ARC since [[retain x] autorelease] - // will not dealloc. // FIXME: Handle a case when there is a local autorelease pool. - if (Ty->isObjCObjectPointerType()) - return true; + if (Ty->isObjCObjectPointerType()) { + auto Type = Ty.isDestructedType(); + if (Type == QualType::DK_objc_weak_lifetime || Type == QualType::DK_none) + return true; + // strong lifetime in ARC could dealloc an object. + } // Fundamental types (integral, nullptr_t, etc...) don't have destructors. if (Ty->isFundamentalType() || Ty->isIntegralOrEnumerationType()) diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm index faebdf4235085..dbdd941007e5c 100644 --- a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm +++ b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UnretainedLocalVarsChecker -fobjc-arc -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UnretainedLocalVarsChecker -fobjc-runtime-has-weak -fobjc-weak -fobjc-arc -verify %s #import "objc-mock-types.h" @@ -19,6 +19,12 @@ void foo2() { void foo3() { SomeObj *bar = provide(); + IOSurfaceRef surface; + // expected-warning@-1{{Local variable 'surface' is unretained and unsafe [alpha.webkit.UnretainedLocalVarsChecker]}} +} + +void foo4() { + __weak SomeObj *bar = provide(); } void bar() { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
