summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2014-02-27 01:14:31 +0000
committerHans Wennborg <hans@hanshq.net>2014-02-27 01:14:31 +0000
commitd7895aca994e058a9c258c212c87bdc1803992c7 (patch)
tree5ed513f09078c5883950c642c3bcf2e4d334e4d0 /clang/lib
parent9a4416486d6255a4bb94a1c3e629b246f933d0e1 (diff)
downloadbcm5719-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.cpp37
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);
OpenPOWER on IntegriCloud