[PATCH] D27358: [MS-ABI]V-base dtor called more than needed when throw happens in v-base ctor in window. Need add "complete object flag" check in eh cleanup code.

Reid Kleckner via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 6 10:07:43 PST 2016


rnk added a comment.

This highlights an interesting MS/Itanium C++ ABI difference. GCC and Clang emit cleanup landing pads in destructors to ensure that all subobjects are destroyed even if one throws an exception. In Mingw, both GCC and Clang print ~A and ~B for this program, but MSVC does not:

  extern "C" int puts(const char *);
  struct A { virtual ~A() noexcept(false) { puts("~A"); } };
  struct B { virtual ~B() noexcept(false) { puts("~B"); } };
  struct C : virtual A, virtual B { virtual ~C() noexcept(false) { throw 1; } };
  int main() {
    try {
      C c;
    } catch (...) {
      puts("caught");
    }
  }

I encountered this while tracing out call sites in clang where `ForVirtualBase` is set to true in EmitCXXDestructorCall.



================
Comment at: lib/CodeGen/MicrosoftCXXABI.cpp:1530-1532
+    const CXXRecordDecl *ClassDecl =
+             cast<CXXConstructorDecl>(CGF.CurCodeDecl)->getParent();
+    if (ClassDecl != nullptr && ClassDecl->getNumVBases())
----------------
These checks seem unnecessary. ForVirtualBase should never be true if there are no vbases, and the IsMostDerivedClass assert will catch it if not.


================
Comment at: test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp:285
+  int var_0;
+  class_2() {};
+  virtual ~class_2() {
----------------
Most of these can be declarations to reduce the output size.


================
Comment at: test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp:316
+  // WIN32: [[DTOR_VBASE]]
+  // WIN32: br label %[[SKIP_VBASE]]
+  // WIN32: [[SKIP_VBASE]]
----------------
Check for a call to the class_2 destructor here


Repository:
  rL LLVM

https://reviews.llvm.org/D27358





More information about the cfe-commits mailing list