aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-07-25 20:28:02 +0000
committerTed Kremenek <kremenek@apple.com>2008-07-25 20:28:02 +0000
commit694eefb7452dd650bae16e1026571ab5a43a74fc (patch)
tree87db54ac98ead647053aaeb0667ae3f46c8479b9
parentabfaf9984eee3d076ded8770bf9fce156f10c185 (diff)
Have the UnusedIvar check skip ivars with setters/getters created by @synthesize.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54050 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/CheckObjCUnusedIVars.cpp30
1 files changed, 26 insertions, 4 deletions
diff --git a/lib/Analysis/CheckObjCUnusedIVars.cpp b/lib/Analysis/CheckObjCUnusedIVars.cpp
index d536ea4bdb..45630c63bb 100644
--- a/lib/Analysis/CheckObjCUnusedIVars.cpp
+++ b/lib/Analysis/CheckObjCUnusedIVars.cpp
@@ -35,10 +35,24 @@ static void Scan(IvarUsageMap& M, Stmt* S) {
ObjCIvarDecl* D = Ex->getDecl();
IvarUsageMap::iterator I = M.find(D);
if (I != M.end()) I->second = Used;
+ return;
}
- else
- for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E;++I)
- Scan(M, *I);
+
+ for (Stmt::child_iterator I=S->child_begin(), E=S->child_end(); I!=E;++I)
+ Scan(M, *I);
+}
+
+static void Scan(IvarUsageMap& M, ObjCPropertyImplDecl* D) {
+ if (!D)
+ return;
+
+ ObjCIvarDecl* ID = D->getPropertyIvarDecl();
+
+ if (!ID)
+ return;
+
+ IvarUsageMap::iterator I = M.find(ID);
+ if (I != M.end()) I->second = Used;
}
void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {
@@ -73,13 +87,21 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {
E = D->instmeth_end(); I!=E; ++I)
Scan(M, (*I)->getBody());
+ // Scan for @synthesized property methods that act as setters/getters
+ // to an ivar.
+ for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
+ E = D->propimpl_end(); I!=E; ++I)
+ Scan(M, *I);
+
// Find ivars that are unused.
for (IvarUsageMap::iterator I = M.begin(), E = M.end(); I!=E; ++I)
if (I->second == Unused) {
std::ostringstream os;
os << "Instance variable '" << I->first->getName()
- << "' in class '" << ID->getName() << "' is never used.";
+ << "' in class '" << ID->getName()
+ << "' is never used by the methods in its @implementation "
+ "(although it may be used by category methods).";
BR.EmitBasicReport("unused ivar",
os.str().c_str(), I->first->getLocation());