[analyzer] Allow IvarInvalidation checker to suppress warnings via

assertions.

To ensure that custom assertions/conditional would also be supported,
just check if the ivar that needs to be invalidated or set to nil is
compared against 0.

Unfortunately, this will not work for code containing 'assert(IvarName)'

llvm-svn: 172147
This commit is contained in:
Anna Zaks 2013-01-10 23:34:16 +00:00
parent 930f73a0dd
commit a96a9ef716
2 changed files with 35 additions and 7 deletions

View File

@ -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(

View File

@ -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