diff options
Diffstat (limited to 'compilerplugins/clang')
-rw-r--r-- | compilerplugins/clang/test/unnecessaryparen.cxx | 12 | ||||
-rw-r--r-- | compilerplugins/clang/unnecessaryparen.cxx | 19 |
2 files changed, 28 insertions, 3 deletions
diff --git a/compilerplugins/clang/test/unnecessaryparen.cxx b/compilerplugins/clang/test/unnecessaryparen.cxx index 968522d63a73..4e85fe97076f 100644 --- a/compilerplugins/clang/test/unnecessaryparen.cxx +++ b/compilerplugins/clang/test/unnecessaryparen.cxx @@ -14,6 +14,8 @@ bool foo(int); enum class EFoo { Bar }; +struct S { operator bool(); }; + int main() { int x = 1; @@ -49,6 +51,16 @@ int main() std::string v3; v3 = (std::string("xx") + "xx"); // expected-error {{parentheses immediately inside assignment [loplugin:unnecessaryparen]}} (void)v3; + + S s1; + if ((s1)) { // expected-error {{parentheses immediately inside if statement [loplugin:unnecessaryparen]}} + // expected-error@-1 {{unnecessary parentheses around identifier [loplugin:unnecessaryparen]}} + return 0; + } + S s2; + if ((s2 = s1)) { + return 0; + } }; /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/compilerplugins/clang/unnecessaryparen.cxx b/compilerplugins/clang/unnecessaryparen.cxx index fdc83410cb0e..a7d3d26e6591 100644 --- a/compilerplugins/clang/unnecessaryparen.cxx +++ b/compilerplugins/clang/unnecessaryparen.cxx @@ -23,8 +23,8 @@ look for unnecessary parentheses namespace { -// Like clang::Stmt::IgnoreImplicit (lib/AST/Stmt.cpp), but also ignoring -// CXXConstructExpr: +// Like clang::Stmt::IgnoreImplicit (lib/AST/Stmt.cpp), but also ignoring CXXConstructExpr and +// 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(); @@ -40,7 +40,15 @@ Expr const * ignoreAllImplicit(Expr const * expr) { if (auto const e = dyn_cast<CXXBindTemporaryExpr>(expr)) { expr = e->getSubExpr(); } - return expr->IgnoreImpCasts(); + 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; } class UnnecessaryParen: @@ -239,6 +247,11 @@ void UnnecessaryParen::VisitSomeStmt(const Stmt * stmt, const Expr* cond, String auto binaryOp = dyn_cast<BinaryOperator>(parenExpr->getSubExpr()); if (binaryOp && binaryOp->getOpcode() == BO_Assign) return; + if (auto const opCall = dyn_cast<CXXOperatorCallExpr>(parenExpr->getSubExpr())) { + if (opCall->getOperator() == OO_Equal) { + return; + } + } report( DiagnosticsEngine::Warning, "parentheses immediately inside %0 statement", parenExpr->getLocStart()) |