File tree Expand file tree Collapse file tree 4 files changed +36
-2
lines changed
lib/StaticAnalyzer/Checkers/WebKit
test/Analysis/Checkers/WebKit Expand file tree Collapse file tree 4 files changed +36
-2
lines changed Original file line number Diff line number Diff line change @@ -160,6 +160,11 @@ bool tryToFindPtrOrigin(
160
160
if (Name == " __builtin___CFStringMakeConstantString" ||
161
161
Name == " NSClassFromString" )
162
162
return callback (E, true );
163
+ } else if (auto *CalleeE = call->getCallee ()) {
164
+ if (auto *E = dyn_cast<DeclRefExpr>(CalleeE->IgnoreParenCasts ())) {
165
+ if (isSingleton (E->getFoundDecl ()))
166
+ return callback (E, true );
167
+ }
163
168
}
164
169
165
170
// Sometimes, canonical type erroneously turns Ref<T> into T.
Original file line number Diff line number Diff line change @@ -479,7 +479,7 @@ bool isTrivialBuiltinFunction(const FunctionDecl *F) {
479
479
Name.starts_with (" os_log" ) || Name.starts_with (" _os_log" );
480
480
}
481
481
482
- bool isSingleton (const FunctionDecl *F) {
482
+ bool isSingleton (const NamedDecl *F) {
483
483
assert (F);
484
484
// FIXME: check # of params == 1
485
485
if (auto *MethodDecl = dyn_cast<CXXMethodDecl>(F)) {
Original file line number Diff line number Diff line change @@ -21,6 +21,7 @@ class CXXMethodDecl;
21
21
class CXXRecordDecl ;
22
22
class Decl ;
23
23
class FunctionDecl ;
24
+ class NamedDecl ;
24
25
class QualType ;
25
26
class RecordType ;
26
27
class Stmt ;
@@ -156,7 +157,7 @@ bool isPtrConversion(const FunctionDecl *F);
156
157
bool isTrivialBuiltinFunction (const FunctionDecl *F);
157
158
158
159
// / \returns true if \p F is a static singleton function.
159
- bool isSingleton (const FunctionDecl *F);
160
+ bool isSingleton (const NamedDecl *F);
160
161
161
162
// / An inter-procedural analysis facility that detects functions with "trivial"
162
163
// / behavior with respect to reference counting, such as simple field getters.
Original file line number Diff line number Diff line change @@ -438,6 +438,34 @@ void use_const_local() {
438
438
439
439
} // namespace const_global
440
440
441
+ namespace var_decl_ref_singleton {
442
+
443
+ static Class initSomeObject () { return nil ; }
444
+ static Class (*getSomeObjectClassSingleton)() = initSomeObject;
445
+
446
+ bool foo (NSString *obj) {
447
+ return [obj isKindOfClass: getSomeObjectClassSingleton ()];
448
+ }
449
+
450
+ class Bar {
451
+ public:
452
+ Class someObject ();
453
+ static Class staticSomeObject ();
454
+ };
455
+ typedef Class (Bar::*SomeObjectSingleton)();
456
+
457
+ bool bar (NSObject *obj, Bar *bar, SomeObjectSingleton someObjSingleton) {
458
+ return [obj isKindOfClass: (bar->*someObjSingleton)()];
459
+ // expected-warning@-1{{Call argument for parameter 'aClass' is unretained and unsafe}}
460
+ }
461
+
462
+ bool baz (NSObject *obj) {
463
+ Class (*someObjectSingleton)() = Bar::staticSomeObject;
464
+ return [obj isKindOfClass: someObjectSingleton ()];
465
+ }
466
+
467
+ } // namespace var_decl_ref_singleton
468
+
441
469
namespace ns_retained_return_value {
442
470
443
471
NSString *provideNS () NS_RETURNS_RETAINED;
You can’t perform that action at this time.
0 commit comments