summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp13
-rw-r--r--clang/test/SemaCXX/MicrosoftCompatibility.cpp16
2 files changed, 25 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index d41748f5e33..82da95e9a67 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 56608681088..26cd7825ee8 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
}
}
OpenPOWER on IntegriCloud