summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/unnecessaryparen.cxx32
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))