Prazek created this revision.
Prazek added reviewers: rsmith, majnemer, rjmccall.
Prazek added a subscriber: cfe-commits.

Bugfix revealed in r245264.

http://reviews.llvm.org/D12128

Files:
  include/clang/AST/VTableBuilder.h
  lib/CodeGen/ItaniumCXXABI.cpp

Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -320,17 +320,15 @@
   void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
 
  private:
-  /// Checks if function has any virtual inline function.
-  bool hasAnyVirtualInlineFunction(const CXXRecordDecl *RD) const {
+   bool hasAnyUsedVirtualInlineFunction(const CXXRecordDecl *RD) const {
     const auto &VtableLayout =
         CGM.getItaniumVTableContext().getVTableLayout(RD);
 
     for (const auto &VtableComponent : VtableLayout.vtable_components()) {
-      if (VtableComponent.getKind() !=
-          VTableComponent::Kind::CK_FunctionPointer)
+      if (!VtableComponent.isUsedFunctionPointerKind())
         continue;
 
-      const auto &Method = VtableComponent.getFunctionDecl();
+      const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
       if (Method->getCanonicalDecl()->isInlined())
         return true;
     }
@@ -1536,7 +1534,7 @@
   // then we are safe to emit available_externally copy of vtable.
   // FIXME we can still emit a copy of the vtable if we
   // can emit definition of the inline functions.
-  return !hasAnyVirtualInlineFunction(RD);
+  return !hasAnyUsedVirtualInlineFunction(RD);
 }
 static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF,
                                           llvm::Value *Ptr,
Index: include/clang/AST/VTableBuilder.h
===================================================================
--- include/clang/AST/VTableBuilder.h
+++ include/clang/AST/VTableBuilder.h
@@ -123,29 +123,39 @@
 
   const CXXRecordDecl *getRTTIDecl() const {
     assert(getKind() == CK_RTTI && "Invalid component kind!");
-
     return reinterpret_cast<CXXRecordDecl *>(getPointer());
   }
 
   const CXXMethodDecl *getFunctionDecl() const {
-    assert(getKind() == CK_FunctionPointer);
-
+    assert(isFunctionPointerKind() && "Invalid component kind!");
+    if (isDestructorKind())
+      return getDestructorDecl();
     return reinterpret_cast<CXXMethodDecl *>(getPointer());
   }
 
   const CXXDestructorDecl *getDestructorDecl() const {
-    assert((getKind() == CK_CompleteDtorPointer ||
-            getKind() == CK_DeletingDtorPointer) && "Invalid component kind!");
-
+    assert(isDestructorKind() && "Invalid component kind!");
     return reinterpret_cast<CXXDestructorDecl *>(getPointer());
   }
 
   const CXXMethodDecl *getUnusedFunctionDecl() const {
-    assert(getKind() == CK_UnusedFunctionPointer);
-
+    assert(getKind() == CK_UnusedFunctionPointer && "Invalid component kind!");
     return reinterpret_cast<CXXMethodDecl *>(getPointer());
   }
 
+  bool isDestructorKind() const {
+    return getKind() == CK_CompleteDtorPointer ||
+           getKind() == CK_DeletingDtorPointer;
+  }
+
+  bool isUsedFunctionPointerKind() const {
+    return getKind() == CK_FunctionPointer || isDestructorKind();
+  }
+
+  bool isFunctionPointerKind() const {
+    return isUsedFunctionPointerKind() || getKind() == CK_UnusedFunctionPointer;
+  }
+
 private:
   VTableComponent(Kind ComponentKind, CharUnits Offset) {
     assert((ComponentKind == CK_VCallOffset ||
@@ -158,12 +168,8 @@
   }
 
   VTableComponent(Kind ComponentKind, uintptr_t Ptr) {
-    assert((ComponentKind == CK_RTTI ||
-            ComponentKind == CK_FunctionPointer ||
-            ComponentKind == CK_CompleteDtorPointer ||
-            ComponentKind == CK_DeletingDtorPointer ||
-            ComponentKind == CK_UnusedFunctionPointer) &&
-            "Invalid component kind!");
+    assert((ComponentKind == CK_RTTI || isFunctionPointerKind()) &&
+           "Invalid component kind!");
 
     assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!");
 
@@ -178,11 +184,7 @@
   }
 
   uintptr_t getPointer() const {
-    assert((getKind() == CK_RTTI ||
-            getKind() == CK_FunctionPointer ||
-            getKind() == CK_CompleteDtorPointer ||
-            getKind() == CK_DeletingDtorPointer ||
-            getKind() == CK_UnusedFunctionPointer) &&
+    assert((getKind() == CK_RTTI || isFunctionPointerKind()) &&
            "Invalid component kind!");
 
     return static_cast<uintptr_t>(Value & ~7ULL);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to