[PATCH] D26822: Sema, CodeGen: Ensure that an implicit copy ctor is always available under the Microsoft C++ ABI.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 17 17:18:32 PST 2016


pcc created this revision.
pcc added a reviewer: rnk.
pcc added a subscriber: llvm-commits.

This is needed because whether the constructor is deleted can control whether
we pass structs by value directly.

To fix this properly we probably want a more direct way for CodeGen to ask
whether the constructor was deleted.

Fixes PR31049.


https://reviews.llvm.org/D26822

Files:
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CodeGenCXX/uncopyable-args.cpp


Index: clang/test/CodeGenCXX/uncopyable-args.cpp
===================================================================
--- clang/test/CodeGenCXX/uncopyable-args.cpp
+++ clang/test/CodeGenCXX/uncopyable-args.cpp
@@ -204,3 +204,34 @@
 
 // WIN64-LABEL: declare void @"\01?foo at two_copy_ctors@@YAXUB at 1@@Z"(%"struct.two_copy_ctors::B"*)
 }
+
+namespace definition_only {
+struct A {
+  A();
+  A(A &&o);
+  void *p;
+};
+void *foo(A a) { return a.p; }
+// WIN64-LABEL: define i8* @"\01?foo at definition_only@@YAPEAXUA at 1@@Z"{{.*}}
+// WIN64-NEXT: :
+// WIN64-NEXT: getelementptr
+// WIN64-NEXT: load
+}
+
+namespace deleted_by_member {
+struct B {
+  B();
+  B(B &&o) : p(o.p) {}
+  void *p;
+};
+struct A {
+  A();
+  B b;
+};
+void *foo(A a) { return a.b.p; }
+// WIN64-LABEL: define i8* @"\01?foo at deleted_by_member@@YAPEAXUA at 1@@Z"{{.*}}
+// WIN64-NEXT: :
+// WIN64-NEXT: getelementptr
+// WIN64-NEXT: getelementptr
+// WIN64-NEXT: load
+}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -7387,8 +7387,15 @@
     // If the properties or semantics of the copy constructor couldn't be
     // determined while the class was being declared, force a declaration
     // of it now.
+    //
+    // We also need to declare the implicit copy constructor under the Microsoft
+    // C++ ABI because whether the constructor is deleted can control whether we
+    // pass the record by value directly (see MicrosoftCXXABI::getRecordArgABI).
+    // FIXME: We should provide a more direct way for CodeGen to ask whether the
+    // constructor was deleted.
     if (ClassDecl->needsOverloadResolutionForCopyConstructor() ||
-        ClassDecl->hasInheritedConstructor())
+        ClassDecl->hasInheritedConstructor() ||
+        Context.getTargetInfo().getCXXABI().isMicrosoft())
       DeclareImplicitCopyConstructor(ClassDecl);
   }
 
Index: clang/lib/CodeGen/MicrosoftCXXABI.cpp
===================================================================
--- clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -830,25 +830,24 @@
         getContext().getTypeSize(RD->getTypeForDecl()) > 64)
       return RAA_Indirect;
 
+    // We need Sema to have determined whether the implicit copy constructor is
+    // deleted. FIXME: We should provide a more direct way for CodeGen to ask
+    // whether the constructor was deleted.
+    assert(!RD->needsImplicitCopyConstructor());
+
     // We have a trivial copy constructor or no copy constructors, but we have
     // to make sure it isn't deleted.
-    bool CopyDeleted = false;
     for (const CXXConstructorDecl *CD : RD->ctors()) {
       if (CD->isCopyConstructor()) {
         assert(CD->isTrivial());
         // We had at least one undeleted trivial copy ctor.  Return directly.
         if (!CD->isDeleted())
           return RAA_Default;
-        CopyDeleted = true;
       }
     }
 
     // The trivial copy constructor was deleted.  Return indirectly.
-    if (CopyDeleted)
-      return RAA_Indirect;
-
-    // There were no copy ctors.  Return in RAX.
-    return RAA_Default;
+    return RAA_Indirect;
   }
 
   llvm_unreachable("invalid enum");


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D26822.78440.patch
Type: text/x-patch
Size: 3250 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161118/822099eb/attachment.bin>


More information about the llvm-commits mailing list