diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -1474,8 +1474,6 @@ llvm_unreachable("Found a duplicate primary base!"); } - const CXXDestructorDecl *ImplicitVirtualDtor = nullptr; - typedef llvm::SmallVector NewVirtualFunctionsTy; NewVirtualFunctionsTy NewVirtualFunctions; @@ -1542,25 +1540,9 @@ } } - if (const CXXDestructorDecl *DD = dyn_cast(MD)) { - if (MD->isImplicit()) { - // Itanium C++ ABI 2.5.2: - // If a class has an implicitly-defined virtual destructor, - // its entries come after the declared virtual function pointers. - - assert(!ImplicitVirtualDtor && - "Did already see an implicit virtual dtor!"); - ImplicitVirtualDtor = DD; - continue; - } - } - NewVirtualFunctions.push_back(MD); } - if (ImplicitVirtualDtor) - NewVirtualFunctions.push_back(ImplicitVirtualDtor); - for (const CXXMethodDecl *MD : NewVirtualFunctions) { // Get the final overrider. FinalOverriders::OverriderInfo Overrider = diff --git a/clang/test/CodeGenCXX/virtual-compare.cpp b/clang/test/CodeGenCXX/virtual-compare.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCXX/virtual-compare.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -std=c++2a -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s + +#include "Inputs/std-compare.h" + +// CHECK: @_ZTV1A = +struct A; +struct X { + // CHECK-SAME: @_ZN1X1xEv + virtual void x(); + friend auto operator<=>(X, X) = default; +}; +struct Y { + virtual ~Y(); + virtual A &operator=(const A &); + friend auto operator<=>(Y, Y) = default; +}; +struct A : X, Y { + // CHECK-SAME: @_ZN1A1fEv + virtual void f(); + // CHECK-SAME: @_ZNKR1AssERKS_ + virtual std::strong_ordering operator<=>(const A &) const & = default; + // CHECK-SAME: @_ZN1A1gEv + virtual void g(); + // CHECK-SAME: @_ZNKO1AssERKS_ + virtual std::strong_ordering operator<=>(const A &) const && = default; + // CHECK-SAME: @_ZN1A1hEv + virtual void h(); + + // CHECK-SAME: @_ZN1AaSERKS_ + // implicit virtual A &operator=(const A&) = default; + + // CHECK-SAME: @_ZN1AD1Ev + // CHECK-SAME: @_ZN1AD0Ev + // implicit virtual ~A(); + + // CHECK-SAME: @_ZNKR1AeqERKS_ + // implicit virtual A &operator==(const A&) const & = default; + + // CHECK-SAME: @_ZNKO1AeqERKS_ + // implicit virtual A &operator==(const A&) const && = default; +}; + +// For Y: +// CHECK-SAME: @_ZTI1A + +// CHECK-SAME: @_ZThn8_N1AD1Ev +// CHECK-SAME: @_ZThn8_N1AD0Ev +// virtual ~Y(); + +// CHECK-SAME: @_ZThn8_N1AaSERKS_ +// virtual A &operator=(const A &); + +void A::f() {}