Index: clang/include/clang/Basic/DiagnosticGroups.td =================================================================== --- clang/include/clang/Basic/DiagnosticGroups.td +++ clang/include/clang/Basic/DiagnosticGroups.td @@ -154,8 +154,10 @@ def DeprecatedArrayCompare : DiagGroup<"deprecated-array-compare">; def DeprecatedAttributes : DiagGroup<"deprecated-attributes">; def DeprecatedCommaSubscript : DiagGroup<"deprecated-comma-subscript">; -def DeprecatedCopy : DiagGroup<"deprecated-copy">; -def DeprecatedCopyDtor : DiagGroup<"deprecated-copy-dtor">; +def DeprecatedCopyUserProvided : DiagGroup<"deprecated-copy-user-provided">; +def DeprecatedCopyDtorUserProvided : DiagGroup<"deprecated-copy-dtor-user-provided">; +def DeprecatedCopy : DiagGroup<"deprecated-copy", [DeprecatedCopyUserProvided]>; +def DeprecatedCopyDtor : DiagGroup<"deprecated-copy-dtor", [DeprecatedCopyDtorUserProvided]>; def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">; def UnavailableDeclarations : DiagGroup<"unavailable-declarations">; def UnguardedAvailabilityNew : DiagGroup<"unguarded-availability-new">; Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -564,6 +564,12 @@ "definition of implicit copy %select{constructor|assignment operator}1 " "for %0 is deprecated because it has a user-declared destructor">, InGroup, DefaultIgnore; +def warn_deprecated_copy_operation_user_provided : Warning< + warn_deprecated_copy_operation.Text>, + InGroup, DefaultIgnore; +def warn_deprecated_copy_dtor_operation_user_provided : Warning< + warn_deprecated_copy_dtor_operation.Text>, + 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: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -13932,12 +13932,20 @@ assert(UserDeclaredOperation); } - if (UserDeclaredOperation && UserDeclaredOperation->isUserProvided()) { - S.Diag(UserDeclaredOperation->getLocation(), - isa(UserDeclaredOperation) - ? diag::warn_deprecated_copy_dtor_operation - : diag::warn_deprecated_copy_operation) - << RD << /*copy assignment*/ !isa(CopyOp); + if (UserDeclaredOperation) { + bool UDOIsUserProvided = UserDeclaredOperation->isUserProvided(); + bool UDOIsDestructor = isa(UserDeclaredOperation); + bool IsCopyAssignment = !isa(CopyOp); + unsigned DiagID = + (UDOIsUserProvided && UDOIsDestructor) + ? diag::warn_deprecated_copy_dtor_operation_user_provided + : (UDOIsUserProvided && !UDOIsDestructor) + ? diag::warn_deprecated_copy_operation_user_provided + : (!UDOIsUserProvided && UDOIsDestructor) + ? diag::warn_deprecated_copy_dtor_operation + : diag::warn_deprecated_copy_operation; + S.Diag(UserDeclaredOperation->getLocation(), DiagID) + << RD << /*copy assignment*/ IsCopyAssignment; } } Index: clang/test/SemaCXX/deprecated-copy-dtor.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/deprecated-copy-dtor.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -std=c++11 %s -Wdeprecated -verify +// RUN: %clang_cc1 -std=c++11 %s -Wdeprecated-copy -verify + +struct S { + int i; + ~A() = delete; // expected-warning {{definition of implicit copy constructor for 'S' is deprecated because it has a user-declared copy assignment operator}} +}; + +S test(const S& s) { return S(s); } // expected-note {{implicit copy constructor for 'S' first required here}} \ No newline at end of file Index: clang/test/SemaCXX/deprecated-copy.cpp =================================================================== --- clang/test/SemaCXX/deprecated-copy.cpp +++ clang/test/SemaCXX/deprecated-copy.cpp @@ -1,23 +1,9 @@ +// RUN: %clang_cc1 -std=c++11 %s -Wdeprecated -verify // RUN: %clang_cc1 -std=c++11 %s -Wdeprecated-copy -verify -// RUN: %clang_cc1 -std=c++11 %s -Wdeprecated-copy-dtor -DDEPRECATED_COPY_DTOR -verify -// RUN: %clang_cc1 -std=c++11 %s -Wextra -verify -#ifdef DEPRECATED_COPY_DTOR -struct A { - int *ptr; - ~A() { delete ptr; } // expected-warning {{definition of implicit copy constructor for 'A' is deprecated because it has a user-declared destructor}} +struct S { + int i; + S& operator=(const S&) = delete; // expected-warning {{definition of implicit copy constructor for 'S' is deprecated because it has a user-declared copy assignment operator}} }; -void foo() { - A a{}; - A b = a; // expected-note {{implicit copy constructor for 'A' first required here}} -} -#else -struct B { - B &operator=(const B &); // expected-warning {{definition of implicit copy constructor for 'B' is deprecated because it has a user-declared copy assignment operator}} -}; - -void bar() { - B b1, b2(b1); // expected-note {{implicit copy constructor for 'B' first required here}} -} -#endif +S test(const S& s) { return S(s); } // expected-note {{implicit copy constructor for 'S' first required here}} \ No newline at end of file Index: clang/test/SemaCXX/deprecated-dtor-user-provided.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/deprecated-dtor-user-provided.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++11 %s -Wdeprecated -verify +// RUN: %clang_cc1 -std=c++11 %s -Wdeprecated-copy-dtor-user-provided -verify + +struct A { + int *ptr; + ~A(); // expected-warning {{definition of implicit copy constructor for 'A' is deprecated because it has a user-declared destructor}} +}; + +void foo() { + A a{}; + A b = a; // expected-note {{implicit copy constructor for 'A' first required here}} +} Index: clang/test/SemaCXX/deprecated-user-provided.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/deprecated-user-provided.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=c++11 %s -Wdeprecated -verify +// RUN: %clang_cc1 -std=c++11 %s -Wdeprecated-copy-user-provided -verify + +struct A { + A &operator=(const A &); // expected-warning {{definition of implicit copy constructor for 'A' is deprecated because it has a user-declared copy assignment operator}} +}; + +void foo() { + A a1, a2(a1); // expected-note {{implicit copy constructor for 'A' first required here}} +} Index: clang/test/SemaCXX/deprecated.cpp =================================================================== --- clang/test/SemaCXX/deprecated.cpp +++ clang/test/SemaCXX/deprecated.cpp @@ -103,10 +103,10 @@ void g() { c1 = c2; } // expected-note {{implicit copy assignment operator for 'DeprecatedCopy::Dtor' first required here}} struct DefaultedDtor { - ~DefaultedDtor() = default; - }; - DefaultedDtor d1, d2(d1); - void h() { d1 = d2; } + ~DefaultedDtor() = default; // expected-warning {{definition of implicit copy constructor for 'DefaultedDtor' is deprecated because it has a user-declared destructor}} + }; // expected-warning@-1 {{definition of implicit copy assignment operator for 'DefaultedDtor' is deprecated because it has a user-declared destructor}} + DefaultedDtor d1, d2(d1); // expected-note {{in implicit copy constructor for 'DeprecatedCopy::DefaultedDtor' first required here}} + void h() { d1 = d2; } // expected-note {{in implicit copy assignment operator for 'DeprecatedCopy::DefaultedDtor' first required here}} } #endif