aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-19 16:50:08 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-19 16:50:08 +0000
commit92c3a04f3ec683f279814b0eb6d6271b3fd3a219 (patch)
tree8aa282a17c24cd6659392c07d93b76226de96dae
parent9ea416e598fa3cb09d67d514c4519c99abb81321 (diff)
Warn about the use of unparenthesized |= in conditionals (which may be
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
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaExpr.cpp20
-rw-r--r--test/SemaCXX/warn-assignment-condition.cpp10
3 files changed, 27 insertions, 5 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 1c1600a735..870a0e0205 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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">;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index deb0bb2b6c..e84e0e11fb 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -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, ")");
diff --git a/test/SemaCXX/warn-assignment-condition.cpp b/test/SemaCXX/warn-assignment-condition.cpp
index e5a3425804..9dcffbfe84 100644
--- a/test/SemaCXX/warn-assignment-condition.cpp
+++ b/test/SemaCXX/warn-assignment-condition.cpp
@@ -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}}
}