diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-06-20 18:41:26 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-06-20 18:41:26 +0000 |
commit | 33f46e22b7fc3b75c34b6d892790f80869da0300 (patch) | |
tree | 36c009cb54f08ca828452ead6c51861ca51cbfaa /lib/Sema/SemaExpr.cpp | |
parent | ab27d6ea7b4ce2762a16905281de796db32bb6f2 (diff) |
Warn for un-parenthesized '&' inside '|' (a & b | c), rdar://9553326.
Patch by Henry Mason with tweaks by me.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133453 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index a00877622d..21b3468ab3 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9147,6 +9147,20 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc, } } +/// \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_bitwise_and_in_bitwise_or_silence), + 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. @@ -9212,13 +9226,28 @@ 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); + } +} + /// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky /// precedence. static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc, SourceLocation OpLoc, Expr *lhs, Expr *rhs){ // Diagnose "arg1 'bitwise' arg2 'eq' arg3". if (BinaryOperator::isBitwiseOp(Opc)) - return DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs); + DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs); + + // Diagnose "arg1 & arg2 | arg3" + if (Opc == BO_Or && !OpLoc.isMacroID()/* Don't warn in macros. */) { + DiagnoseBitwiseAndInBitwiseOr(Self, OpLoc, lhs); + DiagnoseBitwiseAndInBitwiseOr(Self, OpLoc, rhs); + } // Warn about arg1 || arg2 && arg3, as GCC 4.3+ does. // We don't warn for 'assert(a || b && "bad")' since this is safe. |