]> granicus.if.org Git - clang/commitdiff
[MS] Fix bug in r327732 with devirtualized complete destructor calls
authorReid Kleckner <rnk@google.com>
Fri, 16 Mar 2018 22:20:57 +0000 (22:20 +0000)
committerReid Kleckner <rnk@google.com>
Fri, 16 Mar 2018 22:20:57 +0000 (22:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@327754 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
test/CodeGenCXX/devirtualize-ms-dtor.cpp [new file with mode: 0644]

index e221b64d2ecceef381e6a4ca6df0e7bc2f15f082..a47c1c649da2e7f09bfc8558cba568b7335ef61c 100644 (file)
@@ -2550,6 +2550,16 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
     Ty = getTypes().ConvertFunctionType(CanonTy, FD);
   }
 
+  // Devirtualized destructor calls may come through here instead of via
+  // getAddrOfCXXStructor. Make sure we use the MS ABI base destructor instead
+  // of the complete destructor when necessary.
+  if (const auto *DD = dyn_cast<CXXDestructorDecl>(GD.getDecl())) {
+    if (getTarget().getCXXABI().isMicrosoft() &&
+        GD.getDtorType() == Dtor_Complete &&
+        DD->getParent()->getNumVBases() == 0)
+      GD = GlobalDecl(DD, Dtor_Base);
+  }
+
   StringRef MangledName = getMangledName(GD);
   return GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable, DontDefer,
                                  /*IsThunk=*/false, llvm::AttributeList(),
diff --git a/test/CodeGenCXX/devirtualize-ms-dtor.cpp b/test/CodeGenCXX/devirtualize-ms-dtor.cpp
new file mode 100644 (file)
index 0000000..d999b0c
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc %s -emit-llvm -o - | FileCheck %s
+
+// If we de-virtualize ~Foo, we still need to call ??1Foo, not ??_DFoo.
+
+struct Base {
+  virtual ~Base();
+};
+struct Foo final : Base {
+};
+void f(Foo *p) {
+  p->~Foo();
+}
+
+// CHECK-LABEL: define{{.*}} void @"?f@@YAXPEAUFoo@@@Z"(%struct.Foo* %p)
+// CHECK: call void @"??1Foo@@UEAA@XZ"
+// CHECK: ret void