diff options
author | Jordan Rose <jordan_rose@apple.com> | 2014-01-10 20:06:06 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2014-01-10 20:06:06 +0000 |
commit | 1a866cd54b5c4b63d3be6f76ba6585bd262b99b7 (patch) | |
tree | 50157164678f435ae9993157e954e57773865451 /clang/lib/StaticAnalyzer/Core/CallEvent.cpp | |
parent | 26cb6d90b8dd184dbbe6ace171320871aac5f94b (diff) | |
download | bcm5719-llvm-1a866cd54b5c4b63d3be6f76ba6585bd262b99b7.tar.gz bcm5719-llvm-1a866cd54b5c4b63d3be6f76ba6585bd262b99b7.zip |
[analyzer] Model getters of known-@synthesized Objective-C properties.
...by synthesizing their body to be "return self->_prop;", with an extra
nudge to RetainCountChecker to still treat the value as +0 if we have no
other information.
This doesn't handle weak properties, but that's mostly correct anyway,
since they can go to nil at any time. This also doesn't apply to properties
whose implementations we can't see, since they may not be backed by an
ivar at all. And finally, this doesn't handle properties of C++ class type,
because we can't invoke the copy constructor. (Sema has actually done this
work already, but the AST it synthesizes is one the analyzer doesn't quite
handle -- it has an rvalue DeclRefExpr.)
Modeling setters is likely to be more difficult (since it requires
handling strong/copy), but not impossible.
<rdar://problem/11956898>
llvm-svn: 198953
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/CallEvent.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/CallEvent.cpp | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index 838d273cc0a..71895051e2c 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -863,9 +863,17 @@ RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const { Optional<const ObjCMethodDecl *> &Val = PMC[std::make_pair(IDecl, Sel)]; // Query lookupPrivateMethod() if the cache does not hit. - if (!Val.hasValue()) + if (!Val.hasValue()) { Val = IDecl->lookupPrivateMethod(Sel); + // If the method is a property accessor, we should try to "inline" it + // even if we don't actually have an implementation. + if (!*Val) + if (const ObjCMethodDecl *CompileTimeMD = E->getMethodDecl()) + if (CompileTimeMD->isPropertyAccessor()) + Val = IDecl->lookupInstanceMethod(Sel); + } + const ObjCMethodDecl *MD = Val.getValue(); if (CanBeSubClassed) return RuntimeDefinition(MD, Receiver); |