Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -109,6 +109,7 @@ DiagGroup<"c++11-compat-deprecated-writable-strings">; def DeprecatedAttributes : DiagGroup<"deprecated-attributes">; +def DeprecatedCopy : DiagGroup<"deprecated-copy">; def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">; def UnavailableDeclarations : DiagGroup<"unavailable-declarations">; def UnguardedAvailabilityNew : DiagGroup<"unguarded-availability-new">; @@ -126,6 +127,7 @@ [CXX11CompatDeprecatedWritableStr]>; // FIXME: Why is DeprecatedImplementations not in this group? def Deprecated : DiagGroup<"deprecated", [DeprecatedAttributes, + DeprecatedCopy, DeprecatedDeclarations, DeprecatedDynamicExceptionSpec, DeprecatedIncrementBool, Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -539,7 +539,7 @@ "definition of implicit copy %select{constructor|assignment operator}1 " "for %0 is deprecated because it has a user-declared " "%select{copy %select{assignment operator|constructor}1|destructor}2">, - InGroup, DefaultIgnore; + InGroup, DefaultIgnore; def warn_cxx17_compat_exception_spec_in_signature : Warning< "mangled name of %0 will change in C++17 due to non-throwing exception " "specification in function signature">, InGroup; Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -11771,7 +11771,8 @@ // In Microsoft mode, assignment operations don't affect constructors and // vice versa. - if (RD->hasUserDeclaredDestructor()) { + if (RD->hasUserDeclaredDestructor() && + RD->getDestructor()->isUserProvided()) { UserDeclaredOperation = RD->getDestructor(); } else if (!isa(CopyOp) && RD->hasUserDeclaredCopyConstructor() && @@ -11797,7 +11798,7 @@ assert(UserDeclaredOperation); } - if (UserDeclaredOperation) { + if (UserDeclaredOperation && UserDeclaredOperation->isUserProvided()) { S.Diag(UserDeclaredOperation->getLocation(), diag::warn_deprecated_copy_operation) << RD << /*copy assignment*/!isa(CopyOp) Index: test/SemaCXX/deprecated.cpp =================================================================== --- test/SemaCXX/deprecated.cpp +++ test/SemaCXX/deprecated.cpp @@ -96,6 +96,12 @@ }; Dtor c1, c2(c1); // expected-note {{implicit copy constructor for 'DeprecatedCopy::Dtor' first required here}} void g() { c1 = c2; } // expected-note {{implicit copy assignment operator for 'DeprecatedCopy::Dtor' first required here}} + + struct DefaultDtor { + ~DefaultDtor() = default; + }; + DefaultDtor d1, d2(d1); + void h() { d1 = d2; } } #endif