diff options
author | Craig Topper <craig.topper@gmail.com> | 2015-12-13 05:41:41 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2015-12-13 05:41:41 +0000 |
commit | 84543b09cb2886e89a34c54637fea923ba3c27d3 (patch) | |
tree | a6f86612a090d328c4a7b3900270fa56f2327868 /clang/lib/Sema | |
parent | b0dfa7a79aa6629d8de9be9da45aab4a8d2eb781 (diff) | |
download | bcm5719-llvm-84543b09cb2886e89a34c54637fea923ba3c27d3.tar.gz bcm5719-llvm-84543b09cb2886e89a34c54637fea923ba3c27d3.zip |
[Sema] Add -Wparentheses warnings for '^' in '|' expressions and '&' in '^' expressions to compliment '&' in '|' that is already present. Matches gcc behavior.
llvm-svn: 255450
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 43 |
1 files changed, 19 insertions, 24 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 1b3f8dab3f3..b8cb50c9aee 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -10504,21 +10504,6 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc, ParensRange); } -/// \brief It accepts a '&' expr that is inside a '|' one. -/// Emit a diagnostic together with a fixit hint that wraps the '&' expression -/// in parentheses. -static void -EmitDiagnosticForBitwiseAndInBitwiseOr(Sema &Self, SourceLocation OpLoc, - BinaryOperator *Bop) { - assert(Bop->getOpcode() == BO_And); - Self.Diag(Bop->getOperatorLoc(), diag::warn_bitwise_and_in_bitwise_or) - << Bop->getSourceRange() << OpLoc; - SuggestParentheses(Self, Bop->getOperatorLoc(), - Self.PDiag(diag::note_precedence_silence) - << Bop->getOpcodeStr(), - Bop->getSourceRange()); -} - /// \brief It accepts a '&&' expr that is inside a '||' one. /// Emit a diagnostic together with a fixit hint that wraps the '&&' expression /// in parentheses. @@ -10587,12 +10572,21 @@ static void DiagnoseLogicalAndInLogicalOrRHS(Sema &S, SourceLocation OpLoc, } } -/// \brief Look for '&' in the left or right hand of a '|' expr. -static void DiagnoseBitwiseAndInBitwiseOr(Sema &S, SourceLocation OpLoc, - Expr *OrArg) { - if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(OrArg)) { - if (Bop->getOpcode() == BO_And) - return EmitDiagnosticForBitwiseAndInBitwiseOr(S, OpLoc, Bop); +/// \brief Look for bitwise op in the left or right hand of a bitwise op with +/// lower precedence and emit a diagnostic together with a fixit hint that wraps +/// the '&' expression in parentheses. +static void DiagnoseBitwiseOpInBitwiseOp(Sema &S, BinaryOperatorKind Opc, + SourceLocation OpLoc, Expr *SubExpr) { + if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(SubExpr)) { + if (Bop->isBitwiseOp() && Bop->getOpcode() < Opc) { + S.Diag(Bop->getOperatorLoc(), diag::warn_bitwise_op_in_bitwise_op) + << Bop->getOpcodeStr() << BinaryOperator::getOpcodeStr(Opc) + << Bop->getSourceRange() << OpLoc; + SuggestParentheses(S, Bop->getOperatorLoc(), + S.PDiag(diag::note_precedence_silence) + << Bop->getOpcodeStr(), + Bop->getSourceRange()); + } } } @@ -10647,9 +10641,10 @@ static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc, DiagnoseBitwisePrecedence(Self, Opc, OpLoc, LHSExpr, RHSExpr); // Diagnose "arg1 & arg2 | arg3" - if (Opc == BO_Or && !OpLoc.isMacroID()/* Don't warn in macros. */) { - DiagnoseBitwiseAndInBitwiseOr(Self, OpLoc, LHSExpr); - DiagnoseBitwiseAndInBitwiseOr(Self, OpLoc, RHSExpr); + if ((Opc == BO_Or || Opc == BO_Xor) && + !OpLoc.isMacroID()/* Don't warn in macros. */) { + DiagnoseBitwiseOpInBitwiseOp(Self, Opc, OpLoc, LHSExpr); + DiagnoseBitwiseOpInBitwiseOp(Self, Opc, OpLoc, RHSExpr); } // Warn about arg1 || arg2 && arg3, as GCC 4.3+ does. |