diff options
-rw-r--r-- | lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp | 20 | ||||
-rw-r--r-- | test/Analysis/objc_invalidation.m | 22 |
2 files changed, 35 insertions, 7 deletions
diff --git a/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp b/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp index fd763d46f9..80cb58d76b 100644 --- a/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp @@ -576,15 +576,23 @@ void IvarInvalidationChecker::MethodCrawler::VisitBinaryOperator( const BinaryOperator *BO) { VisitStmt(BO); - if (BO->getOpcode() != BO_Assign) + // Do we assign/compare against zero? If yes, check the variable we are + // assigning to. + BinaryOperatorKind Opcode = BO->getOpcode(); + if (Opcode != BO_Assign && + Opcode != BO_EQ && + Opcode != BO_NE) return; - // Do we assign zero? - if (!isZero(BO->getRHS())) - return; + if (isZero(BO->getRHS())) { + check(BO->getLHS()); + return; + } - // Check the variable we are assigning to. - check(BO->getLHS()); + if (Opcode != BO_Assign && isZero(BO->getLHS())) { + check(BO->getRHS()); + return; + } } void IvarInvalidationChecker::MethodCrawler::VisitObjCMessageExpr( diff --git a/test/Analysis/objc_invalidation.m b/test/Analysis/objc_invalidation.m index 8e9cd488a8..f21bfdf474 100644 --- a/test/Analysis/objc_invalidation.m +++ b/test/Analysis/objc_invalidation.m @@ -1,4 +1,10 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.osx.cocoa.InstanceVariableInvalidation -fobjc-default-synthesize-properties -verify %s +extern void __assert_fail (__const char *__assertion, __const char *__file, + unsigned int __line, __const char *__function) + __attribute__ ((__noreturn__)); + +#define assert(expr) \ + ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__)) @protocol NSObject @end @@ -168,10 +174,24 @@ extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, @interface Child: Parent <Invalidation2, IDEBuildable> @end -@implementation Parent +@implementation Parent{ + @private + Invalidation2Class *Ivar10; + Invalidation2Class *Ivar11; + Invalidation2Class *Ivar12; +} + @synthesize ObjB = _ObjB; - (void)invalidate{ _ObjB = ((void*)0); + + assert(Ivar10 == 0); + + if (__builtin_expect(!(Ivar11 == ((void*)0)), 0)) + assert(0); + + assert(0 == Ivar12); + } @end |