]> granicus.if.org Git - clang/commitdiff
Warn about arg1 && arg2 || arg3, as GCC 4.3+ does. Fixes rdar://8659922
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 16 Nov 2010 21:00:12 +0000 (21:00 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 16 Nov 2010 21:00:12 +0000 (21:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119381 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/Sema/parentheses.c

index 55109d089beff7508606fa0686cd9a1a293ed242..4c8325621fb1f54917791ac466205116c3321677 100644 (file)
@@ -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<DiagGroup<"constant-logical-operand">>;
-  
+
+def warn_logical_and_in_logical_or : Warning<
+  "'&&' within '||'">, InGroup<Parentheses>;
+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">;
index 7555af375f7a51a5c5bfe1512a39c24fa7219752..80ee2963a7212301ebb85bc86fc98cb81e50e72a 100644 (file)
@@ -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<BinaryOperator>(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.
index e53f0eb99bc1b572855170424c08bb248f59b1d1..a219c9b342ddabf8f01148fdcc37f731fe8faa98 100644 (file)
@@ -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}}
 }