[cfe-commits] r123836 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/SemaCXX/warn-assignment-condition.cpp

Douglas Gregor dgregor at apple.com
Wed Jan 19 08:50:08 PST 2011


Author: dgregor
Date: Wed Jan 19 10:50:08 2011
New Revision: 123836

URL: http://llvm.org/viewvc/llvm-project?rev=123836&view=rev
Log:
Warn about the use of unparenthesized |= in conditionals (which may be
a typo for !=). Fixes PR9001, from Hans Wennborg!

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

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=123836&r1=123835&r2=123836&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jan 19 10:50:08 2011
@@ -2796,6 +2796,8 @@
   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">;
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=123836&r1=123835&r2=123836&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Jan 19 10:50:08 2011
@@ -9118,18 +9118,21 @@
   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 @@
     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 @@
   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, ")");

Modified: cfe/trunk/test/SemaCXX/warn-assignment-condition.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-assignment-condition.cpp?rev=123836&r1=123835&r2=123836&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-assignment-condition.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-assignment-condition.cpp Wed Jan 19 10:50:08 2011
@@ -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 @@
                 // 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}}
 }





More information about the cfe-commits mailing list