Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -62,8 +62,9 @@ - ``-Wself-assign`` and ``-Wself-assign-field`` were extended to diagnose self-assignment operations using overloaded operators (i.e. classes). If you are doing such an assignment intentionally, e.g. in a unit test for - a data structure, the warning can be suppressed by adding ``*&`` to the - right-hand side or casting it to the appropriate reference type. + a data structure, the first warning can be disabled by passing + ``-Wno-self-assign-overloaded``, also the warning can be suppressed by adding + ``*&`` to the right-hand side or casting it to the appropriate reference type. Non-comprehensive list of changes in this release ------------------------------------------------- Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -404,7 +404,8 @@ def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy", [CXX98CompatBindToTemporaryCopy]>; def SelfAssignmentField : DiagGroup<"self-assign-field">; -def SelfAssignment : DiagGroup<"self-assign", [SelfAssignmentField]>; +def SelfAssignmentOverloaded : DiagGroup<"self-assign-overloaded">; +def SelfAssignment : DiagGroup<"self-assign", [SelfAssignmentOverloaded, SelfAssignmentField]>; def SelfMove : DiagGroup<"self-move">; def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">; def Sentinel : DiagGroup<"sentinel">; Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -5612,9 +5612,12 @@ "operator '%0' has lower precedence than '%1'; " "'%1' will be evaluated first">, InGroup; -def warn_self_assignment : Warning< +def warn_self_assignment_builtin : Warning< "explicitly assigning value of variable of type %0 to itself">, InGroup, DefaultIgnore; +def warn_self_assignment_overloaded : Warning< + "explicitly assigning value of variable of type %0 to itself">, + InGroup, DefaultIgnore; def warn_self_move : Warning< "explicitly moving variable of type %0 to itself">, InGroup, DefaultIgnore; Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -11497,7 +11497,7 @@ /// DiagnoseSelfAssignment - Emits a warning if a value is assigned to itself. /// This warning suppressed in the event of macro expansions. static void DiagnoseSelfAssignment(Sema &S, Expr *LHSExpr, Expr *RHSExpr, - SourceLocation OpLoc) { + SourceLocation OpLoc, bool IsBuiltin) { if (S.inTemplateInstantiation()) return; if (S.isUnevaluatedContext()) @@ -11524,9 +11524,10 @@ if (RefTy->getPointeeType().isVolatileQualified()) return; - S.Diag(OpLoc, diag::warn_self_assignment) - << LHSDeclRef->getType() - << LHSExpr->getSourceRange() << RHSExpr->getSourceRange(); + S.Diag(OpLoc, IsBuiltin ? diag::warn_self_assignment_builtin + : diag::warn_self_assignment_overloaded) + << LHSDeclRef->getType() << LHSExpr->getSourceRange() + << RHSExpr->getSourceRange(); } /// Check if a bitwise-& is performed on an Objective-C pointer. This @@ -11719,7 +11720,7 @@ OK = LHS.get()->getObjectKind(); } if (!ResultTy.isNull()) { - DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc); + DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc, true); DiagnoseSelfMove(LHS.get(), RHS.get(), OpLoc); } RecordModifiableNonNullParam(*this, LHS.get()); @@ -11817,7 +11818,7 @@ break; case BO_AndAssign: case BO_OrAssign: // fallthrough - DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc); + DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc, true); LLVM_FALLTHROUGH; case BO_XorAssign: CompResultTy = CheckBitwiseOperands(LHS, RHS, OpLoc, Opc); @@ -12124,7 +12125,7 @@ case BO_AndAssign: case BO_OrAssign: case BO_XorAssign: - DiagnoseSelfAssignment(S, LHS, RHS, OpLoc); + DiagnoseSelfAssignment(S, LHS, RHS, OpLoc, false); CheckIdentityFieldAssignment(LHS, RHS, OpLoc, S); break; default: Index: test/SemaCXX/warn-self-assign-overloaded.cpp =================================================================== --- test/SemaCXX/warn-self-assign-overloaded.cpp +++ test/SemaCXX/warn-self-assign-overloaded.cpp @@ -4,6 +4,12 @@ // RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV2 -verify %s // RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV3 -verify %s // RUN: %clang_cc1 -fsyntax-only -Wself-assign -DV4 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DDUMMY -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV0 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV1 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV2 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV3 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-self-assign -Wself-assign-overloaded -DV4 -verify %s #ifdef DUMMY struct S {};