From 66bfcb3ea59437b83a15cfe47413b7dc3c9714ee Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Sat, 19 Nov 2016 00:30:56 +0000 Subject: [PATCH] Sema: As of MSVC 2015, a user-declared move operation causes the deletion of both copy operations. Differential Revision: https://reviews.llvm.org/D26868 llvm-svn: 287411 --- clang/lib/Sema/SemaDeclCXX.cpp | 13 +++++++++---- clang/test/SemaCXX/MicrosoftCompatibility.cpp | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index d41748f..82da95e 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -6711,10 +6711,15 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM, (CSM == CXXCopyConstructor || CSM == CXXCopyAssignment)) { CXXMethodDecl *UserDeclaredMove = nullptr; - // In Microsoft mode, a user-declared move only causes the deletion of the - // corresponding copy operation, not both copy operations. + // In Microsoft mode up to MSVC 2013, a user-declared move only causes the + // deletion of the corresponding copy operation, not both copy operations. + // MSVC 2015 has adopted the standards conforming behavior. + bool DeletesOnlyMatchingCopy = + getLangOpts().MSVCCompat && + !getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015); + if (RD->hasUserDeclaredMoveConstructor() && - (!getLangOpts().MSVCCompat || CSM == CXXCopyConstructor)) { + (!DeletesOnlyMatchingCopy || CSM == CXXCopyConstructor)) { if (!Diagnose) return true; // Find any user-declared move constructor. @@ -6726,7 +6731,7 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM, } assert(UserDeclaredMove); } else if (RD->hasUserDeclaredMoveAssignment() && - (!getLangOpts().MSVCCompat || CSM == CXXCopyAssignment)) { + (!DeletesOnlyMatchingCopy || CSM == CXXCopyAssignment)) { if (!Diagnose) return true; // Find any user-declared move assignment operator. diff --git a/clang/test/SemaCXX/MicrosoftCompatibility.cpp b/clang/test/SemaCXX/MicrosoftCompatibility.cpp index 5660868..26cd782 100644 --- a/clang/test/SemaCXX/MicrosoftCompatibility.cpp +++ b/clang/test/SemaCXX/MicrosoftCompatibility.cpp @@ -99,23 +99,39 @@ int jump_over_indirect_goto() { namespace PR11826 { struct pair { pair(int v) { } +#if _MSC_VER >= 1900 + void operator=(pair&& rhs) { } // expected-note {{copy constructor is implicitly deleted because 'pair' has a user-declared move assignment operator}} +#else void operator=(pair&& rhs) { } +#endif }; void f() { pair p0(3); +#if _MSC_VER >= 1900 + pair p = p0; // expected-error {{call to implicitly-deleted copy constructor of 'PR11826::pair'}} +#else pair p = p0; +#endif } } namespace PR11826_for_symmetry { struct pair { pair(int v) { } +#if _MSC_VER >= 1900 + pair(pair&& rhs) { } // expected-note {{copy assignment operator is implicitly deleted because 'pair' has a user-declared move constructor}} +#else pair(pair&& rhs) { } +#endif }; void f() { pair p0(3); pair p(4); +#if _MSC_VER >= 1900 + p = p0; // expected-error {{object of type 'PR11826_for_symmetry::pair' cannot be assigned because its copy assignment operator is implicitly deleted}} +#else p = p0; +#endif } } -- 2.7.4