diff options
| author | Devin Coughlin <dcoughlin@apple.com> | 2016-03-03 21:38:39 +0000 |
|---|---|---|
| committer | Devin Coughlin <dcoughlin@apple.com> | 2016-03-03 21:38:39 +0000 |
| commit | 578a20a82eaf029aa9c480bfa7bf43878313cfd4 (patch) | |
| tree | 6dd39c4a979284750737052c8612c85644d488de | |
| parent | c1a7c97c1b5f62f918faee0ccf190c53ad519de1 (diff) | |
| download | bcm5719-llvm-578a20a82eaf029aa9c480bfa7bf43878313cfd4.tar.gz bcm5719-llvm-578a20a82eaf029aa9c480bfa7bf43878313cfd4.zip | |
[analyzer] ObjCDeallocChecker: Only check for nil-out when type is retainable.
This fixes a crash when setting a property of struct type in -dealloc.
llvm-svn: 262659
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp | 6 | ||||
| -rw-r--r-- | clang/test/Analysis/DeallocMissingRelease.m | 19 |
2 files changed, 24 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp index c09924cfc2e..f9fd9fcf957 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp @@ -860,9 +860,13 @@ ObjCDeallocChecker::getValueReleasedByNillingOut(const ObjCMethodCall &M, if (!ReceiverVal.isValid()) return nullptr; - // Is the first argument nil? if (M.getNumArgs() == 0) return nullptr; + + if (!M.getArgExpr(0)->getType()->isObjCRetainableType()) + return nullptr; + + // Is the first argument nil? SVal Arg = M.getArgSVal(0); ProgramStateRef notNilState, nilState; std::tie(notNilState, nilState) = diff --git a/clang/test/Analysis/DeallocMissingRelease.m b/clang/test/Analysis/DeallocMissingRelease.m index 383bacb539f..75afd0e5f1b 100644 --- a/clang/test/Analysis/DeallocMissingRelease.m +++ b/clang/test/Analysis/DeallocMissingRelease.m @@ -664,6 +664,25 @@ void ReleaseMe(id arg); @end #endif +struct SomeStruct { + int f; +}; +@interface ZeroOutStructWithSetter : NSObject + @property(assign) struct SomeStruct s; +@end + +@implementation ZeroOutStructWithSetter +- (void)dealloc { + struct SomeStruct zeroedS; + zeroedS.f = 0; + + self.s = zeroedS; +#if NON_ARC + [super dealloc]; +#endif +} +@end + #if NON_ARC @interface ReleaseIvarInArray : NSObject { NSObject *_array[3]; |

