Make not warning about !! in loplugin:simplifybool consistent

...so that 640e03da110d76b2c7d5ed5b8b8ba3b4367865ba "loplugin:simplifybool re-
activate the !! warning", which did not warn about

  !!( nAttribs & ucb::ContentInfoAttribute::KIND_FOLDER )

in ucb/source/core/ucbcmds.cxx (involving sal_Int32 and sal_Int16), would not
have warned about

  !!(nMode & nUpdateMode)

in sfx2/source/appl/workwin.cxx (ivolving o3tl::typed_flags<SfxVisibilityFlags>)
either.

Change-Id: Ibe955592951a04b1bd9a9b4e8cc502024bc1d460
Reviewed-on: https://gerrit.libreoffice.org/45083
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
This commit is contained in:
Stephan Bergmann 2017-11-22 13:13:09 +01:00
parent b26012ef15
commit 52dbe0c99b
2 changed files with 61 additions and 3 deletions

View File

@ -7,10 +7,35 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#include <cassert>
#include "plugin.hxx" #include "plugin.hxx"
namespace { namespace {
// Like clang::Stmt::IgnoreImplicit (lib/AST/Stmt.cpp), but also looking through implicit
// UserDefinedConversion's member function call:
Expr const * ignoreAllImplicit(Expr const * expr) {
if (auto const e = dyn_cast<ExprWithCleanups>(expr)) {
expr = e->getSubExpr();
}
if (auto const e = dyn_cast<MaterializeTemporaryExpr>(expr)) {
expr = e->GetTemporaryExpr();
}
if (auto const e = dyn_cast<CXXBindTemporaryExpr>(expr)) {
expr = e->getSubExpr();
}
while (auto const e = dyn_cast<ImplicitCastExpr>(expr)) {
expr = e->getSubExpr();
if (e->getCastKind() == CK_UserDefinedConversion) {
auto const ce = cast<CXXMemberCallExpr>(expr);
assert(ce->getNumArgs() == 0);
expr = ce->getImplicitObjectArgument();
}
}
return expr;
}
Expr const * ignoreParenImpCastAndComma(Expr const * expr) { Expr const * ignoreParenImpCastAndComma(Expr const * expr) {
for (;;) { for (;;) {
expr = expr->IgnoreParenImpCasts(); expr = expr->IgnoreParenImpCasts();
@ -94,15 +119,16 @@ bool SimplifyBool::VisitUnaryLNot(UnaryOperator const * expr) {
if (e->getLocStart().isMacroID()) if (e->getLocStart().isMacroID())
return true; return true;
// double logical not of an int is an idiom to convert to bool // double logical not of an int is an idiom to convert to bool
if (!e->IgnoreImpCasts()->getType()->isBooleanType()) auto const sub = ignoreAllImplicit(e);
if (!sub->getType()->isBooleanType())
return true; return true;
report( report(
DiagnosticsEngine::Warning, DiagnosticsEngine::Warning,
("double logical negation expression of the form '!!A' (with A of type" ("double logical negation expression of the form '!!A' (with A of type"
" %0) can %select{logically|literally}1 be simplified as 'A'"), " %0) can %select{logically|literally}1 be simplified as 'A'"),
expr->getLocStart()) expr->getLocStart())
<< e->IgnoreImpCasts()->getType() << sub->getType()
<< e->IgnoreImpCasts()->getType()->isBooleanType() << sub->getType()->isBooleanType()
<< expr->getSourceRange(); << expr->getSourceRange();
return true; return true;
} }

View File

@ -15,4 +15,36 @@ void f1(int a, int b)
} }
}; };
// Consitently either warn about all or none of the below occurrences of "!!":
enum E1
{
E1_1 = 1
};
enum E2
{
E2_1 = 1
};
E2 operator&(E2 e1, E2 e2);
bool operator!(E2 e);
enum class E3
{
E1 = 1
};
struct W
{
operator bool();
};
W operator&(E3 e1, E3 e2);
bool f0(int n) { return !!(n & 1); }
bool f1(E1 e) { return !!(e & E1_1); }
bool f2(E2 e) { return !!(e & E2_1); }
bool f3(E3 e) { return !!(e & E3::E1); }
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */