Add -Wcomma warning to Clang.
-Wcomma will detect and warn on most uses of the builtin comma operator. It
currently whitelists the first and third statements of the for-loop. For other
cases, the warning can be silenced by casting the first operand of the comma
operator to void.
Differential Revision: http://reviews.llvm.org/D3976
llvm-svn: 261278
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 350f16d..c58bf46 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -488,6 +488,20 @@
return LS;
}
+namespace {
+class CommaVisitor : public EvaluatedExprVisitor<CommaVisitor> {
+ typedef EvaluatedExprVisitor<CommaVisitor> Inherited;
+ Sema &SemaRef;
+public:
+ CommaVisitor(Sema &SemaRef) : Inherited(SemaRef.Context), SemaRef(SemaRef) {}
+ void VisitBinaryOperator(BinaryOperator *E) {
+ if (E->getOpcode() == BO_Comma)
+ SemaRef.DiagnoseCommaOperator(E->getLHS(), E->getExprLoc());
+ EvaluatedExprVisitor<CommaVisitor>::VisitBinaryOperator(E);
+ }
+};
+}
+
StmtResult
Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
Stmt *thenStmt, SourceLocation ElseLoc,
@@ -502,6 +516,11 @@
}
Expr *ConditionExpr = CondResult.getAs<Expr>();
if (ConditionExpr) {
+
+ if (!Diags.isIgnored(diag::warn_comma_operator,
+ ConditionExpr->getExprLoc()))
+ CommaVisitor(*this).Visit(ConditionExpr);
+
DiagnoseUnusedExprResult(thenStmt);
if (!elseStmt) {
@@ -1240,6 +1259,10 @@
return StmtError();
CheckBreakContinueBinding(ConditionExpr);
+ if (ConditionExpr &&
+ !Diags.isIgnored(diag::warn_comma_operator, ConditionExpr->getExprLoc()))
+ CommaVisitor(*this).Visit(ConditionExpr);
+
DiagnoseUnusedExprResult(Body);
if (isa<NullStmt>(Body))
@@ -1642,6 +1665,11 @@
return StmtError();
}
+ if (SecondResult.get() &&
+ !Diags.isIgnored(diag::warn_comma_operator,
+ SecondResult.get()->getExprLoc()))
+ CommaVisitor(*this).Visit(SecondResult.get());
+
Expr *Third = third.release().getAs<Expr>();
DiagnoseUnusedExprResult(First);