diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-11-22 09:33:32 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-11-23 06:59:31 +0100 |
commit | 7a1c21e53fc4733a4bb52282ce0098fcc085ab0e (patch) | |
tree | c1b90f74e1ce9e9f3a852f398890899459189cab /compilerplugins/clang/simplifybool.cxx | |
parent | c24c32bf71b8e64bd0d36e511f554e1f6c015842 (diff) |
loplugin:simplifybool for negation of comparison operator
Change-Id: Ie56daf560185274754afbc7a09c432b5c2793791
Reviewed-on: https://gerrit.libreoffice.org/45068
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins/clang/simplifybool.cxx')
-rw-r--r-- | compilerplugins/clang/simplifybool.cxx | 52 |
1 files changed, 35 insertions, 17 deletions
diff --git a/compilerplugins/clang/simplifybool.cxx b/compilerplugins/clang/simplifybool.cxx index cf5570b60008..091591f30988 100644 --- a/compilerplugins/clang/simplifybool.cxx +++ b/compilerplugins/clang/simplifybool.cxx @@ -87,25 +87,43 @@ bool SimplifyBool::VisitUnaryLNot(UnaryOperator const * expr) { return true; } auto e = getSubExprOfLogicalNegation(expr->getSubExpr()); - if (e == nullptr) { + if (e) { + // Ignore macros, otherwise + // OSL_ENSURE(!b, ...); + // triggers. + if (e->getLocStart().isMacroID()) + return true; + // double logical not of an int is an idiom to convert to bool + if (!e->IgnoreImpCasts()->getType()->isBooleanType()) + return true; + report( + DiagnosticsEngine::Warning, + ("double logical negation expression of the form '!!A' (with A of type" + " %0) can %select{logically|literally}1 be simplified as 'A'"), + expr->getLocStart()) + << e->IgnoreImpCasts()->getType() + << e->IgnoreImpCasts()->getType()->isBooleanType() + << expr->getSourceRange(); return true; } - // Ignore macros, otherwise - // OSL_ENSURE(!b, ...); - // triggers. - if (e->getLocStart().isMacroID()) - return true; - // double logical not of an int is an idiom to convert to bool - if (!e->IgnoreImpCasts()->getType()->isBooleanType()) - return true; - report( - DiagnosticsEngine::Warning, - ("double logical negation expression of the form '!!A' (with A of type" - " %0) can %select{logically|literally}1 be simplified as 'A'"), - expr->getLocStart()) - << e->IgnoreImpCasts()->getType() - << e->IgnoreImpCasts()->getType()->isBooleanType() - << expr->getSourceRange(); + if (auto binaryOp = dyn_cast<BinaryOperator>(expr->getSubExpr()->IgnoreParenImpCasts())) { + // Ignore macros, otherwise + // OSL_ENSURE(!b, ...); + // triggers. + if (binaryOp->getLocStart().isMacroID()) + return true; + auto t = binaryOp->getLHS()->IgnoreImpCasts()->getType()->getUnqualifiedDesugaredType(); + // RecordType would require more smarts - we'd need to verify that an inverted operator actually existed + if (t->isTemplateTypeParmType() || t->isRecordType() || t->isDependentType()) + return true; + if (!binaryOp->isComparisonOp()) + return true; + report( + DiagnosticsEngine::Warning, + ("logical negation of comparison operator, can be simplified by inverting operator"), + expr->getLocStart()) + << expr->getSourceRange(); + } return true; } |