diff options
author | George Karpenkov <ekarpenkov@apple.com> | 2019-02-01 02:13:02 +0000 |
---|---|---|
committer | George Karpenkov <ekarpenkov@apple.com> | 2019-02-01 02:13:02 +0000 |
commit | b6c6ab312e9ffa0f1144e3fccc2d25e3afef0e31 (patch) | |
tree | 15793ede65976a23f400cd37de50880dc4d76d9a | |
parent | 6fa43f8b9c5e86636a4e8b1948309b6b6036ca34 (diff) | |
download | bcm5719-llvm-b6c6ab312e9ffa0f1144e3fccc2d25e3afef0e31.tar.gz bcm5719-llvm-b6c6ab312e9ffa0f1144e3fccc2d25e3afef0e31.zip |
[analyzer] [RetainCountChecker] Fix object type for CF/Obj-C bridged casts
Having an incorrect type for a cast causes the checker to incorrectly
dismiss the operation under ARC, leading to a false positive
use-after-release on the test.
rdar://47709885
Differential Revision: https://reviews.llvm.org/D57557
llvm-svn: 352824
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp | 11 | ||||
-rw-r--r-- | clang/test/Analysis/objc-arc.m | 15 |
2 files changed, 24 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp index 2fe0d286bb3..9d2d8cd82aa 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp @@ -185,7 +185,16 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE, if (!BE) return; - ArgEffect AE = ArgEffect(IncRef, ObjKind::ObjC); + QualType QT = CE->getType(); + ObjKind K; + if (coreFoundation::isCFObjectRef(QT)) { + K = ObjKind::CF; + } else { + assert(cocoa::isCocoaObjectRef(QT)); + K = ObjKind::ObjC; + } + + ArgEffect AE = ArgEffect(IncRef, K); switch (BE->getBridgeKind()) { case OBC_Bridge: diff --git a/clang/test/Analysis/objc-arc.m b/clang/test/Analysis/objc-arc.m index 08fca7659cd..c5549fae846 100644 --- a/clang/test/Analysis/objc-arc.m +++ b/clang/test/Analysis/objc-arc.m @@ -123,7 +123,7 @@ void rdar9424882() { typedef const void *CFTypeRef; typedef const struct __CFString *CFStringRef; -@interface NSString +@interface NSString : NSObject - (id) self; @end @@ -231,3 +231,16 @@ id rdar14061675() { return result; } +typedef const void * CFTypeRef; +typedef const struct __CFString * CFStringRef; +typedef const struct __CFAllocator * CFAllocatorRef; +extern const CFAllocatorRef kCFAllocatorDefault; + +extern CFTypeRef CFRetain(CFTypeRef cf); +extern void CFRelease(CFTypeRef cf); + +void check_bridge_retained_cast() { + NSString *nsStr = [[NSString alloc] init]; + CFStringRef cfStr = (__bridge_retained CFStringRef)nsStr; + CFRelease(cfStr); // no-warning +} |