From: Argyrios Kyrtzidis Date: Tue, 16 Nov 2010 21:00:12 +0000 (+0000) Subject: Warn about arg1 && arg2 || arg3, as GCC 4.3+ does. Fixes rdar://8659922 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bee77f75358a5aaf2e2e01ab9cfd37ffc514ed7a;p=clang Warn about arg1 && arg2 || arg3, as GCC 4.3+ does. Fixes rdar://8659922 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119381 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 55109d089b..4c8325621f 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2156,7 +2156,12 @@ def note_precedence_bitwise_silence : Note< def warn_logical_instead_of_bitwise : Warning< "use of logical %0 with constant operand; switch to bitwise %1 or " "remove constant">, InGroup>; - + +def warn_logical_and_in_logical_or : Warning< + "'&&' within '||'">, InGroup; +def note_logical_and_in_logical_or_silence : Note< + "place parentheses around the '&&' expression to silence this warning">; + def err_sizeof_nonfragile_interface : Error< "invalid application of '%select{alignof|sizeof}1' to interface %0 in " "non-fragile ABI">; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 7555af375f..80ee2963a7 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -7329,13 +7329,33 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc, rhs->getSourceRange()); } +static void DiagnoseLogicalAndInLogicalOr(Sema &Self, SourceLocation OpLoc, + Expr *E) { + if (BinaryOperator *Bop = dyn_cast(E)) { + if (Bop->getOpcode() == BO_LAnd) { + SuggestParentheses(Self, OpLoc, + Self.PDiag(diag::warn_logical_and_in_logical_or) + << E->getSourceRange(), + Self.PDiag(diag::note_logical_and_in_logical_or_silence), + E->getSourceRange(), + Self.PDiag(0), SourceRange()); + } + } +} + /// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky -/// precedence. This currently diagnoses only "arg1 'bitwise' arg2 'eq' arg3". -/// But it could also warn about arg1 && arg2 || arg3, as GCC 4.3+ does. +/// precedence. static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc, SourceLocation OpLoc, Expr *lhs, Expr *rhs){ + // Diagnose "arg1 'bitwise' arg2 'eq' arg3". if (BinaryOperator::isBitwiseOp(Opc)) - DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs); + return DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs); + + /// Warn about arg1 && arg2 || arg3, as GCC 4.3+ does. + if (Opc == BO_LOr) { + DiagnoseLogicalAndInLogicalOr(Self, OpLoc, lhs); + DiagnoseLogicalAndInLogicalOr(Self, OpLoc, rhs); + } } // Binary Operators. 'Tok' is the token for the operator. diff --git a/test/Sema/parentheses.c b/test/Sema/parentheses.c index e53f0eb99b..a219c9b342 100644 --- a/test/Sema/parentheses.c +++ b/test/Sema/parentheses.c @@ -25,4 +25,7 @@ void bitwise_rel(unsigned i) { // Eager logical op (void)(i == 1 | i == 2 | i == 3); (void)(i != 1 & i != 2 & i != 3); + + (void)(i || i && i); // expected-warning {{'&&' within '||'}} \ + // expected-note {{place parentheses around the '&&' expression to silence this warning}} }