Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -14429,13 +14429,10 @@ CXXRecordDecl *RD = CopyOp->getParent(); CXXMethodDecl *UserDeclaredOperation = nullptr; - // In Microsoft mode, assignment operations don't affect constructors and - // vice versa. if (RD->hasUserDeclaredDestructor()) { UserDeclaredOperation = RD->getDestructor(); } else if (!isa(CopyOp) && - RD->hasUserDeclaredCopyConstructor() && - !S.getLangOpts().MSVCCompat) { + RD->hasUserDeclaredCopyConstructor()) { // Find any user-declared copy constructor. for (auto *I : RD->ctors()) { if (I->isCopyConstructor()) { @@ -14445,8 +14442,7 @@ } assert(UserDeclaredOperation); } else if (isa(CopyOp) && - RD->hasUserDeclaredCopyAssignment() && - !S.getLangOpts().MSVCCompat) { + RD->hasUserDeclaredCopyAssignment()) { // Find any user-declared move assignment operator. for (auto *I : RD->methods()) { if (I->isCopyAssignmentOperator()) { Index: clang/test/SemaCXX/deprecated-copy-msvc.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/deprecated-copy-msvc.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 %s -std=c++11 %s -Wdeprecated-copy -verify -fms-compatibility + +struct A { + A& operator=(const A&) = default; // expected-warning {{definition of implicit copy constructor for 'A' is deprecated because it has a user-declared copy assignment operator}} +}; + +struct B { + B& operator=(const B&) = delete; // expected-warning {{definition of implicit copy constructor for 'B' is deprecated because it has a user-declared copy assignment operator}} +}; + +void test() { + A a1; + A a2(a1); // expected-note {{implicit copy constructor for 'A' first required here}} + + B b1; + B b2(b1); // expected-note {{implicit copy constructor for 'B' first required here}} +} + +// PR45634 +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}} +}; + +S test(const S &s) { return S(s); } // expected-note {{implicit copy constructor for 'S' first required here}}