From c5302325b2a62d77cf13dd16cd5c19141862fed0 Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Fri, 7 Apr 2023 11:34:56 -0400 Subject: [PATCH] [clang:diagnostics] Turning off warn_self_assignment_overloaded for user-defined compound assignments Fixes 42469 https://github.com/llvm/llvm-project/issues/42469 Only check self assignment on BO_Assign when BuildOverloadedBinOp. --- clang/lib/Sema/SemaExpr.cpp | 11 ++++++++++- clang/test/SemaCXX/warn-self-assign-overloaded.cpp | 12 ++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 351db6d..86a4cbf 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -15657,13 +15657,22 @@ static ExprResult BuildOverloadedBinOp(Sema &S, Scope *Sc, SourceLocation OpLoc, Expr *LHS, Expr *RHS) { switch (Opc) { case BO_Assign: + // In the non-overloaded case, we warn about self-assignment (x = x) for + // both simple assignment and certain compound assignments where algebra + // tells us the operation yields a constant result. When the operator is + // overloaded, we can't do the latter because we don't want to assume that + // those algebraic identities still apply; for example, a path-building + // library might use operator/= to append paths. But it's still reasonable + // to assume that simple assignment is just moving/copying values around + // and so self-assignment is likely a bug. + DiagnoseSelfAssignment(S, LHS, RHS, OpLoc, false); + [[fallthrough]]; case BO_DivAssign: case BO_RemAssign: case BO_SubAssign: case BO_AndAssign: case BO_OrAssign: case BO_XorAssign: - DiagnoseSelfAssignment(S, LHS, RHS, OpLoc, false); CheckIdentityFieldAssignment(LHS, RHS, OpLoc, S); break; default: diff --git a/clang/test/SemaCXX/warn-self-assign-overloaded.cpp b/clang/test/SemaCXX/warn-self-assign-overloaded.cpp index b27f4c8..428797a 100644 --- a/clang/test/SemaCXX/warn-self-assign-overloaded.cpp +++ b/clang/test/SemaCXX/warn-self-assign-overloaded.cpp @@ -53,15 +53,15 @@ void f() { #ifndef DUMMY a *= a; - a /= a; // expected-warning {{explicitly assigning}} - a %= a; // expected-warning {{explicitly assigning}} + a /= a; + a %= a; a += a; - a -= a; // expected-warning {{explicitly assigning}} + a -= a; a <<= a; a >>= a; - a &= a; // expected-warning {{explicitly assigning}} - a |= a; // expected-warning {{explicitly assigning}} - a ^= a; // expected-warning {{explicitly assigning}} + a &= a; + a |= a; + a ^= a; #endif } -- 2.7.4