ningvin created this revision.
ningvin added a reviewer: rsmith.
ningvin added a project: clang.
Herald added a project: All.
ningvin requested review of this revision.
Herald added a subscriber: cfe-commits.

When running in MSVC compatibility mode, previously no deprecated copy 
operation warnings (enabled by `-Wdeprecated-copy`) were raised. This 
restriction was already in place when the deprecated copy warning was first 
introduced 
<https://reviews.llvm.org/rGd577fbbd1c9d6dab193d530fcd807efc3b3bc9ad>.

This patch removes said restriction so that deprecated copy warnings, if 
enabled, are also raised in MSVC compatibility mode. The reasoning here being 
that these warnings are still useful when running in MSVC compatibility mode 
and also have to be semi-explicitly enabled in the first place (using 
`-Wdeprecated-copy`, `-Wdeprecated` or `-Wextra`).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133354

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/deprecated-copy-msvc.cpp


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}}
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<CXXConstructorDecl>(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<CXXConstructorDecl>(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}}
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<CXXConstructorDecl>(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<CXXConstructorDecl>(CopyOp) &&
-             RD->hasUserDeclaredCopyAssignment() &&
-             !S.getLangOpts().MSVCCompat) {
+             RD->hasUserDeclaredCopyAssignment()) {
     // Find any user-declared move assignment operator.
     for (auto *I : RD->methods()) {
       if (I->isCopyAssignmentOperator()) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to