diff options
| author | Hans Wennborg <hans@hanshq.net> | 2014-02-27 01:14:31 +0000 |
|---|---|---|
| committer | Hans Wennborg <hans@hanshq.net> | 2014-02-27 01:14:31 +0000 |
| commit | d7895aca994e058a9c258c212c87bdc1803992c7 (patch) | |
| tree | 5ed513f09078c5883950c642c3bcf2e4d334e4d0 /clang/lib | |
| parent | 9a4416486d6255a4bb94a1c3e629b246f933d0e1 (diff) | |
| download | bcm5719-llvm-d7895aca994e058a9c258c212c87bdc1803992c7.tar.gz bcm5719-llvm-d7895aca994e058a9c258c212c87bdc1803992c7.zip | |
[MS ABI] Error instead of generating bad vftables for certain virtual hierarchies (PR18967)
Erroring out until we fix the bug means we don't have to keep chasing down
this same miscompile in a bunch of different places.
Differential Revision: http://llvm-reviews.chandlerc.com/D2890
llvm-svn: 202331
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/VTableBuilder.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp index e0e30a122a8..8efd9c03d4c 100644 --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -2560,10 +2560,47 @@ private: const CXXRecordDecl *LastVBase, BasesSetVectorTy &VisitedBases); + void CheckBadVirtualInheritanceHierarchy() { + // We fail at this-adjustment for virtual methods inherited from + // non-virtual bases that overrides a method in a virtual base. + if (Context.getLangOpts().DumpVTableLayouts) + return; + for (CXXRecordDecl::base_class_const_iterator BI = + MostDerivedClass->bases_begin(), BE = MostDerivedClass->bases_end(); + BI != BE; ++BI) { + const CXXRecordDecl *Base = BI->getType()->getAsCXXRecordDecl(); + 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-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. + CheckBadVirtualInheritanceHierarchy(); + BasesSetVectorTy VisitedBases; AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, 0, VisitedBases); |

