]> granicus.if.org Git - clang/commitdiff
Warn about the use of unparenthesized |= in conditionals (which may be
authorDouglas Gregor <dgregor@apple.com>
Wed, 19 Jan 2011 16:50:08 +0000 (16:50 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 19 Jan 2011 16:50:08 +0000 (16:50 +0000)
a typo for !=). Fixes PR9001, from Hans Wennborg!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123836 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/SemaCXX/warn-assignment-condition.cpp

index 1c1600a735de5c314a30131edaa90103df6a6200..870a0e0205c2c370a9141b65562e748fcfbdd2e7 100644 (file)
@@ -2796,6 +2796,8 @@ def warn_condition_is_idiomatic_assignment : Warning<"using the result "
   InGroup<DiagGroup<"idiomatic-parentheses">>, DefaultIgnore;
 def note_condition_assign_to_comparison : Note<
   "use '==' to turn this assignment into an equality comparison">;
+def note_condition_or_assign_to_comparison : Note<
+  "use '!=' to turn this compound assignment into an inequality comparison">;
 def note_condition_assign_silence : Note<
   "place parentheses around the assignment to silence this warning">;
 
index deb0bb2b6c233235738db6e33f58d335718ef95e..e84e0e11fb9913ac76c5d1c4ca49c9e692ba129e 100644 (file)
@@ -9118,18 +9118,21 @@ bool Sema::CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
   return false;
 }
 
-// Diagnose the common s/=/==/ typo.  Note that adding parentheses
+// Diagnose the s/=/==/ and s/\|=/!=/ typos. Note that adding parentheses
 // will prevent this condition from triggering, which is what we want.
 void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
   SourceLocation Loc;
 
   unsigned diagnostic = diag::warn_condition_is_assignment;
+  bool IsOrAssign = false;
 
   if (isa<BinaryOperator>(E)) {
     BinaryOperator *Op = cast<BinaryOperator>(E);
-    if (Op->getOpcode() != BO_Assign)
+    if (Op->getOpcode() != BO_Assign && Op->getOpcode() != BO_OrAssign)
       return;
 
+    IsOrAssign = Op->getOpcode() == BO_OrAssign;
+
     // Greylist some idioms by putting them into a warning subcategory.
     if (ObjCMessageExpr *ME
           = dyn_cast<ObjCMessageExpr>(Op->getRHS()->IgnoreParenCasts())) {
@@ -9149,9 +9152,10 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
     Loc = Op->getOperatorLoc();
   } else if (isa<CXXOperatorCallExpr>(E)) {
     CXXOperatorCallExpr *Op = cast<CXXOperatorCallExpr>(E);
-    if (Op->getOperator() != OO_Equal)
+    if (Op->getOperator() != OO_Equal && Op->getOperator() != OO_PipeEqual)
       return;
 
+    IsOrAssign = Op->getOperator() == OO_PipeEqual;
     Loc = Op->getOperatorLoc();
   } else {
     // Not an assignment.
@@ -9162,8 +9166,14 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
   SourceLocation Close = PP.getLocForEndOfToken(E->getSourceRange().getEnd());
 
   Diag(Loc, diagnostic) << E->getSourceRange();
-  Diag(Loc, diag::note_condition_assign_to_comparison)
-    << FixItHint::CreateReplacement(Loc, "==");
+
+  if (IsOrAssign)
+    Diag(Loc, diag::note_condition_or_assign_to_comparison)
+      << FixItHint::CreateReplacement(Loc, "!=");
+  else
+    Diag(Loc, diag::note_condition_assign_to_comparison)
+      << FixItHint::CreateReplacement(Loc, "==");
+
   Diag(Loc, diag::note_condition_assign_silence)
     << FixItHint::CreateInsertion(Open, "(")
     << FixItHint::CreateInsertion(Close, ")");
index e5a3425804b898ce7df1138e2447845b65184518..9dcffbfe84e8cd48cb8176b1739b19ab824f7996 100644 (file)
@@ -3,6 +3,7 @@
 struct A {
   int foo();
   friend A operator+(const A&, const A&);
+  A operator|=(const A&);
   operator bool();
 };
 
@@ -95,4 +96,13 @@ void test() {
                 // expected-note{{use '==' to turn this assignment into an equality comparison}} \
   // expected-note{{place parentheses around the assignment to silence this warning}}
   for (; (a = b + b); ) {}
+
+  // Compound assignments.
+  if (x |= 2) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '!=' to turn this compound assignment into an inequality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
+
+  if (a |= b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                // expected-note{{use '!=' to turn this compound assignment into an inequality comparison}} \
+  // expected-note{{place parentheses around the assignment to silence this warning}}
 }