diff --git a/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp b/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp index 633648ec6c22f1ee3e310641f1698922d52c932f..7f64f8e2c40acca623d802379c49750d660cd08a 100644 --- a/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp @@ -357,8 +357,15 @@ void IdempotentOperationChecker::PostVisitBinaryOperator( const BinaryOperator *B) { // Add the ExplodedNode we just visited BinaryOperatorData &Data = hash[B]; - assert(isa<BinaryOperator>(cast<StmtPoint>(C.getPredecessor() - ->getLocation()).getStmt())); + + const Stmt *predStmt + = cast<StmtPoint>(C.getPredecessor()->getLocation()).getStmt(); + + // Ignore implicit calls to setters. + if (isa<ObjCPropertyRefExpr>(predStmt)) + return; + + assert(isa<BinaryOperator>(predStmt)); Data.explodedNodes.Add(C.getPredecessor()); } diff --git a/test/Analysis/idempotent-operations.m b/test/Analysis/idempotent-operations.m index 3f68206b168fc6ff4abf3cadcf1e1a66691e1408..bda98fa7171344f1676c5cc4f13d331eebd75132 100644 --- a/test/Analysis/idempotent-operations.m +++ b/test/Analysis/idempotent-operations.m @@ -4,10 +4,12 @@ typedef signed char BOOL; typedef unsigned long NSUInteger; typedef struct _NSZone NSZone; @protocol NSObject - (BOOL)isEqual:(id)object; -@end @interface NSObject <NSObject> { -} @end +@interface NSObject {} + @property int locked; + @property(nonatomic, readonly) NSObject *media; +@end // <rdar://problem/8725041> - Don't flag idempotent operation warnings when // a method may invalidate an instance variable. @@ -32,3 +34,9 @@ typedef struct _NSZone NSZone; } @end +// Test that the idempotent operations checker works in the prescence +// of property expressions. +void pr9116(NSObject *placeholder) { + int x = placeholder.media.locked = placeholder ? 1 : 0; +} +