Author: Ryosuke Niwa Date: 2024-09-11T12:06:04-07:00 New Revision: b06954a5d02a41a38b72f7914c791428ccd95318
URL: https://github.com/llvm/llvm-project/commit/b06954a5d02a41a38b72f7914c791428ccd95318 DIFF: https://github.com/llvm/llvm-project/commit/b06954a5d02a41a38b72f7914c791428ccd95318.diff LOG: [alpha.webkit.UncountedCallArgsChecker] Allow protector functions in Objective-C++ (#108184) This PR fixes the bug that WebKit checkers didn't recognize the return value of an Objective-C++ selector which returns Ref or RefPtr to be safe. Added: clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.mm Modified: clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp Removed: ################################################################################ diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index 42efc0c43766e9..f48b2fd9dca71b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -143,6 +143,16 @@ bool isReturnValueRefCounted(const clang::FunctionDecl *F) { return false; } +std::optional<bool> isUncounted(const QualType T) { + if (auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T)) { + if (auto *Decl = Subst->getAssociatedDecl()) { + if (isRefType(safeGetName(Decl))) + return false; + } + } + return isUncounted(T->getAsCXXRecordDecl()); +} + std::optional<bool> isUncounted(const CXXRecordDecl* Class) { // Keep isRefCounted first as it's cheaper. diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h index ec1db1cc335807..2932e62ad06e4b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h @@ -20,6 +20,7 @@ class CXXMethodDecl; class CXXRecordDecl; class Decl; class FunctionDecl; +class QualType; class Stmt; class Type; @@ -42,6 +43,10 @@ std::optional<bool> isRefCountable(const clang::CXXRecordDecl* Class); /// \returns true if \p Class is ref-counted, false if not. bool isRefCounted(const clang::CXXRecordDecl *Class); +/// \returns true if \p Class is ref-countable AND not ref-counted, false if +/// not, std::nullopt if inconclusive. +std::optional<bool> isUncounted(const clang::QualType T); + /// \returns true if \p Class is ref-countable AND not ref-counted, false if /// not, std::nullopt if inconclusive. std::optional<bool> isUncounted(const clang::CXXRecordDecl* Class); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp index 704c082a4d1d63..81c2434ce64775 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp @@ -87,8 +87,7 @@ class UncountedCallArgsChecker } auto *E = MemberCallExpr->getImplicitObjectArgument(); QualType ArgType = MemberCallExpr->getObjectType(); - std::optional<bool> IsUncounted = - isUncounted(ArgType->getAsCXXRecordDecl()); + std::optional<bool> IsUncounted = isUncounted(ArgType); if (IsUncounted && *IsUncounted && !isPtrOriginSafe(E)) reportBugOnThis(E); } diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.mm b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.mm new file mode 100644 index 00000000000000..db0c5b19eec5bb --- /dev/null +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.mm @@ -0,0 +1,26 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s +// expected-no-diagnostics + +#import "mock-types.h" +#import "mock-system-header.h" +#import "../../Inputs/system-header-simulator-for-objc-dealloc.h" + +@interface Foo : NSObject + +@property (nonatomic, readonly) RefPtr<RefCountable> countable; + +- (void)execute; +- (RefPtr<RefCountable>)_protectedRefCountable; +@end + +@implementation Foo + +- (void)execute { + self._protectedRefCountable->method(); +} + +- (RefPtr<RefCountable>)_protectedRefCountable { + return _countable; +} + +@end _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits