diff options
| author | Richard Trieu <rtrieu@google.com> | 2013-04-17 02:12:45 +0000 |
|---|---|---|
| committer | Richard Trieu <rtrieu@google.com> | 2013-04-17 02:12:45 +0000 |
| commit | fe042e6aab263e0d9ff1556b8a27bc12d069ef58 (patch) | |
| tree | 76eb35b54a598ed8691abc52410d06bc0a5c904f /clang/lib/Sema/SemaExpr.cpp | |
| parent | 37ae72b508d7f8974c143f017c01f6c27dc6805c (diff) | |
| download | bcm5719-llvm-fe042e6aab263e0d9ff1556b8a27bc12d069ef58.tar.gz bcm5719-llvm-fe042e6aab263e0d9ff1556b8a27bc12d069ef58.zip | |
Add warning group -Woverloaded-shift-op-parentheses to -Wparentheses. This
will fire on code such as:
cout << x == 0;
which the compiler will intrepret as
(cout << x) == 0;
This warning comes with two fixits attached to notes, one for parentheses to
silence the warning, and another to evaluate the comparison first.
llvm-svn: 179662
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index cdfdc09e06e..ce60f9171fd 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -8877,6 +8877,33 @@ static void DiagnoseAdditionInShift(Sema &S, SourceLocation OpLoc, } } +static void DiagnoseShiftCompare(Sema &S, SourceLocation OpLoc, + Expr *LHSExpr, Expr *RHSExpr) { + CXXOperatorCallExpr *OCE = dyn_cast<CXXOperatorCallExpr>(LHSExpr); + if (!OCE) + return; + + FunctionDecl *FD = OCE->getDirectCallee(); + if (!FD || !FD->isOverloadedOperator()) + return; + + OverloadedOperatorKind Kind = FD->getOverloadedOperator(); + if (Kind != OO_LessLess && Kind != OO_GreaterGreater) + return; + + S.Diag(OpLoc, diag::warn_overloaded_shift_in_comparison) + << LHSExpr->getSourceRange() << RHSExpr->getSourceRange() + << (Kind == OO_LessLess); + SuggestParentheses(S, OpLoc, + S.PDiag(diag::note_evaluate_comparison_first), + SourceRange(OCE->getArg(1)->getLocStart(), + RHSExpr->getLocEnd())); + SuggestParentheses(S, OCE->getOperatorLoc(), + S.PDiag(diag::note_precedence_silence) + << (Kind == OO_LessLess ? "<<" : ">>"), + OCE->getSourceRange()); +} + /// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky /// precedence. static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc, @@ -8905,6 +8932,11 @@ static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc, DiagnoseAdditionInShift(Self, OpLoc, LHSExpr, Shift); DiagnoseAdditionInShift(Self, OpLoc, RHSExpr, Shift); } + + // Warn on overloaded shift operators and comparisons, such as: + // cout << 5 == 4; + if (BinaryOperator::isComparisonOp(Opc)) + DiagnoseShiftCompare(Self, OpLoc, LHSExpr, RHSExpr); } // Binary Operators. 'Tok' is the token for the operator. |

