diff options
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/unnecessaryparen.cxx | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/compilerplugins/clang/unnecessaryparen.cxx b/compilerplugins/clang/unnecessaryparen.cxx index 4abfd69e3b7c..1e01c41d5893 100644 --- a/compilerplugins/clang/unnecessaryparen.cxx +++ b/compilerplugins/clang/unnecessaryparen.cxx @@ -55,6 +55,7 @@ public: bool VisitDoStmt(const DoStmt *); bool VisitWhileStmt(const WhileStmt *); bool VisitSwitchStmt(const SwitchStmt *); + bool VisitReturnStmt(const ReturnStmt* ); bool VisitCallExpr(const CallExpr *); bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *); bool TraverseCaseStmt(CaseStmt *); @@ -162,6 +163,37 @@ bool UnnecessaryParen::VisitSwitchStmt(const SwitchStmt* switchStmt) return true; } +bool UnnecessaryParen::VisitReturnStmt(const ReturnStmt* returnStmt) +{ + if (ignoreLocation(returnStmt)) + return true; + if (returnStmt->getLocStart().isMacroID()) + return true; + + if (!returnStmt->getRetValue()) + return true; + auto parenExpr = dyn_cast<ParenExpr>(returnStmt->getRetValue()->IgnoreImpCasts()); + if (!parenExpr) + return true; + if (parenExpr->getLocStart().isMacroID()) + return true; + // assignments need extra parentheses or they generate a compiler warning + auto binaryOp = dyn_cast<BinaryOperator>(parenExpr->getSubExpr()); + if (binaryOp && binaryOp->getOpcode() == BO_Assign) + return true; + + // only non-operator-calls for now + auto subExpr = parenExpr->getSubExpr(); + if (isa<CallExpr>(subExpr) && !isa<CXXOperatorCallExpr>(subExpr)) + { + report( + DiagnosticsEngine::Warning, "parentheses immediately inside return statement", + parenExpr->getLocStart()) + << parenExpr->getSourceRange(); + } + return true; +} + void UnnecessaryParen::VisitSomeStmt(const Stmt *parent, const Expr* cond, StringRef stmtName) { if (ignoreLocation(parent)) |