From 5ef4fe7d8ee31c83c4ebc118b21402e7ea14c9f2 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Fri, 13 Jun 2014 06:43:46 +0000 Subject: MS ABI: Fix inheritance model calculation in CRTP CRTP-like patterns involve a class which inherits from another class using itself as a template parameter. However, the base class itself may try to create a pointer-to-member which involves the derived class. This is problematic because we may not have finished parsing the most derived classes' base specifiers yet. It turns out that MSVC simply uses the unspecified inheritance model instead of doing anything fancy. This fixes PR19987. llvm-svn: 210886 --- clang/lib/AST/DeclCXX.cpp | 9 +++++++-- clang/lib/AST/MicrosoftCXXABI.cpp | 2 +- clang/lib/Sema/SemaDeclCXX.cpp | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'clang/lib') diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 0ac8b73e306..43d0fca9f92 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -70,7 +70,8 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) ImplicitCopyAssignmentHasConstParam(true), HasDeclaredCopyConstructorWithConstParam(false), HasDeclaredCopyAssignmentWithConstParam(false), - IsLambda(false), NumBases(0), NumVBases(0), Bases(), VBases(), + IsLambda(false), IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0), + Bases(), VBases(), Definition(D), FirstFriend() { } @@ -334,8 +335,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, addedClassSubobject(BaseClassDecl); } - if (VBases.empty()) + if (VBases.empty()) { + data().IsParsingBaseSpecifiers = false; return; + } // Create base specifier for any direct or indirect virtual bases. data().VBases = new (C) CXXBaseSpecifier[VBases.size()]; @@ -346,6 +349,8 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, addedClassSubobject(Type->getAsCXXRecordDecl()); data().getVBases()[I] = *VBases[I]; } + + data().IsParsingBaseSpecifiers = false; } void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) { diff --git a/clang/lib/AST/MicrosoftCXXABI.cpp b/clang/lib/AST/MicrosoftCXXABI.cpp index 359e8648278..6870315b216 100644 --- a/clang/lib/AST/MicrosoftCXXABI.cpp +++ b/clang/lib/AST/MicrosoftCXXABI.cpp @@ -93,7 +93,7 @@ static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) { } MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const { - if (!hasDefinition()) + if (!hasDefinition() || isParsingBaseSpecifiers()) return MSInheritanceAttr::Keyword_unspecified_inheritance; if (getNumVBases() > 0) return MSInheritanceAttr::Keyword_virtual_inheritance; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 57e6550cec5..ed7908dfc92 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1431,6 +1431,9 @@ Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange, if (!Class) return true; + // We haven't yet attached the base specifiers. + Class->setIsParsingBaseSpecifiers(); + // We do not support any C++11 attributes on base-specifiers yet. // Diagnose any attributes we see. if (!Attributes.empty()) { -- cgit v1.2.3