summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2017-06-19 14:16:05 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2017-06-20 10:01:48 +0200
commit9d9d024ffba8753db8a93e34d34e22818da002aa (patch)
treed463f8994286a98a238435270acbe50891194c0b /compilerplugins
parent05f67637fc4f71750dda46fccf0bed5b3fd99233 (diff)
loplugin:unusedfields fix some more false positives
in the write-only analysis Change-Id: Ic570416e855b8ec38d54f6f6f1adef4819ea53ee
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/test/unusedfields.cxx17
-rw-r--r--compilerplugins/clang/unusedfields.cxx18
2 files changed, 33 insertions, 2 deletions
diff --git a/compilerplugins/clang/test/unusedfields.cxx b/compilerplugins/clang/test/unusedfields.cxx
index f549a9a37673..d24e6551c660 100644
--- a/compilerplugins/clang/test/unusedfields.cxx
+++ b/compilerplugins/clang/test/unusedfields.cxx
@@ -17,12 +17,27 @@ struct Foo
struct Bar
// expected-error@-1 {{read m_bar2 [loplugin:unusedfields]}}
+// expected-error@-2 {{read m_bar3 [loplugin:unusedfields]}}
+// expected-error@-3 {{read m_bar4 [loplugin:unusedfields]}}
+// expected-error@-4 {{read m_functionpointer [loplugin:unusedfields]}}
{
int m_bar1;
int m_bar2 = 1;
+ int* m_bar3;
+ int m_bar4;
+ void (*m_functionpointer)(int&);
+ //check that we see reads of fields when referred to via constructor initializer
Bar(Foo const & foo) : m_bar1(foo.m_foo1) {}
- int bar() { return m_bar2; }
+ int bar1() { return m_bar2; }
+
+ // check that we see reads of fields when operated on via pointer de-ref
+ void bar2() { *m_bar3 = 2; }
+
+ // check that we see reads of field when passed to a function pointer
+ // check that we see read of a field that is a function pointer
+ void bar3() { m_functionpointer(m_bar4); }
+
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/compilerplugins/clang/unusedfields.cxx b/compilerplugins/clang/unusedfields.cxx
index df64c987f347..824efa5c41f7 100644
--- a/compilerplugins/clang/unusedfields.cxx
+++ b/compilerplugins/clang/unusedfields.cxx
@@ -261,12 +261,28 @@ bool UnusedFields::VisitMemberExpr( const MemberExpr* memberExpr )
break;
}
if (isa<CastExpr>(parent) || isa<MemberExpr>(parent) || isa<ParenExpr>(parent) || isa<ParenListExpr>(parent)
- || isa<ExprWithCleanups>(parent) || isa<UnaryOperator>(parent))
+ || isa<ExprWithCleanups>(parent))
{
child = parent;
auto parentsRange = compiler.getASTContext().getParents(*parent);
parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>();
}
+ else if (auto unaryOperator = dyn_cast<UnaryOperator>(parent))
+ {
+ UnaryOperator::Opcode op = unaryOperator->getOpcode();
+ if (op == UO_AddrOf || op == UO_Deref
+ || op == UO_Plus || op == UO_Minus
+ || op == UO_Not || op == UO_LNot
+ || op == UO_PreInc || op == UO_PostInc
+ || op == UO_PreDec || op == UO_PostDec)
+ {
+ bPotentiallyReadFrom = true;
+ break;
+ }
+ child = parent;
+ auto parentsRange = compiler.getASTContext().getParents(*parent);
+ parent = parentsRange.begin() == parentsRange.end() ? nullptr : parentsRange.begin()->get<Stmt>();
+ }
else if (isa<CaseStmt>(parent))
{
bPotentiallyReadFrom = dyn_cast<CaseStmt>(parent)->getLHS() == child