summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2017-06-15 09:49:05 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2017-06-15 11:36:05 +0200
commit2c83c40b4358330f7360b66b8506997ffd80bcde (patch)
treea68a0be99013f51f892e36924f9e65acfa266143 /compilerplugins
parent416752b9e4bc4605c479d3eff7797be9f0ef2a38 (diff)
improve unusedfields loplugin
to ignore assignments when doing writeonly analysis Change-Id: I9eb6f2594003a610582dbc20acb7ccf14ef72c6c
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/constparams.cxx3
-rw-r--r--compilerplugins/clang/unusedfields.cxx41
2 files changed, 34 insertions, 10 deletions
diff --git a/compilerplugins/clang/constparams.cxx b/compilerplugins/clang/constparams.cxx
index ad5549d02263..95325c57d1a7 100644
--- a/compilerplugins/clang/constparams.cxx
+++ b/compilerplugins/clang/constparams.cxx
@@ -194,8 +194,7 @@ bool ConstParams::checkIfCanBeConst(const Stmt* stmt)
return checkIfCanBeConst(parent);
}
return true;
- } else if (isa<BinaryOperator>(parent)) {
- const BinaryOperator* binaryOp = dyn_cast<BinaryOperator>(parent);
+ } else if (auto binaryOp = dyn_cast<BinaryOperator>(parent)) {
BinaryOperator::Opcode op = binaryOp->getOpcode();
// TODO could do better, but would require tracking the LHS
if (binaryOp->getRHS() == stmt && op == BO_Assign) {
diff --git a/compilerplugins/clang/unusedfields.cxx b/compilerplugins/clang/unusedfields.cxx
index 2d87cab22708..e77af78870ab 100644
--- a/compilerplugins/clang/unusedfields.cxx
+++ b/compilerplugins/clang/unusedfields.cxx
@@ -271,11 +271,30 @@ bool UnusedFields::VisitMemberExpr( const MemberExpr* memberExpr )
bPotentiallyReadFrom = true;
break;
}
- else if (isa<ReturnStmt>(parent) || isa<CXXConstructExpr>(parent)
- || isa<ConditionalOperator>(parent) || isa<SwitchStmt>(parent) || isa<ArraySubscriptExpr>(parent)
- || isa<DeclStmt>(parent) || isa<WhileStmt>(parent) || isa<CXXNewExpr>(parent)
- || isa<ForStmt>(parent) || isa<InitListExpr>(parent)
- || isa<BinaryOperator>(parent) || isa<CXXDependentScopeMemberExpr>(parent)
+ else if (auto binaryOp = dyn_cast<BinaryOperator>(parent))
+ {
+ BinaryOperator::Opcode op = binaryOp->getOpcode();
+ // If the child is on the LHS and it is an assignment, we are obviously not reading from it,
+ // so walk up the tree.
+ if (binaryOp->getLHS() == child && op == BO_Assign) {
+ child = parent;
+ parent = parentStmt(parent);
+ } else {
+ bPotentiallyReadFrom = true;
+ break;
+ }
+ }
+ else if (isa<ReturnStmt>(parent)
+ || isa<CXXConstructExpr>(parent)
+ || isa<ConditionalOperator>(parent)
+ || isa<SwitchStmt>(parent)
+ || isa<ArraySubscriptExpr>(parent)
+ || isa<DeclStmt>(parent)
+ || isa<WhileStmt>(parent)
+ || isa<CXXNewExpr>(parent)
+ || isa<ForStmt>(parent)
+ || isa<InitListExpr>(parent)
+ || isa<CXXDependentScopeMemberExpr>(parent)
|| isa<UnresolvedMemberExpr>(parent)
|| isa<MaterializeTemporaryExpr>(parent)) //???
{
@@ -283,9 +302,13 @@ bool UnusedFields::VisitMemberExpr( const MemberExpr* memberExpr )
break;
}
else if (isa<CXXDeleteExpr>(parent)
- || isa<UnaryExprOrTypeTraitExpr>(parent)
- || isa<CXXUnresolvedConstructExpr>(parent) || isa<CompoundStmt>(parent)
- || isa<CXXTypeidExpr>(parent) || isa<DefaultStmt>(parent))
+ || isa<UnaryExprOrTypeTraitExpr>(parent)
+ || isa<CXXUnresolvedConstructExpr>(parent)
+ || isa<CompoundStmt>(parent)
+ || isa<LabelStmt>(parent)
+ || isa<CXXForRangeStmt>(parent)
+ || isa<CXXTypeidExpr>(parent)
+ || isa<DefaultStmt>(parent))
{
break;
}
@@ -305,7 +328,9 @@ bool UnusedFields::VisitMemberExpr( const MemberExpr* memberExpr )
parent->dump();
}
if (bPotentiallyReadFrom)
+ {
readFromSet.insert(fieldInfo);
+ }
return true;
}