Skip to content

Commit 2413856

Browse files
committed
[WebKit checkers] Treat function pointers with "Singleton" suffix as singleton. (llvm#158012)
1 parent dabe455 commit 2413856

File tree

4 files changed

+36
-2
lines changed

4 files changed

+36
-2
lines changed

clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ bool tryToFindPtrOrigin(
161161
if (Name == "__builtin___CFStringMakeConstantString" ||
162162
Name == "NSClassFromString")
163163
return callback(E, true);
164+
} else if (auto *CalleeE = call->getCallee()) {
165+
if (auto *E = dyn_cast<DeclRefExpr>(CalleeE->IgnoreParenCasts())) {
166+
if (isSingleton(E->getFoundDecl()))
167+
return callback(E, true);
168+
}
164169
}
165170

166171
// Sometimes, canonical type erroneously turns Ref<T> into T.

clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ bool isTrivialBuiltinFunction(const FunctionDecl *F) {
494494
Name.starts_with("os_log") || Name.starts_with("_os_log");
495495
}
496496

497-
bool isSingleton(const FunctionDecl *F) {
497+
bool isSingleton(const NamedDecl *F) {
498498
assert(F);
499499
// FIXME: check # of params == 1
500500
if (auto *MethodDecl = dyn_cast<CXXMethodDecl>(F)) {

clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class CXXMethodDecl;
2121
class CXXRecordDecl;
2222
class Decl;
2323
class FunctionDecl;
24+
class NamedDecl;
2425
class QualType;
2526
class RecordType;
2627
class Stmt;
@@ -156,7 +157,7 @@ bool isPtrConversion(const FunctionDecl *F);
156157
bool isTrivialBuiltinFunction(const FunctionDecl *F);
157158

158159
/// \returns true if \p F is a static singleton function.
159-
bool isSingleton(const FunctionDecl *F);
160+
bool isSingleton(const NamedDecl *F);
160161

161162
/// An inter-procedural analysis facility that detects functions with "trivial"
162163
/// behavior with respect to reference counting, such as simple field getters.

clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,34 @@ void use_const_local() {
437437

438438
} // namespace const_global
439439

440+
namespace var_decl_ref_singleton {
441+
442+
static Class initSomeObject() { return nil; }
443+
static Class (*getSomeObjectClassSingleton)() = initSomeObject;
444+
445+
bool foo(NSString *obj) {
446+
return [obj isKindOfClass:getSomeObjectClassSingleton()];
447+
}
448+
449+
class Bar {
450+
public:
451+
Class someObject();
452+
static Class staticSomeObject();
453+
};
454+
typedef Class (Bar::*SomeObjectSingleton)();
455+
456+
bool bar(NSObject *obj, Bar *bar, SomeObjectSingleton someObjSingleton) {
457+
return [obj isKindOfClass:(bar->*someObjSingleton)()];
458+
// expected-warning@-1{{Call argument for parameter 'aClass' is unretained and unsafe}}
459+
}
460+
461+
bool baz(NSObject *obj) {
462+
Class (*someObjectSingleton)() = Bar::staticSomeObject;
463+
return [obj isKindOfClass:someObjectSingleton()];
464+
}
465+
466+
} // namespace var_decl_ref_singleton
467+
440468
namespace ns_retained_return_value {
441469

442470
NSString *provideNS() NS_RETURNS_RETAINED;

0 commit comments

Comments
 (0)