diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 79ae67210f2b47740d715207a1275f01cef8492d..79e317bb8caa29206e8db390ea2076ad02b29cca 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -147,21 +147,23 @@ static void DiagnoseTopLevelComparison(Sema &S, const Stmt *Statement) { } SourceLocation Loc; - bool IsNotEqual = false; + bool IsNotEqual, CanAssign; if (const BinaryOperator *Op = dyn_cast(E)) { if (Op->getOpcode() != BO_EQ && Op->getOpcode() != BO_NE) return; - IsNotEqual = Op->getOpcode() == BO_NE; Loc = Op->getOperatorLoc(); + IsNotEqual = Op->getOpcode() == BO_NE; + CanAssign = Op->getLHS()->IgnoreParenImpCasts()->isLValue(); } else if (const CXXOperatorCallExpr *Op = dyn_cast(E)) { if (Op->getOperator() != OO_EqualEqual && Op->getOperator() != OO_ExclaimEqual) return; - IsNotEqual = Op->getOperator() == OO_ExclaimEqual; Loc = Op->getOperatorLoc(); + IsNotEqual = Op->getOperator() == OO_ExclaimEqual; + CanAssign = Op->getArg(0)->IgnoreParenImpCasts()->isLValue(); } else { // Not a typo-prone comparison. return; @@ -181,12 +183,16 @@ static void DiagnoseTopLevelComparison(Sema &S, const Stmt *Statement) { << FixItHint::CreateInsertion(Open, "(void)(") << FixItHint::CreateInsertion(Close, ")"); - if (IsNotEqual) - S.Diag(Loc, diag::note_inequality_comparison_to_or_assign) - << FixItHint::CreateReplacement(Loc, "|="); - else - S.Diag(Loc, diag::note_equality_comparison_to_assign) - << FixItHint::CreateReplacement(Loc, "="); + // If the LHS is a plausible entity to assign to, provide a fixit hint to + // correct common typos. + if (CanAssign) { + if (IsNotEqual) + S.Diag(Loc, diag::note_inequality_comparison_to_or_assign) + << FixItHint::CreateReplacement(Loc, "|="); + else + S.Diag(Loc, diag::note_equality_comparison_to_assign) + << FixItHint::CreateReplacement(Loc, "="); + } } void Sema::DiagnoseUnusedExprResult(const Stmt *S) { diff --git a/clang/test/SemaCXX/warn-top-level-comparison.cpp b/clang/test/SemaCXX/warn-top-level-comparison.cpp index e298d2653b3bcabf8c1e2e712e428c28f593c6e6..dad21aeedc0889da116318631c587b8318f69a2e 100644 --- a/clang/test/SemaCXX/warn-top-level-comparison.cpp +++ b/clang/test/SemaCXX/warn-top-level-comparison.cpp @@ -17,6 +17,8 @@ void test() { x != 7; // expected-warning {{inequality comparison as an unused top-level statement}} \ // expected-note {{cast this comparison to void to silence this warning}} \ // expected-note {{use '|=' to turn this inequality comparison into an or-assignment}} + 7 == x; // expected-warning {{equality comparison as an unused top-level statement}} \ + // expected-note {{cast this comparison to void to silence this warning}} p == p; // expected-warning {{equality comparison as an unused top-level statement}} \ // expected-note {{cast this comparison to void to silence this warning}} \ // expected-note {{use '=' to turn this equality comparison into an assignment}} \ @@ -30,6 +32,8 @@ void test() { a != b; // expected-warning {{inequality comparison as an unused top-level statement}} \ // expected-note {{cast this comparison to void to silence this warning}} \ // expected-note {{use '|=' to turn this inequality comparison into an or-assignment}} + A() == b; // expected-warning {{equality comparison as an unused top-level statement}} \ + // expected-note {{cast this comparison to void to silence this warning}} if (42) x == 7; // expected-warning {{equality comparison as an unused top-level statement}} \ // expected-note {{cast this comparison to void to silence this warning}} \ // expected-note {{use '=' to turn this equality comparison into an assignment}}