From 5d546de67b44dec23ecfa5a6378e2968912f8253 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Sun, 19 Jul 2020 14:53:29 +0200 Subject: Adapt to Clang 12 trunk RecursiveASTVisitor change "Removed a RecursiveASTVisitor feature to visit operator kinds with different methods". That change is incompatible in that before the change individual TraverseUnary* and TraverseBin* functions were called, while now TraverseUnaryOperator and TraverseBinaryOperator/TraverseCompoundAssignOperator are called for all the different operators. Fixed that with a few #if for the non-shared plugins, but that doesn't work for the shared plugin. So made the two affected plugins non- shared for now and left a better fix as a TODO. Change-Id: I5b87d329ae2c4c93bf605bb1ecc9641039f014a3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99000 Tested-by: Jenkins Reviewed-by: Stephan Bergmann --- compilerplugins/clang/charrightshift.cxx | 5 +- compilerplugins/clang/checkunusedparams.cxx | 14 +- compilerplugins/clang/commaoperator.cxx | 21 +- compilerplugins/clang/comparisonwithconstant.cxx | 29 +- compilerplugins/clang/consttobool.cxx | 62 ++-- compilerplugins/clang/derefnullptr.cxx | 7 +- compilerplugins/clang/empty.cxx | 37 +-- compilerplugins/clang/fakebool.cxx | 9 +- compilerplugins/clang/functionaddress.hxx | 5 +- compilerplugins/clang/implicitboolconversion.cxx | 350 +++++++-------------- compilerplugins/clang/inlinefields.cxx | 7 +- compilerplugins/clang/intvsfloat.cxx | 8 +- compilerplugins/clang/passparamsbyref.cxx | 7 +- compilerplugins/clang/redundantcast.cxx | 43 +-- compilerplugins/clang/salcall.cxx | 16 +- .../clang/sharedvisitor/dummyplugin.hxx | 5 +- compilerplugins/clang/simplifybool.cxx | 60 ++-- compilerplugins/clang/simplifypointertobool.cxx | 92 +++--- .../clang/test/implicitboolconversion.cxx | 8 + 19 files changed, 358 insertions(+), 427 deletions(-) (limited to 'compilerplugins') diff --git a/compilerplugins/clang/charrightshift.cxx b/compilerplugins/clang/charrightshift.cxx index 6f3027002daa..4168826aeb13 100644 --- a/compilerplugins/clang/charrightshift.cxx +++ b/compilerplugins/clang/charrightshift.cxx @@ -24,7 +24,10 @@ public: void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } - bool VisitBinShr(BinaryOperator const * expr) { + bool VisitBinaryOperator(BinaryOperator const * expr) { + if (expr->getOpcode() != BO_Shr) { + return true; + } if (ignoreLocation(expr)) { return true; } diff --git a/compilerplugins/clang/checkunusedparams.cxx b/compilerplugins/clang/checkunusedparams.cxx index f5540db33e43..fac2a08d3249 100644 --- a/compilerplugins/clang/checkunusedparams.cxx +++ b/compilerplugins/clang/checkunusedparams.cxx @@ -30,10 +30,10 @@ public: FilteringPlugin(data) {} void run() override; bool VisitFunctionDecl(FunctionDecl const *); - bool VisitUnaryAddrOf(UnaryOperator const *); + bool VisitUnaryOperator(UnaryOperator const *); bool VisitInitListExpr(InitListExpr const *); bool VisitCallExpr(CallExpr const *); - bool VisitBinAssign(BinaryOperator const *); + bool VisitBinaryOperator(BinaryOperator const *); bool VisitCXXConstructExpr(CXXConstructExpr const *); private: void checkForFunctionDecl(Expr const *, bool bCheckOnly = false); @@ -85,14 +85,20 @@ void CheckUnusedParams::run() TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } -bool CheckUnusedParams::VisitUnaryAddrOf(UnaryOperator const * op) { +bool CheckUnusedParams::VisitUnaryOperator(UnaryOperator const * op) { + if (op->getOpcode() != UO_AddrOf) { + return true; + } if (m_phase != PluginPhase::FindAddressOf) return true; checkForFunctionDecl(op->getSubExpr()); return true; } -bool CheckUnusedParams::VisitBinAssign(BinaryOperator const * binaryOperator) { +bool CheckUnusedParams::VisitBinaryOperator(BinaryOperator const * binaryOperator) { + if (binaryOperator->getOpcode() != BO_Assign) { + return true; + } if (m_phase != PluginPhase::FindAddressOf) return true; checkForFunctionDecl(binaryOperator->getRHS()); diff --git a/compilerplugins/clang/commaoperator.cxx b/compilerplugins/clang/commaoperator.cxx index e619d3794c58..423bd49e5e43 100644 --- a/compilerplugins/clang/commaoperator.cxx +++ b/compilerplugins/clang/commaoperator.cxx @@ -12,6 +12,9 @@ #include #include #include + +#include "config_clang.h" + #include "plugin.hxx" /** @@ -66,8 +69,11 @@ public: return ret; } - bool TraverseBinComma(BinaryOperator * expr) { - if (!WalkUpFromBinComma(expr)) { + bool TraverseBinaryOperator(BinaryOperator * expr) { + if (expr->getOpcode() != BO_Comma) { + return RecursiveASTVisitor::TraverseBinaryOperator(expr); + } + if (!WalkUpFromBinaryOperator(expr)) { return false; } auto const saved1 = ignore1_; @@ -78,15 +84,22 @@ public: return ret; } - bool VisitBinComma(const BinaryOperator* ); +#if CLANG_VERSION <= 110000 + bool TraverseBinComma(BinaryOperator * expr) { return TraverseBinaryOperator(expr); } +#endif + + bool VisitBinaryOperator(const BinaryOperator* ); private: Stmt const * ignore1_ = nullptr; Stmt const * ignore2_ = nullptr; }; -bool CommaOperator::VisitBinComma(const BinaryOperator* binaryOp) +bool CommaOperator::VisitBinaryOperator(const BinaryOperator* binaryOp) { + if (binaryOp->getOpcode() != BO_Comma) { + return true; + } if (binaryOp == ignore1_ || binaryOp == ignore2_) { return true; } diff --git a/compilerplugins/clang/comparisonwithconstant.cxx b/compilerplugins/clang/comparisonwithconstant.cxx index 6787be87424d..284e5567b65f 100644 --- a/compilerplugins/clang/comparisonwithconstant.cxx +++ b/compilerplugins/clang/comparisonwithconstant.cxx @@ -13,6 +13,8 @@ #include #include +#include "config_clang.h" + #include "compat.hxx" #include "plugin.hxx" @@ -33,29 +35,26 @@ public: TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } - // Deliberately drop RecursiveASTVisitor::TraverseBinEQ's DataRecursionQueue - // parameter; TraverseBinEQ must use stack instead of data recursion for any + // Deliberately drop RecursiveASTVisitor::TraverseBinaryOperator's DataRecursionQueue + // parameter; TraverseBinaryOperator must use stack instead of data recursion for any // children's VisitBinaryOperator to see changes to occurrence_ by a parent // VisitBinaryOperator: - bool TraverseBinEQ(BinaryOperator * S) + bool TraverseBinaryOperator(BinaryOperator * S) { + auto const op = S->getOpcode(); + if (op != BO_EQ && op != BO_NE) { + return RecursiveASTVisitor::TraverseBinaryOperator(S); + } auto const saved = occurrence_; - auto const ret = RecursiveASTVisitor::TraverseBinEQ(S); + auto const ret = RecursiveASTVisitor::TraverseBinaryOperator(S); occurrence_ = saved; return ret; } - // Deliberately drop RecursiveASTVisitor::TraverseBinNE's DataRecursionQueue - // parameter; TraverseBinNE must use stack instead of data recursion for any - // children's VisitBinaryOperator to see changes to occurrence_ by a parent - // VisitBinaryOperator: - bool TraverseBinNE(BinaryOperator * S) - { - auto const saved = occurrence_; - auto const ret = RecursiveASTVisitor::TraverseBinNE(S); - occurrence_ = saved; - return ret; - } +#if CLANG_VERSION <= 110000 + bool TraverseBinEQ(BinaryOperator * expr) { return TraverseBinaryOperator(expr); } + bool TraverseBinNE(BinaryOperator * expr) { return TraverseBinaryOperator(expr); } +#endif bool VisitBinaryOperator(const BinaryOperator *); private: diff --git a/compilerplugins/clang/consttobool.cxx b/compilerplugins/clang/consttobool.cxx index c09a9534bb75..b8933b231621 100644 --- a/compilerplugins/clang/consttobool.cxx +++ b/compilerplugins/clang/consttobool.cxx @@ -7,7 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef LO_CLANG_SHARED_PLUGINS +//TODO: Make this a shared plugin for Clang 12 (and possibly even for older Clang) again. #include #include @@ -15,6 +15,8 @@ #include "clang/Basic/Builtins.h" +#include "config_clang.h" + #include "check.hxx" #include "plugin.hxx" @@ -55,54 +57,74 @@ public: return ret; } - bool PreTraverseUnaryLNot(UnaryOperator* expr) + bool PreTraverseUnaryOperator(UnaryOperator* expr) { - ignoredInAssert_.push(expr->getSubExpr()); + if (expr->getOpcode() == UO_LNot) + { + ignoredInAssert_.push(expr->getSubExpr()); + } return true; } - bool PostTraverseUnaryLNot(UnaryOperator*, bool) + bool PostTraverseUnaryOperator(UnaryOperator* expr, bool) { - assert(!ignoredInAssert_.empty()); - ignoredInAssert_.pop(); + if (expr->getOpcode() == UO_LNot) + { + assert(!ignoredInAssert_.empty()); + ignoredInAssert_.pop(); + } return true; } - bool TraverseUnaryLNot(UnaryOperator* expr) + bool TraverseUnaryOperator(UnaryOperator* expr) { bool ret = true; - if (PreTraverseUnaryLNot(expr)) + if (PreTraverseUnaryOperator(expr)) { - ret = FilteringPlugin::TraverseUnaryLNot(expr); - PostTraverseUnaryLNot(expr, ret); + ret = FilteringPlugin::TraverseUnaryOperator(expr); + PostTraverseUnaryOperator(expr, ret); } return ret; } - bool PreTraverseBinLAnd(BinaryOperator* expr) +#if CLANG_VERSION <= 110000 + bool TraverseUnaryLNot(UnaryOperator* expr) { return TraverseUnaryOperator(expr); } +#endif + + bool PreTraverseBinaryOperator(BinaryOperator* expr) { - ignoredInAssert_.push(expr->getRHS()); + if (expr->getOpcode() == BO_LAnd) + { + ignoredInAssert_.push(expr->getRHS()); + } return true; } - bool PostTraverseBinLAnd(BinaryOperator*, bool) + bool PostTraverseBinaryOperator(BinaryOperator* expr, bool) { - assert(!ignoredInAssert_.empty()); - ignoredInAssert_.pop(); + if (expr->getOpcode() == BO_LAnd) + { + assert(!ignoredInAssert_.empty()); + ignoredInAssert_.pop(); + } return true; } - bool TraverseBinLAnd(BinaryOperator* expr) + bool TraverseBinaryOperator(BinaryOperator* expr) { bool ret = true; - if (PreTraverseBinLAnd(expr)) + if (PreTraverseBinaryOperator(expr)) { - ret = FilteringPlugin::TraverseBinLAnd(expr); - PostTraverseBinLAnd(expr, ret); + ret = FilteringPlugin::TraverseBinaryOperator(expr); + PostTraverseBinaryOperator(expr, ret); } return ret; } +#if CLANG_VERSION <= 110000 + bool TraverseBinLAnd(BinaryOperator* expr) { return TraverseBinaryOperator(expr); } +#endif + bool VisitImplicitCastExpr(ImplicitCastExpr const* expr) { if (ignoreLocation(expr)) @@ -276,6 +298,4 @@ private: loplugin::Plugin::Registration consttobool("consttobool"); } -#endif - /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/derefnullptr.cxx b/compilerplugins/clang/derefnullptr.cxx index 61ffbfab24df..b1c9d6da6747 100644 --- a/compilerplugins/clang/derefnullptr.cxx +++ b/compilerplugins/clang/derefnullptr.cxx @@ -23,10 +23,13 @@ public: void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } - bool VisitUnaryDeref(UnaryOperator const * op); + bool VisitUnaryOperator(UnaryOperator const * op); }; -bool DerefNullPtr::VisitUnaryDeref(UnaryOperator const * op) { +bool DerefNullPtr::VisitUnaryOperator(UnaryOperator const * op) { + if (op->getOpcode() != UO_Deref) { + return true; + } if (!ignoreLocation(op) && (op->getSubExpr()->IgnoreParenCasts()->isNullPointerConstant( compiler.getASTContext(), Expr::NPC_ValueDependentIsNotNull/*TODO*/) diff --git a/compilerplugins/clang/empty.cxx b/compilerplugins/clang/empty.cxx index 108745460d0c..0eaa4e287852 100644 --- a/compilerplugins/clang/empty.cxx +++ b/compilerplugins/clang/empty.cxx @@ -47,39 +47,12 @@ public: { } - bool VisitBinLT(BinaryOperator const* expr) + bool VisitBinaryOperator(BinaryOperator const* expr) { - visitComparison(expr); - return true; - } - - bool VisitBinGT(BinaryOperator const* expr) - { - visitComparison(expr); - return true; - } - - bool VisitBinLE(BinaryOperator const* expr) - { - visitComparison(expr); - return true; - } - - bool VisitBinGE(BinaryOperator const* expr) - { - visitComparison(expr); - return true; - } - - bool VisitBinEQ(BinaryOperator const* expr) - { - visitComparison(expr); - return true; - } - - bool VisitBinNE(BinaryOperator const* expr) - { - visitComparison(expr); + if (expr->isRelationalOp() || expr->isEqualityOp()) + { + visitComparison(expr); + } return true; } diff --git a/compilerplugins/clang/fakebool.cxx b/compilerplugins/clang/fakebool.cxx index f50116b8ee88..804f1d51afa1 100644 --- a/compilerplugins/clang/fakebool.cxx +++ b/compilerplugins/clang/fakebool.cxx @@ -184,7 +184,7 @@ public: virtual void run() override; - bool VisitUnaryAddrOf(UnaryOperator const * op); + bool VisitUnaryOperator(UnaryOperator * op); bool VisitCallExpr(CallExpr * expr); @@ -446,8 +446,11 @@ void FakeBool::run() { } } -bool FakeBool::VisitUnaryAddrOf(UnaryOperator const * op) { - FunctionAddress::VisitUnaryAddrOf(op); +bool FakeBool::VisitUnaryOperator(UnaryOperator * op) { + if (op->getOpcode() != UO_AddrOf) { + return FunctionAddress::VisitUnaryOperator(op); + } + FunctionAddress::VisitUnaryOperator(op); Expr const * e1 = op->getSubExpr()->IgnoreParenCasts(); if (isFakeBool(e1->getType()) != FBK_No) { if (DeclRefExpr const * e2 = dyn_cast(e1)) { diff --git a/compilerplugins/clang/functionaddress.hxx b/compilerplugins/clang/functionaddress.hxx index 93241ea5b4b0..266788a24119 100644 --- a/compilerplugins/clang/functionaddress.hxx +++ b/compilerplugins/clang/functionaddress.hxx @@ -88,7 +88,10 @@ public: return true; } - bool VisitUnaryAddrOf(UnaryOperator const * expr) { + bool VisitUnaryOperator(UnaryOperator * expr) { + if (expr->getOpcode() != UO_AddrOf) { + return Base::VisitUnaryOperator(expr); + } if (this->ignoreLocation(expr)) { return true; } diff --git a/compilerplugins/clang/implicitboolconversion.cxx b/compilerplugins/clang/implicitboolconversion.cxx index 5b713ce77ecb..53da99518ff0 100644 --- a/compilerplugins/clang/implicitboolconversion.cxx +++ b/compilerplugins/clang/implicitboolconversion.cxx @@ -17,6 +17,8 @@ #include "clang/Basic/Builtins.h" +#include "config_clang.h" + #include "check.hxx" #include "compat.hxx" #include "plugin.hxx" @@ -249,25 +251,28 @@ public: bool TraverseConditionalOperator(ConditionalOperator * expr); - bool TraverseBinLT(BinaryOperator * expr); - - bool TraverseBinLE(BinaryOperator * expr); - - bool TraverseBinGT(BinaryOperator * expr); - - bool TraverseBinGE(BinaryOperator * expr); - - bool TraverseBinEQ(BinaryOperator * expr); - - bool TraverseBinNE(BinaryOperator * expr); - - bool TraverseBinAssign(BinaryOperator * expr); - - bool TraverseBinAndAssign(CompoundAssignOperator * expr); - - bool TraverseBinOrAssign(CompoundAssignOperator * expr); - - bool TraverseBinXorAssign(CompoundAssignOperator * expr); + bool TraverseBinaryOperator(BinaryOperator * expr); + +#if CLANG_VERSION <= 110000 + bool TraverseBinLT(BinaryOperator * expr) { return TraverseBinaryOperator(expr); } + bool TraverseBinLE(BinaryOperator * expr) { return TraverseBinaryOperator(expr); } + bool TraverseBinGT(BinaryOperator * expr) { return TraverseBinaryOperator(expr); } + bool TraverseBinGE(BinaryOperator * expr) { return TraverseBinaryOperator(expr); } + bool TraverseBinEQ(BinaryOperator * expr) { return TraverseBinaryOperator(expr); } + bool TraverseBinNE(BinaryOperator * expr) { return TraverseBinaryOperator(expr); } + bool TraverseBinAssign(BinaryOperator * expr) { return TraverseBinaryOperator(expr); } +#endif + + bool TraverseCompoundAssignOperator(CompoundAssignOperator * expr); + +#if CLANG_VERSION <= 110000 + bool TraverseBinAndAssign(CompoundAssignOperator * expr) + { return TraverseCompoundAssignOperator(expr); } + bool TraverseBinOrAssign(CompoundAssignOperator * expr) + { return TraverseCompoundAssignOperator(expr); } + bool TraverseBinXorAssign(CompoundAssignOperator * expr) + { return TraverseCompoundAssignOperator(expr); } +#endif bool TraverseCXXStdInitializerListExpr(CXXStdInitializerListExpr * expr); @@ -521,235 +526,104 @@ bool ImplicitBoolConversion::TraverseConditionalOperator( return bRet; } -bool ImplicitBoolConversion::TraverseBinLT(BinaryOperator * expr) { - nested.push(std::vector()); - bool bRet = RecursiveASTVisitor::TraverseBinLT(expr); - assert(!nested.empty()); - for (auto i: nested.top()) { - if (!((i == expr->getLHS()->IgnoreParens() - && isMatchingBool( - expr->getRHS()->IgnoreImpCasts(), i->getSubExprAsWritten())) - || (i == expr->getRHS()->IgnoreParens() - && isMatchingBool( - expr->getLHS()->IgnoreImpCasts(), - i->getSubExprAsWritten())))) - { - reportWarning(i); - } - } - nested.pop(); - return bRet; -} - -bool ImplicitBoolConversion::TraverseBinLE(BinaryOperator * expr) { - nested.push(std::vector()); - bool bRet = RecursiveASTVisitor::TraverseBinLE(expr); - assert(!nested.empty()); - for (auto i: nested.top()) { - if (!((i == expr->getLHS()->IgnoreParens() - && isMatchingBool( - expr->getRHS()->IgnoreImpCasts(), i->getSubExprAsWritten())) - || (i == expr->getRHS()->IgnoreParens() - && isMatchingBool( - expr->getLHS()->IgnoreImpCasts(), - i->getSubExprAsWritten())))) - { - reportWarning(i); - } - } - nested.pop(); - return bRet; -} - -bool ImplicitBoolConversion::TraverseBinGT(BinaryOperator * expr) { - nested.push(std::vector()); - bool bRet = RecursiveASTVisitor::TraverseBinGT(expr); - assert(!nested.empty()); - for (auto i: nested.top()) { - if (!((i == expr->getLHS()->IgnoreParens() - && isMatchingBool( - expr->getRHS()->IgnoreImpCasts(), i->getSubExprAsWritten())) - || (i == expr->getRHS()->IgnoreParens() - && isMatchingBool( - expr->getLHS()->IgnoreImpCasts(), - i->getSubExprAsWritten())))) - { - reportWarning(i); - } - } - nested.pop(); - return bRet; -} - -bool ImplicitBoolConversion::TraverseBinGE(BinaryOperator * expr) { - nested.push(std::vector()); - bool bRet = RecursiveASTVisitor::TraverseBinGE(expr); - assert(!nested.empty()); - for (auto i: nested.top()) { - if (!((i == expr->getLHS()->IgnoreParens() - && isMatchingBool( - expr->getRHS()->IgnoreImpCasts(), i->getSubExprAsWritten())) - || (i == expr->getRHS()->IgnoreParens() - && isMatchingBool( - expr->getLHS()->IgnoreImpCasts(), - i->getSubExprAsWritten())))) - { - reportWarning(i); - } - } - nested.pop(); - return bRet; -} - -bool ImplicitBoolConversion::TraverseBinEQ(BinaryOperator * expr) { - nested.push(std::vector()); - bool bRet = RecursiveASTVisitor::TraverseBinEQ(expr); - assert(!nested.empty()); - for (auto i: nested.top()) { - if (!((i == expr->getLHS()->IgnoreParens() - && isMatchingBool( - expr->getRHS()->IgnoreImpCasts(), i->getSubExprAsWritten())) - || (i == expr->getRHS()->IgnoreParens() - && isMatchingBool( - expr->getLHS()->IgnoreImpCasts(), - i->getSubExprAsWritten())))) - { - reportWarning(i); - } - } - nested.pop(); - return bRet; -} - -bool ImplicitBoolConversion::TraverseBinNE(BinaryOperator * expr) { - nested.push(std::vector()); - bool bRet = RecursiveASTVisitor::TraverseBinNE(expr); - assert(!nested.empty()); - for (auto i: nested.top()) { - if (!((i == expr->getLHS()->IgnoreParens() - && isMatchingBool( - expr->getRHS()->IgnoreImpCasts(), i->getSubExprAsWritten())) - || (i == expr->getRHS()->IgnoreParens() - && isMatchingBool( - expr->getLHS()->IgnoreImpCasts(), - i->getSubExprAsWritten())))) - { - reportWarning(i); - } - } - nested.pop(); - return bRet; -} - -bool ImplicitBoolConversion::TraverseBinAssign(BinaryOperator * expr) { - nested.push(std::vector()); - bool bRet = RecursiveASTVisitor::TraverseBinAssign(expr); - // gtk-2.0/gtk/gtktogglebutton.h: struct _GtkToggleButton: - // guint GSEAL (active) : 1; - // even though : - // "active" gboolean : Read / Write - // qt5/QtGui/qaccessible.h: struct State: - // quint64 disabled : 1; - bool bExt = false; - MemberExpr const * me = dyn_cast(expr->getLHS()); - if (me != nullptr) { - FieldDecl const * fd = dyn_cast(me->getMemberDecl()); - if (fd != nullptr && fd->isBitField() - && fd->getBitWidthValue(compiler.getASTContext()) == 1) - { - auto const check = loplugin::TypeCheck(fd->getType()); - bExt = check.Typedef("guint").GlobalNamespace() - || check.Typedef("quint64").GlobalNamespace(); - } - } - assert(!nested.empty()); - for (auto i: nested.top()) { - if (i != expr->getRHS()->IgnoreParens() - || !(bExt || isBoolExpr(expr->getLHS()))) +bool ImplicitBoolConversion::TraverseBinaryOperator(BinaryOperator * expr) { + switch (expr->getOpcode()) { + case BO_LT: + case BO_LE: + case BO_GT: + case BO_GE: + case BO_EQ: + case BO_NE: { - reportWarning(i); + nested.push(std::vector()); + bool bRet = RecursiveASTVisitor::TraverseBinaryOperator(expr); + assert(!nested.empty()); + for (auto i: nested.top()) { + if (!((i == expr->getLHS()->IgnoreParens() + && isMatchingBool( + expr->getRHS()->IgnoreImpCasts(), i->getSubExprAsWritten())) + || (i == expr->getRHS()->IgnoreParens() + && isMatchingBool( + expr->getLHS()->IgnoreImpCasts(), + i->getSubExprAsWritten())))) + { + reportWarning(i); + } + } + nested.pop(); + return bRet; } - } - nested.pop(); - return bRet; -} - -bool ImplicitBoolConversion::TraverseBinAndAssign(CompoundAssignOperator * expr) -{ - nested.push(std::vector()); - bool bRet = RecursiveASTVisitor::TraverseBinAndAssign(expr); - assert(!nested.empty()); - for (auto i: nested.top()) { - if (i != expr->getRHS()->IgnoreParens() - || !isBool(expr->getLHS()->IgnoreParens(), false)) + case BO_Assign: { - reportWarning(i); - } - } - nested.pop(); - if (!ignoreLocation(expr) && isBool(expr->getLHS(), false) - && !isBool(expr->getRHS()->IgnoreParenImpCasts(), false)) - { - report( - DiagnosticsEngine::Warning, "mix of %0 and %1 in operator &=", - compat::getBeginLoc(expr->getRHS())) - << expr->getLHS()->getType() - << expr->getRHS()->IgnoreParenImpCasts()->getType() - << expr->getSourceRange(); - } - return bRet; -} - -bool ImplicitBoolConversion::TraverseBinOrAssign(CompoundAssignOperator * expr) -{ - nested.push(std::vector()); - bool bRet = RecursiveASTVisitor::TraverseBinOrAssign(expr); - assert(!nested.empty()); - for (auto i: nested.top()) { - if (i != expr->getRHS()->IgnoreParens() - || !isBool(expr->getLHS()->IgnoreParens(), false)) - { - reportWarning(i); + nested.push(std::vector()); + bool bRet = RecursiveASTVisitor::TraverseBinaryOperator(expr); + // gtk-2.0/gtk/gtktogglebutton.h: struct _GtkToggleButton: + // guint GSEAL (active) : 1; + // even though : + // "active" gboolean : Read / Write + // qt5/QtGui/qaccessible.h: struct State: + // quint64 disabled : 1; + bool bExt = false; + MemberExpr const * me = dyn_cast(expr->getLHS()); + if (me != nullptr) { + FieldDecl const * fd = dyn_cast(me->getMemberDecl()); + if (fd != nullptr && fd->isBitField() + && fd->getBitWidthValue(compiler.getASTContext()) == 1) + { + auto const check = loplugin::TypeCheck(fd->getType()); + bExt = check.Typedef("guint").GlobalNamespace() + || check.Typedef("quint64").GlobalNamespace(); + } + } + assert(!nested.empty()); + for (auto i: nested.top()) { + if (i != expr->getRHS()->IgnoreParens() + || !(bExt || isBoolExpr(expr->getLHS()))) + { + reportWarning(i); + } + } + nested.pop(); + return bRet; } + default: + return RecursiveASTVisitor::TraverseBinaryOperator(expr); } - nested.pop(); - if (!ignoreLocation(expr) && isBool(expr->getLHS(), false) - && !isBool(expr->getRHS()->IgnoreParenImpCasts(), false)) - { - report( - DiagnosticsEngine::Warning, "mix of %0 and %1 in operator |=", - compat::getBeginLoc(expr->getRHS())) - << expr->getLHS()->getType() - << expr->getRHS()->IgnoreParenImpCasts()->getType() - << expr->getSourceRange(); - } - return bRet; } -bool ImplicitBoolConversion::TraverseBinXorAssign(CompoundAssignOperator * expr) -{ - nested.push(std::vector()); - bool bRet = RecursiveASTVisitor::TraverseBinXorAssign(expr); - assert(!nested.empty()); - for (auto i: nested.top()) { - if (i != expr->getRHS()->IgnoreParens() - || !isBool(expr->getLHS()->IgnoreParens(), false)) +bool ImplicitBoolConversion::TraverseCompoundAssignOperator(CompoundAssignOperator * expr) { + switch (expr->getOpcode()) { + case BO_AndAssign: + case BO_OrAssign: + case BO_XorAssign: { - reportWarning(i); + nested.push(std::vector()); + bool bRet = RecursiveASTVisitor::TraverseCompoundAssignOperator(expr); + assert(!nested.empty()); + for (auto i: nested.top()) { + if (i != expr->getRHS()->IgnoreParens() + || !isBool(expr->getLHS()->IgnoreParens(), false)) + { + reportWarning(i); + } + } + nested.pop(); + if (!ignoreLocation(expr) && isBool(expr->getLHS(), false) + && !isBool(expr->getRHS()->IgnoreParenImpCasts(), false)) + { + report( + DiagnosticsEngine::Warning, "mix of %0 and %1 in operator %2", + compat::getBeginLoc(expr->getRHS())) + << expr->getLHS()->getType() + << expr->getRHS()->IgnoreParenImpCasts()->getType() + << expr->getOpcodeStr() + << expr->getSourceRange(); + } + return bRet; } + default: + return RecursiveASTVisitor::TraverseCompoundAssignOperator(expr); } - nested.pop(); - if (!ignoreLocation(expr) && isBool(expr->getLHS(), false) - && !isBool(expr->getRHS()->IgnoreParenImpCasts(), false)) - { - report( - DiagnosticsEngine::Warning, "mix of %0 and %1 in operator ^=", - compat::getBeginLoc(expr->getRHS())) - << expr->getLHS()->getType() - << expr->getRHS()->IgnoreParenImpCasts()->getType() - << expr->getSourceRange(); - } - return bRet; } bool ImplicitBoolConversion::TraverseCXXStdInitializerListExpr( diff --git a/compilerplugins/clang/inlinefields.cxx b/compilerplugins/clang/inlinefields.cxx index a29a9662e6d5..abc665de6959 100644 --- a/compilerplugins/clang/inlinefields.cxx +++ b/compilerplugins/clang/inlinefields.cxx @@ -95,7 +95,7 @@ public: bool VisitFieldDecl( const FieldDecl* ); bool VisitCXXConstructorDecl( const CXXConstructorDecl* ); bool VisitCXXDeleteExpr( const CXXDeleteExpr* ); - bool VisitBinAssign( const BinaryOperator* ); + bool VisitBinaryOperator( const BinaryOperator* ); private: MyFieldInfo niceName(const FieldDecl*); void checkTouched(const FieldDecl* fieldDecl, const Expr* memberExpr); @@ -174,8 +174,11 @@ static bool isSameParent(const CXXMethodDecl* cxxMethodDecl, const FieldDecl* fi return cxxMethodDecl->getParent() == dyn_cast(fieldDecl->getParent()); } -bool InlineFields::VisitBinAssign(const BinaryOperator * binaryOp) +bool InlineFields::VisitBinaryOperator(const BinaryOperator * binaryOp) { + if (binaryOp->getOpcode() != BO_Assign) { + return true; + } if( ignoreLocation( binaryOp ) ) return true; auto memberExpr = dyn_cast(binaryOp->getLHS()); diff --git a/compilerplugins/clang/intvsfloat.cxx b/compilerplugins/clang/intvsfloat.cxx index 922d14db2b1c..d89b34155cce 100644 --- a/compilerplugins/clang/intvsfloat.cxx +++ b/compilerplugins/clang/intvsfloat.cxx @@ -32,7 +32,7 @@ public: void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } bool VisitVarDecl(VarDecl const*); - bool VisitBinEQ(BinaryOperator const*); + bool VisitBinaryOperator(BinaryOperator const*); private: llvm::Optional getExprValue(Expr const* expr); @@ -61,8 +61,12 @@ bool IntVsFloat::VisitVarDecl(VarDecl const* varDecl) return true; } -bool IntVsFloat::VisitBinEQ(BinaryOperator const* op) +bool IntVsFloat::VisitBinaryOperator(BinaryOperator const* op) { + if (op->getOpcode() != BO_EQ) + { + return true; + } if (ignoreLocation(compat::getBeginLoc(op))) return true; auto lhs = op->getLHS()->IgnoreImpCasts(); diff --git a/compilerplugins/clang/passparamsbyref.cxx b/compilerplugins/clang/passparamsbyref.cxx index 7de7133f3aed..9a3562752c2c 100644 --- a/compilerplugins/clang/passparamsbyref.cxx +++ b/compilerplugins/clang/passparamsbyref.cxx @@ -49,7 +49,7 @@ public: bool PreTraverseImplicitCastExpr(ImplicitCastExpr *); bool TraverseImplicitCastExpr(ImplicitCastExpr *); - bool VisitBinAssign(BinaryOperator const *); + bool VisitBinaryOperator(BinaryOperator const *); bool VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *); private: @@ -166,8 +166,11 @@ bool PassParamsByRef::TraverseImplicitCastExpr(ImplicitCastExpr * expr) return ret; } -bool PassParamsByRef::VisitBinAssign(const BinaryOperator * binaryOperator) +bool PassParamsByRef::VisitBinaryOperator(const BinaryOperator * binaryOperator) { + if (binaryOperator->getOpcode() != BO_Assign) { + return true; + } if (!mbInsideFunctionDecl) return true; // if we are assigning to a parameter, it can be inconvenient to make the param pass-by-ref diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx index 862410c6484d..bdac3f3bcc56 100644 --- a/compilerplugins/clang/redundantcast.cxx +++ b/compilerplugins/clang/redundantcast.cxx @@ -127,28 +127,21 @@ public: bool VisitCStyleCastExpr(CStyleCastExpr const * expr); - bool VisitBinSub(BinaryOperator const * expr) - { return visitBinOp(expr); } - - bool VisitBinLT(BinaryOperator const * expr) - { return visitBinOp(expr); } - - bool VisitBinGT(BinaryOperator const * expr) - { return visitBinOp(expr); } - - bool VisitBinLE(BinaryOperator const * expr) - { return visitBinOp(expr); } - - bool VisitBinGE(BinaryOperator const * expr) - { return visitBinOp(expr); } - - bool VisitBinEQ(BinaryOperator const * expr) - { return visitBinOp(expr); } - - bool VisitBinNE(BinaryOperator const * expr) - { return visitBinOp(expr); } + bool VisitBinaryOperator(BinaryOperator const * expr) { + auto const op = expr->getOpcode(); + if (op == BO_Sub || expr->isRelationalOp() || expr->isEqualityOp()) { + return visitBinOp(expr); + } + if (op == BO_Assign) { + if (ignoreLocation(expr)) { + return true; + } + visitAssign(expr->getLHS()->getType(), expr->getRHS()); + return true; + } + return true; + } - bool VisitBinAssign(BinaryOperator const * binaryOperator); bool VisitVarDecl(VarDecl const * varDecl); private: @@ -356,14 +349,6 @@ bool RedundantCast::VisitCStyleCastExpr(CStyleCastExpr const * expr) { return true; } -bool RedundantCast::VisitBinAssign(BinaryOperator const * binaryOperator) { - if (ignoreLocation(binaryOperator)) { - return true; - } - visitAssign(binaryOperator->getLHS()->getType(), binaryOperator->getRHS()); - return true; -} - bool RedundantCast::VisitVarDecl(VarDecl const * varDecl) { if (ignoreLocation(varDecl)) { return true; diff --git a/compilerplugins/clang/salcall.cxx b/compilerplugins/clang/salcall.cxx index 66e8ec89861e..3c91e76b870a 100644 --- a/compilerplugins/clang/salcall.cxx +++ b/compilerplugins/clang/salcall.cxx @@ -68,10 +68,10 @@ public: } bool VisitFunctionDecl(FunctionDecl const*); - bool VisitUnaryAddrOf(UnaryOperator const*); + bool VisitUnaryOperator(UnaryOperator const*); bool VisitInitListExpr(InitListExpr const*); bool VisitCallExpr(CallExpr const*); - bool VisitBinAssign(BinaryOperator const*); + bool VisitBinaryOperator(BinaryOperator const*); bool VisitCXXConstructExpr(CXXConstructExpr const*); private: @@ -88,16 +88,24 @@ private: PluginPhase m_phase; }; -bool SalCall::VisitUnaryAddrOf(UnaryOperator const* op) +bool SalCall::VisitUnaryOperator(UnaryOperator const* op) { + if (op->getOpcode() != UO_AddrOf) + { + return true; + } if (m_phase != PluginPhase::FindAddressOf) return true; checkForFunctionDecl(op->getSubExpr()); return true; } -bool SalCall::VisitBinAssign(BinaryOperator const* binaryOperator) +bool SalCall::VisitBinaryOperator(BinaryOperator const* binaryOperator) { + if (binaryOperator->getOpcode() != BO_Assign) + { + return true; + } if (m_phase != PluginPhase::FindAddressOf) return true; checkForFunctionDecl(binaryOperator->getRHS()); diff --git a/compilerplugins/clang/sharedvisitor/dummyplugin.hxx b/compilerplugins/clang/sharedvisitor/dummyplugin.hxx index b52dfaebd238..d20f82f9278e 100644 --- a/compilerplugins/clang/sharedvisitor/dummyplugin.hxx +++ b/compilerplugins/clang/sharedvisitor/dummyplugin.hxx @@ -12,6 +12,8 @@ #ifndef DUMMYPLUGIN_H #define DUMMYPLUGIN_H +#include "config_clang.h" + #include "../plugin.hxx" using namespace clang; @@ -42,9 +44,6 @@ public: bool TraverseDoStmt( DoStmt* ) { return complain(); } bool TraverseForStmt( ForStmt* ) { return complain(); } bool TraverseCXXForRangeStmt( CXXForRangeStmt* ) { return complain(); } - bool TraverseUnaryLNot( UnaryOperator* ) { return complain(); } - bool TraverseBinLAnd( BinaryOperator* ) { return complain(); } - bool TraverseBinLOr( BinaryOperator* ) { return complain(); } bool TraverseConditionalOperator( ConditionalOperator* ) { return complain(); } bool TraverseCXXCatchStmt( CXXCatchStmt* ) { return complain(); } bool TraverseCXXDestructorDecl( CXXDestructorDecl* ) { return complain(); } diff --git a/compilerplugins/clang/simplifybool.cxx b/compilerplugins/clang/simplifybool.cxx index 4e48de99cb5c..ff50cb47f0c7 100644 --- a/compilerplugins/clang/simplifybool.cxx +++ b/compilerplugins/clang/simplifybool.cxx @@ -187,27 +187,29 @@ public: void run() override; - bool VisitUnaryLNot(UnaryOperator const * expr); + bool VisitUnaryOperator(UnaryOperator const * expr); - bool VisitBinLT(BinaryOperator const * expr); + bool VisitBinaryOperator(BinaryOperator const * expr); - bool VisitBinGT(BinaryOperator const * expr); + bool VisitConditionalOperator(ConditionalOperator const * expr); - bool VisitBinLE(BinaryOperator const * expr); + bool TraverseFunctionDecl(FunctionDecl *); - bool VisitBinGE(BinaryOperator const * expr); + bool TraverseCXXMethodDecl(CXXMethodDecl *); - bool VisitBinEQ(BinaryOperator const * expr); +private: + bool visitBinLT(BinaryOperator const * expr); - bool VisitBinNE(BinaryOperator const * expr); + bool visitBinGT(BinaryOperator const * expr); - bool VisitConditionalOperator(ConditionalOperator const * expr); + bool visitBinLE(BinaryOperator const * expr); - bool TraverseFunctionDecl(FunctionDecl *); + bool visitBinGE(BinaryOperator const * expr); - bool TraverseCXXMethodDecl(CXXMethodDecl *); + bool visitBinEQ(BinaryOperator const * expr); + + bool visitBinNE(BinaryOperator const * expr); -private: FunctionDecl* m_insideFunctionDecl = nullptr; }; @@ -217,7 +219,10 @@ void SimplifyBool::run() { } } -bool SimplifyBool::VisitUnaryLNot(UnaryOperator const * expr) { +bool SimplifyBool::VisitUnaryOperator(UnaryOperator const * expr) { + if (expr->getOpcode() != UO_LNot) { + return true; + } if (ignoreLocation(expr)) { return true; } @@ -356,7 +361,26 @@ bool SimplifyBool::VisitUnaryLNot(UnaryOperator const * expr) { return true; } -bool SimplifyBool::VisitBinLT(BinaryOperator const * expr) { +bool SimplifyBool::VisitBinaryOperator(BinaryOperator const * expr) { + switch (expr->getOpcode()) { + case BO_LT: + return visitBinLT(expr); + case BO_GT: + return visitBinGT(expr); + case BO_LE: + return visitBinLE(expr); + case BO_GE: + return visitBinGE(expr); + case BO_EQ: + return visitBinEQ(expr); + case BO_NE: + return visitBinNE(expr); + default: + return true; + } +} + +bool SimplifyBool::visitBinLT(BinaryOperator const * expr) { if (ignoreLocation(expr)) { return true; } @@ -473,7 +497,7 @@ bool SimplifyBool::VisitBinLT(BinaryOperator const * expr) { return true; } -bool SimplifyBool::VisitBinGT(BinaryOperator const * expr) { +bool SimplifyBool::visitBinGT(BinaryOperator const * expr) { if (ignoreLocation(expr)) { return true; } @@ -591,7 +615,7 @@ bool SimplifyBool::VisitBinGT(BinaryOperator const * expr) { return true; } -bool SimplifyBool::VisitBinLE(BinaryOperator const * expr) { +bool SimplifyBool::visitBinLE(BinaryOperator const * expr) { if (ignoreLocation(expr)) { return true; } @@ -710,7 +734,7 @@ bool SimplifyBool::VisitBinLE(BinaryOperator const * expr) { return true; } -bool SimplifyBool::VisitBinGE(BinaryOperator const * expr) { +bool SimplifyBool::visitBinGE(BinaryOperator const * expr) { if (ignoreLocation(expr)) { return true; } @@ -829,7 +853,7 @@ bool SimplifyBool::VisitBinGE(BinaryOperator const * expr) { return true; } -bool SimplifyBool::VisitBinEQ(BinaryOperator const * expr) { +bool SimplifyBool::visitBinEQ(BinaryOperator const * expr) { if (ignoreLocation(expr)) { return true; } @@ -965,7 +989,7 @@ bool SimplifyBool::VisitBinEQ(BinaryOperator const * expr) { return true; } -bool SimplifyBool::VisitBinNE(BinaryOperator const * expr) { +bool SimplifyBool::visitBinNE(BinaryOperator const * expr) { if (ignoreLocation(expr)) { return true; } diff --git a/compilerplugins/clang/simplifypointertobool.cxx b/compilerplugins/clang/simplifypointertobool.cxx index 05058d5d8c01..756985c760fa 100644 --- a/compilerplugins/clang/simplifypointertobool.cxx +++ b/compilerplugins/clang/simplifypointertobool.cxx @@ -16,6 +16,9 @@ #include #include + +#include "config_clang.h" + #include "plugin.hxx" #include "check.hxx" #include "compat.hxx" @@ -26,7 +29,7 @@ can be if (x) */ -#ifndef LO_CLANG_SHARED_PLUGINS +//TODO: Make this a shared plugin for Clang 12 (and possibly even for older Clang) again. namespace { @@ -47,76 +50,75 @@ public: bool VisitImplicitCastExpr(ImplicitCastExpr const*); bool VisitBinaryOperator(BinaryOperator const*); - bool PreTraverseUnaryLNot(UnaryOperator* expr) + bool PreTraverseUnaryOperator(UnaryOperator* expr) { - contextuallyConvertedExprs_.push_back(expr->getSubExpr()->IgnoreParenImpCasts()); + if (expr->getOpcode() == UO_LNot) + { + contextuallyConvertedExprs_.push_back(expr->getSubExpr()->IgnoreParenImpCasts()); + } return true; } - bool PostTraverseUnaryLNot(UnaryOperator*, bool) + bool PostTraverseUnaryOperator(UnaryOperator* expr, bool) { - assert(!contextuallyConvertedExprs_.empty()); - contextuallyConvertedExprs_.pop_back(); + if (expr->getOpcode() == UO_LNot) + { + assert(!contextuallyConvertedExprs_.empty()); + contextuallyConvertedExprs_.pop_back(); + } return true; } - bool TraverseUnaryLNot(UnaryOperator* expr) + bool TraverseUnaryOperator(UnaryOperator* expr) { - auto res = PreTraverseUnaryLNot(expr); + auto res = PreTraverseUnaryOperator(expr); assert(res); - res = FilteringRewritePlugin::TraverseUnaryLNot(expr); - PostTraverseUnaryLNot(expr, res); + res = FilteringRewritePlugin::TraverseUnaryOperator(expr); + PostTraverseUnaryOperator(expr, res); return res; } - bool PreTraverseBinLAnd(BinaryOperator* expr) - { - contextuallyConvertedExprs_.push_back(expr->getLHS()->IgnoreParenImpCasts()); - contextuallyConvertedExprs_.push_back(expr->getRHS()->IgnoreParenImpCasts()); - return true; - } - - bool PostTraverseBinLAnd(BinaryOperator*, bool) - { - assert(contextuallyConvertedExprs_.size() >= 2); - contextuallyConvertedExprs_.pop_back(); - contextuallyConvertedExprs_.pop_back(); - return true; - } - - bool TraverseBinLAnd(BinaryOperator* expr) - { - auto res = PreTraverseBinLAnd(expr); - assert(res); - res = FilteringRewritePlugin::TraverseBinLAnd(expr); - PostTraverseBinLAnd(expr, res); - return res; - } +#if CLANG_VERSION <= 110000 + bool TraverseUnaryLNot(UnaryOperator* expr) { return TraverseUnaryOperator(expr); } +#endif - bool PreTraverseBinLOr(BinaryOperator* expr) + bool PreTraverseBinaryOperator(BinaryOperator* expr) { - contextuallyConvertedExprs_.push_back(expr->getLHS()->IgnoreParenImpCasts()); - contextuallyConvertedExprs_.push_back(expr->getRHS()->IgnoreParenImpCasts()); + auto const op = expr->getOpcode(); + if (op == BO_LAnd || op == BO_LOr) + { + contextuallyConvertedExprs_.push_back(expr->getLHS()->IgnoreParenImpCasts()); + contextuallyConvertedExprs_.push_back(expr->getRHS()->IgnoreParenImpCasts()); + } return true; } - bool PostTraverseBinLOr(BinaryOperator*, bool) + bool PostTraverseBinaryOperator(BinaryOperator* expr, bool) { - assert(contextuallyConvertedExprs_.size() >= 2); - contextuallyConvertedExprs_.pop_back(); - contextuallyConvertedExprs_.pop_back(); + auto const op = expr->getOpcode(); + if (op == BO_LAnd || op == BO_LOr) + { + assert(contextuallyConvertedExprs_.size() >= 2); + contextuallyConvertedExprs_.pop_back(); + contextuallyConvertedExprs_.pop_back(); + } return true; } - bool TraverseBinLOr(BinaryOperator* expr) + bool TraverseBinaryOperator(BinaryOperator* expr) { - auto res = PreTraverseBinLOr(expr); + auto res = PreTraverseBinaryOperator(expr); assert(res); - res = FilteringRewritePlugin::TraverseBinLOr(expr); - PostTraverseBinLOr(expr, res); + res = FilteringRewritePlugin::TraverseBinaryOperator(expr); + PostTraverseBinaryOperator(expr, res); return res; } +#if CLANG_VERSION <= 110000 + bool TraverseBinLAnd(BinaryOperator* expr) { return TraverseBinaryOperator(expr); } + bool TraverseBinLOr(BinaryOperator* expr) { return TraverseBinaryOperator(expr); } +#endif + bool PreTraverseConditionalOperator(ConditionalOperator* expr) { contextuallyConvertedExprs_.push_back(expr->getCond()->IgnoreParenImpCasts()); @@ -452,6 +454,4 @@ loplugin::Plugin::Registration simplifypointertobool("sim } // namespace -#endif // LO_CLANG_SHARED_PLUGINS - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/compilerplugins/clang/test/implicitboolconversion.cxx b/compilerplugins/clang/test/implicitboolconversion.cxx index c438822d3b88..31082d1d378b 100644 --- a/compilerplugins/clang/test/implicitboolconversion.cxx +++ b/compilerplugins/clang/test/implicitboolconversion.cxx @@ -11,10 +11,16 @@ #include +#include + +bool g(); + void f() { // expected-error@+1 {{implicit conversion (IntegralCast) from 'bool' to 'int' [loplugin:implicitboolconversion]}} int i = false; + // expected-error@+1 {{implicit conversion (IntegralCast) from 'bool' to 'int' [loplugin:implicitboolconversion]}} + i = true; (void)i; std::atomic b = false; (void)b; @@ -23,6 +29,8 @@ void f() // expected-error-re@+1 {{implicit conversion (IntegralCast) from 'bool' to {{.+}} [loplugin:implicitboolconversion]}} std::atomic a = false; (void)a; + bool b2 = true; + b2 &= g(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ -- cgit