Author: ctopper Date: Sat Dec 12 23:41:41 2015 New Revision: 255450 URL: http://llvm.org/viewvc/llvm-project?rev=255450&view=rev Log: [Sema] Add -Wparentheses warnings for '^' in '|' expressions and '&' in '^' expressions to compliment '&' in '|' that is already present. Matches gcc behavior.
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/test/Sema/parentheses.c Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=255450&r1=255449&r2=255450&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Dec 12 23:41:41 2015 @@ -4977,8 +4977,8 @@ def note_logical_instead_of_bitwise_chan def note_logical_instead_of_bitwise_remove_constant : Note< "remove constant to silence this warning">; -def warn_bitwise_and_in_bitwise_or : Warning< - "'&' within '|'">, InGroup<BitwiseOpParentheses>; +def warn_bitwise_op_in_bitwise_op : Warning< + "'%0' within '%1'">, InGroup<BitwiseOpParentheses>; def warn_logical_and_in_logical_or : Warning< "'&&' within '||'">, InGroup<LogicalOpParentheses>; Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=255450&r1=255449&r2=255450&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Dec 12 23:41:41 2015 @@ -10504,21 +10504,6 @@ static void DiagnoseBitwisePrecedence(Se 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 DiagnoseLogicalAndInLogicalO } } -/// \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 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. Modified: cfe/trunk/test/Sema/parentheses.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/parentheses.c?rev=255450&r1=255449&r2=255450&view=diff ============================================================================== --- cfe/trunk/test/Sema/parentheses.c (original) +++ cfe/trunk/test/Sema/parentheses.c Sat Dec 12 23:41:41 2015 @@ -55,6 +55,26 @@ void bitwise_rel(unsigned i) { // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:14-[[@LINE-2]]:14}:"(" // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:19-[[@LINE-3]]:19}:")" + (void)(i ^ i | i); // expected-warning {{'^' within '|'}} \ + // expected-note {{place parentheses around the '^' expression to silence this warning}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:15-[[@LINE-3]]:15}:")" + + (void)(i | i ^ i); // expected-warning {{'^' within '|'}} \ + // expected-note {{place parentheses around the '^' expression to silence this warning}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:14-[[@LINE-2]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:19-[[@LINE-3]]:19}:")" + + (void)(i & i ^ i); // expected-warning {{'&' within '^'}} \ + // expected-note {{place parentheses around the '&' expression to silence this warning}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:10}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:15-[[@LINE-3]]:15}:")" + + (void)(i ^ i & i); // expected-warning {{'&' within '^'}} \ + // expected-note {{place parentheses around the '&' expression to silence this warning}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:14-[[@LINE-2]]:14}:"(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:19-[[@LINE-3]]:19}:")" + (void)(i || i && i); // expected-warning {{'&&' within '||'}} \ // expected-note {{place parentheses around the '&&' expression to silence this warning}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits