diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-06-15 09:49:05 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-06-15 11:36:05 +0200 |
commit | 2c83c40b4358330f7360b66b8506997ffd80bcde (patch) | |
tree | a68a0be99013f51f892e36924f9e65acfa266143 /compilerplugins | |
parent | 416752b9e4bc4605c479d3eff7797be9f0ef2a38 (diff) |
improve unusedfields loplugin
to ignore assignments when doing writeonly analysis
Change-Id: I9eb6f2594003a610582dbc20acb7ccf14ef72c6c
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/constparams.cxx | 3 | ||||
-rw-r--r-- | compilerplugins/clang/unusedfields.cxx | 41 |
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; } |