[PATCH] [MS ABI] Error instead of generating bad vftables for certain virtual hierarchies (PR18967)
Hans Wennborg
hans at chromium.org
Wed Feb 26 14:41:25 PST 2014
Hi rnk,
It's not pretty, but this allows us to fall back instead of miscompiling stuff.
http://llvm-reviews.chandlerc.com/D2890
Files:
lib/AST/VTableBuilder.cpp
test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-pr18967.cpp
Index: lib/AST/VTableBuilder.cpp
===================================================================
--- lib/AST/VTableBuilder.cpp
+++ lib/AST/VTableBuilder.cpp
@@ -2560,10 +2560,52 @@
const CXXRecordDecl *LastVBase,
BasesSetVectorTy &VisitedBases);
+ void CheckPR18967() {
+ // PR18967: We fail at this-adjustment for virtual methods inherited from
+ // non-primary non-vritual bases the overrides a method in a virtual base.
+
+ if (Context.getLangOpts().DumpVTableLayouts)
+ return;
+ const ASTRecordLayout &Layout = Context.getASTRecordLayout(
+ MostDerivedClass);
+ for (CXXRecordDecl::base_class_const_iterator BI =
+ MostDerivedClass->bases_begin(), BE = MostDerivedClass->bases_end();
+ BI != BE; ++BI) {
+ const CXXRecordDecl *Base = BI->getType()->getAsCXXRecordDecl();
+ if (Base == Layout.getPrimaryBase())
+ continue;
+ if (BI->isVirtual())
+ continue;
+ for (CXXRecordDecl::method_iterator I = Base->method_begin(),
+ E = Base->method_end(); I != E; ++I) {
+ const CXXMethodDecl *Method = *I;
+ if (!Method->isVirtual())
+ continue;
+ if (isa<CXXDestructorDecl>(Method))
+ continue;
+ OverriddenMethodsSetTy OverriddenMethods;
+ ComputeAllOverriddenMethods(Method, OverriddenMethods);
+ for (OverriddenMethodsSetTy::const_iterator I =
+ OverriddenMethods.begin(),
+ E = OverriddenMethods.end(); I != E; ++I) {
+ const CXXMethodDecl *Overridden = *I;
+ if (Base->isVirtuallyDerivedFrom(Overridden->getParent())) {
+ ErrorUnsupported("classes with non-primary non-virtual base "
+ "classes that override methods in virtual bases",
+ BI->getLocStart());
+ return;
+ }
+ }
+ }
+ }
+ }
+
void LayoutVFTable() {
// FIXME: add support for RTTI when we have proper LLVM support for symbols
// pointing to the middle of a section.
+ CheckPR18967();
+
BasesSetVectorTy VisitedBases;
AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, 0,
VisitedBases);
Index: test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
+++ test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -217,7 +217,12 @@
// CHECK: ret
}
-struct C : B {
+struct X : virtual VBase {
+ int x;
+};
+
+
+struct C : X {
C();
// has an implicit vdtor.
};
Index: test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-pr18967.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-pr18967.cpp
@@ -0,0 +1,27 @@
+// RUN: not %clang_cc1 -triple i686-pc-win32 -emit-llvm -fno-rtti %s 2>&1 | FileCheck %s
+
+// CHECK: error: v-table layout for classes with non-primary non-virtual base classes that override methods in virtual bases is not supported yet
+
+struct A {
+ virtual int foo() { return a; }
+ int a;
+};
+struct B : virtual A {
+ B() : b(1) {}
+ virtual int bar() { return b; }
+ int b;
+};
+struct C : virtual A {
+ C() : c(2) {}
+ virtual int foo() { return c; }
+ int c;
+};
+struct D : B, C {
+ D() : d(3) {}
+ virtual int bar() { return d; }
+ int d;
+};
+int main() {
+ D d;
+ return d.foo();
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2890.1.patch
Type: text/x-patch
Size: 3485 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140226/752ab211/attachment.bin>
More information about the cfe-commits
mailing list