aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-02-12 01:01:31 +0000
committerTed Kremenek <kremenek@apple.com>2011-02-12 01:01:31 +0000
commit148849a74781ed16c6e6f30366f9aaf1f67b1cb1 (patch)
treed0d40b7db1bde6d8d8b6e4b1c1dee38ffbab9d71
parentf4e532b5a1683a9f6c842f361c7415bf3474315f (diff)
static analyzer: Also invalidate instance variables of a receiver in a message expression, just as we do with parameters.
Fixes <rdar://problem/8725041>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125422 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Core/CFRefCount.cpp12
-rw-r--r--test/Analysis/idempotent-operations.m34
2 files changed, 46 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Core/CFRefCount.cpp b/lib/StaticAnalyzer/Core/CFRefCount.cpp
index 09e69239d6..92bd4116a7 100644
--- a/lib/StaticAnalyzer/Core/CFRefCount.cpp
+++ b/lib/StaticAnalyzer/Core/CFRefCount.cpp
@@ -2514,6 +2514,18 @@ void CFRefCount::evalSummary(ExplodedNodeSet& Dst,
// done an invalidation pass.
llvm::DenseSet<SymbolRef> WhitelistedSymbols;
+ // Invalidate all instance variables of the receiver of a message.
+ // FIXME: We should be able to do better with inter-procedural analysis.
+ if (Receiver) {
+ SVal V = Receiver.getSValAsScalarOrLoc(state);
+ if (SymbolRef Sym = V.getAsLocSymbol()) {
+ if (state->get<RefBindings>(Sym))
+ WhitelistedSymbols.insert(Sym);
+ }
+ if (const MemRegion *region = V.getAsRegion())
+ RegionsToInvalidate.push_back(region);
+ }
+
for (unsigned idx = 0, e = callOrMsg.getNumArgs(); idx != e; ++idx) {
SVal V = callOrMsg.getArgSValAsScalarOrLoc(idx);
SymbolRef Sym = V.getAsLocSymbol();
diff --git a/test/Analysis/idempotent-operations.m b/test/Analysis/idempotent-operations.m
new file mode 100644
index 0000000000..3f68206b16
--- /dev/null
+++ b/test/Analysis/idempotent-operations.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-check-objc-mem -analyzer-check-idempotent-operations -verify %s
+
+typedef signed char BOOL;
+typedef unsigned long NSUInteger;
+typedef struct _NSZone NSZone;
+@protocol NSObject - (BOOL)isEqual:(id)object;
+@end @interface NSObject <NSObject> {
+}
+@end
+
+
+// <rdar://problem/8725041> - Don't flag idempotent operation warnings when
+// a method may invalidate an instance variable.
+@interface Rdar8725041 : NSObject {
+ id _attribute;
+}
+ - (void) method2;
+@end
+
+@implementation Rdar8725041
+- (BOOL) method1 {
+ BOOL needsUpdate = (BOOL)0;
+ id oldAttribute = _attribute;
+ [self method2];
+ needsUpdate |= (_attribute != oldAttribute); // no-warning
+ return needsUpdate;
+}
+
+- (void) method2
+{
+ _attribute = ((void*)0);
+}
+@end
+