Mark the vtable used when defining implicit copy and move ctors
authorReid Kleckner <reid@kleckner.net>
Fri, 18 Jul 2014 01:48:10 +0000 (01:48 +0000)
committerReid Kleckner <reid@kleckner.net>
Fri, 18 Jul 2014 01:48:10 +0000 (01:48 +0000)
I don't think other implicit members like copy assignment and move
assignment require this treatment, because they should already be
operating on a constructed object.

Fixes PR20351.

llvm-svn: 213346

clang/lib/Sema/SemaDeclCXX.cpp
clang/test/CodeGenCXX/microsoft-abi-structors.cpp

index 14be511..3f9e63f 100644 (file)
@@ -10384,6 +10384,8 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
   }
 
   CopyConstructor->markUsed(Context);
+  MarkVTableUsed(CurrentLocation, ClassDecl);
+
   if (ASTMutationListener *L = getASTMutationListener()) {
     L->CompletedImplicitDefinition(CopyConstructor);
   }
@@ -10542,6 +10544,7 @@ void Sema::DefineImplicitMoveConstructor(SourceLocation CurrentLocation,
   }
 
   MoveConstructor->markUsed(Context);
+  MarkVTableUsed(CurrentLocation, ClassDecl);
 
   if (ASTMutationListener *L = getASTMutationListener()) {
     L->CompletedImplicitDefinition(MoveConstructor);
index 04227e3..7d3992b 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 -fno-rtti > %t
+// RUN: %clang_cc1 -emit-llvm -fno-rtti %s -std=c++11 -o - -mconstructor-aliases -triple=i386-pc-win32 -fno-rtti > %t
 // RUN: FileCheck %s < %t
 // vftables are emitted very late, so do another pass to try to keep the checks
 // in source order.
@@ -406,6 +406,26 @@ void construct_b() {
 // CHECK:               (%"struct.test1::B"* {{.*}}, i32 1, i8* {{.*}}, i32 1, i32 2)
 }
 
+namespace implicit_copy_vtable {
+// This was a crash that only reproduced in ABIs without key functions.
+struct ImplicitCopy {
+  // implicit copy ctor
+  virtual ~ImplicitCopy();
+};
+void CreateCopy(ImplicitCopy *a) {
+  new ImplicitCopy(*a);
+}
+// CHECK: store {{.*}} @"\01??_7ImplicitCopy@implicit_copy_vtable@@6B@"
+
+struct MoveOnly {
+  MoveOnly(MoveOnly &&o) = default;
+  virtual ~MoveOnly();
+};
+MoveOnly &&f();
+void g() { new MoveOnly(f()); }
+// CHECK: store {{.*}} @"\01??_7MoveOnly@implicit_copy_vtable@@6B@"
+}
+
 // Dtor thunks for classes in anonymous namespaces should be internal, not
 // linkonce_odr.
 namespace {