<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [ms] CXXRecordDecl::getMSInheritanceModel() dereferences null MSInheritanceAttr"
   href="https://bugs.llvm.org/show_bug.cgi?id=37399">37399</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[ms] CXXRecordDecl::getMSInheritanceModel() dereferences null MSInheritanceAttr
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows XP
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Frontend
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>andrew.rogers@wdc.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=20277" name="attach_20277" title="Testcase">attachment 20277</a> <a href="attachment.cgi?id=20277&action=edit" title="Testcase">[details]</a></span>
Testcase

Compile the following:

template<typename ObjT>
class Functor
{
   void (ObjT::*PtrToMemberFunction)();
};

template<typename SomeType> class DerivedFunctor;

template<typename SomeType>
class DerivedFunctor
 : public Functor<DerivedFunctor<SomeType> >
{
};

DerivedFunctor<void> AFunctor;

with:

clang-cpp.exe -cc1 -emit-llvm-only -x c++ test.cpp

This generates the following ASSERT (debug build) / AV (release build):

C:\Temp\clang\clang>c:\workspaces\llvm-build\Debug\bin\clang-cpp.exe -cc1
-emit-llvm-only -x c++ test.cpp
Assertion failed: IA && "Expected MSInheritanceAttr on the CXXRecordDecl!",
file c:\workspaces\llvm\tools\clang\lib\ast\microsoftcxxabi.cpp, line 171
Wrote crash dump file
"C:\Users\14166\AppData\Local\Temp\clang-cpp.exe-346498.dmp"
...

The failing callstack which tries to use a null MSInheritanceAttr looks like
this:

<span class="quote">>        clang-cpp.exe!clang::CXXRecordDecl::getMSInheritanceModel() Line 171    C++</span >
        clang-cpp.exe!getMSMemberPointerSlots(const clang::MemberPointerType *
MPT) Line 213    C++
        clang-cpp.exe!`anonymous
namespace'::MicrosoftCXXABI::getMemberPointerInfo(const
clang::MemberPointerType * MPT) Line 239       C++
        clang-cpp.exe!clang::ASTContext::getTypeInfoImpl(const clang::Type * T)
Line 1858       C++
        clang-cpp.exe!clang::ASTContext::getTypeInfo(const clang::Type * T)
Line 1657   C++
        clang-cpp.exe!clang::ASTContext::getTypeInfoInChars(const clang::Type *
T) Line 1609    C++
        clang-cpp.exe!`anonymous
namespace'::MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(const
clang::FieldDecl * FD) Line 2387        C++
        clang-cpp.exe!`anonymous
namespace'::MicrosoftRecordLayoutBuilder::layoutField(const clang::FieldDecl *
FD) Line 2646   C++
        clang-cpp.exe!`anonymous
namespace'::MicrosoftRecordLayoutBuilder::layoutFields(const clang::RecordDecl
* RD) Line 2636 C++
        clang-cpp.exe!`anonymous
namespace'::MicrosoftRecordLayoutBuilder::cxxLayout(const clang::CXXRecordDecl
* RD) Line 2439 C++
        clang-cpp.exe!clang::ASTContext::getASTRecordLayout(const
clang::RecordDecl * D) Line 2980      C++
        clang-cpp.exe!`anonymous
namespace'::CGRecordLowering::CGRecordLowering(clang::CodeGen::CodeGenTypes &
Types, const clang::RecordDecl * D, bool Packed) Line 221        C++
        clang-cpp.exe!clang::CodeGen::CodeGenTypes::ComputeRecordLayout(const
clang::RecordDecl * D, llvm::StructType * Ty) Line 726    C++
        clang-cpp.exe!clang::CodeGen::CodeGenTypes::ConvertRecordDeclType(const
clang::RecordDecl * RD) Line 710        C++
        clang-cpp.exe!clang::CodeGen::CodeGenTypes::ConvertRecordDeclType(const
clang::RecordDecl * RD) Line 706        C++
        clang-cpp.exe!clang::CodeGen::CodeGenTypes::getCGRecordLayout(const
clang::RecordDecl * RD) Line 743    C++
        clang-cpp.exe!clang::CodeGen::CodeGenTypes::isZeroInitializable(const
clang::RecordDecl * RD) Line 784  C++
       
clang-cpp.exe!clang::CodeGen::CodeGenTypes::isZeroInitializable(clang::QualType
T) Line 772     C++
       
clang-cpp.exe!clang::CodeGen::CodeGenModule::EmitNullConstant(clang::QualType
T) Line 2103      C++
       
clang-cpp.exe!clang::CodeGen::ConstantEmitter::tryEmitPrivateForVarInit(const
clang::VarDecl & D) Line 1406     C++
       
clang-cpp.exe!clang::CodeGen::ConstantEmitter::tryEmitForInitializer(const
clang::VarDecl & D) Line 1191        C++
       
clang-cpp.exe!clang::CodeGen::CodeGenModule::EmitGlobalVarDefinition(const
clang::VarDecl * D, bool IsTentative) Line 3156      C++
       
clang-cpp.exe!clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl
GD, llvm::GlobalValue * GV) Line 2304       C++
       
clang-cpp.exe!clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl GD)
Line 2077 C++
       
clang-cpp.exe!clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl * D)
Line 4393        C++
        clang-cpp.exe!`anonymous
namespace'::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef DG) Line
160     C++
       
clang-cpp.exe!clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef D)
Line 168        C++
        clang-cpp.exe!clang::ParseAST(clang::Sema & S, bool PrintStats, bool
SkipFunctionBodies) Line 156       C++
        clang-cpp.exe!clang::ASTFrontendAction::ExecuteAction() Line 1005      
C++
        clang-cpp.exe!clang::CodeGenAction::ExecuteAction() Line 1044   C++
        clang-cpp.exe!clang::FrontendAction::Execute() Line 904 C++
       
clang-cpp.exe!clang::CompilerInstance::ExecuteAction(clang::FrontendAction &
Act) Line 990      C++
        clang-cpp.exe!clang::ExecuteCompilerInvocation(clang::CompilerInstance
* Clang) Line 255        C++
        clang-cpp.exe!cc1_main(llvm::ArrayRef<char const *> Argv, const char *
Argv0, void * MainAddr) Line 222 C++
        clang-cpp.exe!ExecuteCC1Tool(llvm::ArrayRef<char const *> argv,
llvm::StringRef Tool) Line 310  C++
        clang-cpp.exe!main(int argc_, const char * * argv_) Line 382    C++
        clang-cpp.exe!invoke_main() Line 78     C++

The AST looks like this (with -ast-dump):

TranslationUnitDecl 0xc7e6ad0 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0xc7e6fe8 <<invalid sloc>> <invalid sloc> implicit
__NSConstantString '__NSConstantString_tag'
| `-RecordType 0xc7e6e40 '__NSConstantString_tag'
|   `-CXXRecord 0xc7e6de0 '__NSConstantString_tag'
|-CXXRecordDecl 0xc7e7018 <<invalid sloc>> <invalid sloc> implicit class
type_info
| `-TypeVisibilityAttr 0xc7e7098 <<invalid sloc>> Implicit Default
|-TypedefDecl 0xc7e70e0 <<invalid sloc>> <invalid sloc> implicit size_t
'unsigned int'
| `-BuiltinType 0xc7e6ba0 'unsigned int'
|-TypedefDecl 0xc7e7140 <<invalid sloc>> <invalid sloc> implicit
__builtin_va_list 'char *'
| `-PointerType 0xc7e7110 'char *'
|   `-BuiltinType 0xc7e6b20 'char'
|-ClassTemplateDecl 0xc7e7250 <test.cpp:1:1, line:5:1> line:2:7 Functor
| |-TemplateTypeParmDecl 0xc7e7170 <line:1:10, col:19> col:19 typename depth 0
index 0 ObjT
| |-CXXRecordDecl 0xc7e71f0 <line:2:1, line:5:1> line:2:7 class Functor
definition
| | |-DefinitionData pass_in_registers standard_layout trivially_copyable
trivial
| | | |-DefaultConstructor exists trivial needs_implicit
| | | |-CopyConstructor simple trivial has_const_param needs_implicit
implicit_has_const_param
| | | |-MoveConstructor exists simple trivial needs_implicit
| | | |-CopyAssignment trivial has_const_param needs_implicit
implicit_has_const_param
| | | |-MoveAssignment exists simple trivial needs_implicit
| | | `-Destructor simple irrelevant trivial needs_implicit
| | |-CXXRecordDecl 0xc7e73f8 <col:1, col:7> col:7 implicit class Functor
| | `-FieldDecl 0xc7e7558 <line:4:4, col:38> col:17 PtrToMemberFunction 'void
(ObjT::*)() __attribute__((thiscall))'
| `-ClassTemplateSpecializationDecl 0xe986ad0 <line:1:1, line:5:1> line:2:7
class Functor definition
|   |-DefinitionData pass_in_registers standard_layout trivially_copyable
trivial literal
|   | |-DefaultConstructor exists trivial
|   | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
|   | |-MoveConstructor exists simple trivial
|   | |-CopyAssignment trivial has_const_param needs_implicit
implicit_has_const_param
|   | |-MoveAssignment exists simple trivial needs_implicit
|   | `-Destructor simple irrelevant trivial
|   |-TemplateArgument type 'DerivedFunctor<void>'
|   |-CXXRecordDecl 0xe986c40 prev 0xe986ad0 <col:1, col:7> col:7 implicit
class Functor
|   |-FieldDecl 0xe986d70 <line:4:4, col:38> col:17 PtrToMemberFunction 'void
(DerivedFunctor<void>::*)() __attribute__((thiscall))'
|   |-CXXConstructorDecl 0xe986f10 <line:2:7> col:7 implicit used Functor 'void
() __attribute__((thiscall)) noexcept' inline default trivial
|   | `-CompoundStmt 0xe9874e0 <col:7>
|   |-CXXDestructorDecl 0xe986fb0 <col:7> col:7 implicit ~Functor 'void ()
__attribute__((thiscall))' inline default trivial noexcept-unevaluated
0xe986fb0
|   |-CXXConstructorDecl 0xe987078 <col:7> col:7 implicit constexpr Functor
'void (const Functor<DerivedFunctor<void> > &) __attribute__((thiscall))'
inline default trivial noexcept-unevaluated 0xe987078
|   | `-ParmVarDecl 0xe987138 <col:7> col:7 'const Functor<DerivedFunctor<void>
<span class="quote">> &'</span >
|   `-CXXConstructorDecl 0xe987198 <col:7> col:7 implicit constexpr Functor
'void (Functor<DerivedFunctor<void> > &&) __attribute__((thiscall))' inline
default trivial noexcept-unevaluated 0xe987198
|     `-ParmVarDecl 0xe987258 <col:7> col:7 'Functor<DerivedFunctor<void> > &&'
|-ClassTemplateDecl 0xc7e7650 <line:7:1, col:35> col:35 DerivedFunctor
| |-TemplateTypeParmDecl 0xc7e7598 <col:10, col:19> col:19 typename depth 0
index 0 SomeType
| |-CXXRecordDecl 0xc7e75f0 <col:29, col:35> col:35 class DerivedFunctor
| `-ClassTemplateSpecializationDecl 0xe986840 <line:9:1, line:13:1> line:10:7
class DerivedFunctor definition
|   |-DefinitionData pass_in_registers standard_layout trivially_copyable
trivial literal
|   | |-DefaultConstructor exists trivial
|   | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
|   | |-MoveConstructor exists simple trivial
|   | |-CopyAssignment trivial has_const_param needs_implicit
implicit_has_const_param
|   | |-MoveAssignment exists simple trivial needs_implicit
|   | `-Destructor simple irrelevant trivial needs_implicit
|   |-public 'Functor<DerivedFunctor<void> >':'Functor<DerivedFunctor<void> >'
|   |-TemplateArgument type 'void'
|   |-MSInheritanceAttr 0xe986d40 <line:9:1, line:13:1> Implicit
__single_inheritance BestCase
|   |-CXXRecordDecl 0xe986de0 prev 0xe986840 <line:10:1, col:7> col:7 implicit
class DerivedFunctor
|   |-CXXConstructorDecl 0xe986e60 <col:7> col:7 implicit used DerivedFunctor
'void () __attribute__((thiscall)) noexcept' inline default trivial
|   | |-CXXCtorInitializer 'Functor<DerivedFunctor<void>
<span class="quote">>':'Functor<DerivedFunctor<void> >'</span >
|   | | `-CXXConstructExpr 0xe9874f0 <col:7> 'Functor<DerivedFunctor<void>
<span class="quote">>':'Functor<DerivedFunctor<void> >' 'void () __attribute__((thiscall))</span >
noexcept'
|   | `-CompoundStmt 0xe987590 <col:7>
|   |-CXXConstructorDecl 0xe987298 <col:7> col:7 implicit constexpr
DerivedFunctor 'void (const DerivedFunctor<void> &) __attribute__((thiscall))'
inline default trivial noexcept-unevaluated 0xe987298
|   | `-ParmVarDecl 0xe987358 <col:7> col:7 'const DerivedFunctor<void> &'
|   `-CXXConstructorDecl 0xe9873b8 <col:7> col:7 implicit constexpr
DerivedFunctor 'void (DerivedFunctor<void> &&) __attribute__((thiscall))'
inline default trivial noexcept-unevaluated 0xe9873b8
|     `-ParmVarDecl 0xe987478 <col:7> col:7 'DerivedFunctor<void> &&'
|-ClassTemplateDecl 0xc7e7860 prev 0xc7e7650 <line:9:1, line:13:1> line:10:7
DerivedFunctor
| |-TemplateTypeParmDecl 0xc7e77a8 <line:9:10, col:19> col:19 referenced
typename depth 0 index 0 SomeType
| |-CXXRecordDecl 0xc7e7800 prev 0xc7e75f0 <line:10:1, line:13:1> line:10:7
class DerivedFunctor definition
| | |-DefinitionData pass_in_registers empty standard_layout trivially_copyable
trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
| | | |-DefaultConstructor exists trivial constexpr needs_implicit
defaulted_is_constexpr
| | | |-CopyConstructor simple trivial has_const_param needs_implicit
implicit_has_const_param
| | | |-MoveConstructor exists simple trivial needs_implicit
| | | |-CopyAssignment trivial has_const_param needs_implicit
implicit_has_const_param
| | | |-MoveAssignment exists simple trivial needs_implicit
| | | `-Destructor simple irrelevant trivial needs_implicit
| | |-public 'Functor<DerivedFunctor<SomeType> >'
| | `-CXXRecordDecl 0xe9867c0 <col:1, col:7> col:7 implicit class
DerivedFunctor
| `-ClassTemplateSpecialization 0xe986840 'DerivedFunctor'
`-VarDecl 0xe986988 <line:15:1, col:22> col:22 AFunctor
'DerivedFunctor<void>':'DerivedFunctor<void>' callinit
  `-CXXConstructExpr 0xe9875a0 <col:22>
'DerivedFunctor<void>':'DerivedFunctor<void>' 'void ()
__attribute__((thiscall)) noexcept'

The problem occurs because assignInheritanceModel() is called on the "class
DerivedFunctor" CXXRecordDecl, when it is the RD returned by
MPTy->getMostRecentCXXRecordDecl():

<span class="quote">>        clang-cpp.exe!assignInheritanceModel(clang::Sema & S, clang::CXXRecordDecl * RD) Line 7544  C++</span >
       
clang-cpp.exe!clang::Sema::RequireCompleteTypeImpl(clang::SourceLocation Loc,
clang::QualType T, clang::Sema::TypeDiagnoser * Diagnoser) Line 7591      C++
        clang-cpp.exe!clang::Sema::RequireCompleteType(clang::SourceLocation
Loc, clang::QualType T, clang::Sema::TypeDiagnoser & Diagnoser) Line 7449  C++
        clang-cpp.exe!clang::Sema::RequireCompleteType(clang::SourceLocation
Loc, clang::QualType T, unsigned int DiagID) Line 7750     C++
        clang-cpp.exe!clang::Sema::CheckFieldDecl(clang::DeclarationName Name,
clang::QualType T, clang::TypeSourceInfo * TInfo, clang::RecordDecl * Record,
clang::SourceLocation Loc, bool Mutable, clang::Expr * BitWidth,
clang::InClassInitStyle InitStyle, clang::SourceLocation TSSL,
clang::AccessSpecifier AS, clang::NamedDecl * PrevDecl, clang::Declarator * D)
Line 14886  C++
       
clang-cpp.exe!clang::TemplateDeclInstantiator::VisitFieldDecl(clang::FieldDecl
* D) Line 804    C++
       
clang-cpp.exe!clang::declvisitor::Base<clang::declvisitor::make_ptr,clang::TemplateDeclInstantiator,clang::Decl
*>::Visit(clang::Decl * D) Line 369     C++
        clang-cpp.exe!clang::Sema::InstantiateClass(clang::SourceLocation
PointOfInstantiation, clang::CXXRecordDecl * Instantiation,
clang::CXXRecordDecl * Pattern, const clang::MultiLevelTemplateArgumentList &
TemplateArgs, clang::TemplateSpecializationKind TSK, bool Complain) Line 2091  
    C++
       
clang-cpp.exe!clang::Sema::InstantiateClassTemplateSpecialization(clang::SourceLocation
PointOfInstantiation, clang::ClassTemplateSpecializationDecl *
ClassTemplateSpec, clang::TemplateSpecializationKind TSK, bool Complain) Line
2542       C++
       
clang-cpp.exe!clang::Sema::RequireCompleteTypeImpl(clang::SourceLocation Loc,
clang::QualType T, clang::Sema::TypeDiagnoser * Diagnoser) Line 7683      C++
        clang-cpp.exe!clang::Sema::RequireCompleteType(clang::SourceLocation
Loc, clang::QualType T, clang::Sema::TypeDiagnoser & Diagnoser) Line 7449  C++
       
clang-cpp.exe!clang::Sema::RequireCompleteType<clang::SourceRange>(clang::SourceLocation
Loc, clang::QualType T, unsigned int DiagID, const clang::SourceRange &
<Args_0>) Line 1616    C++
        clang-cpp.exe!clang::Sema::CheckBaseSpecifier(clang::CXXRecordDecl *
Class, clang::SourceRange SpecifierRange, bool Virtual, clang::AccessSpecifier
Access, clang::TypeSourceInfo * TInfo, clang::SourceLocation EllipsisLoc) Line
2220 C++
        clang-cpp.exe!clang::Sema::SubstBaseSpecifiers(clang::CXXRecordDecl *
Instantiation, clang::CXXRecordDecl * Pattern, const
clang::MultiLevelTemplateArgumentList & TemplateArgs) Line 1950      C++
        clang-cpp.exe!clang::Sema::InstantiateClass(clang::SourceLocation
PointOfInstantiation, clang::CXXRecordDecl * Instantiation,
clang::CXXRecordDecl * Pattern, const clang::MultiLevelTemplateArgumentList &
TemplateArgs, clang::TemplateSpecializationKind TSK, bool Complain) Line 2064  
    C++
       
clang-cpp.exe!clang::Sema::InstantiateClassTemplateSpecialization(clang::SourceLocation
PointOfInstantiation, clang::ClassTemplateSpecializationDecl *
ClassTemplateSpec, clang::TemplateSpecializationKind TSK, bool Complain) Line
2542       C++
       
clang-cpp.exe!clang::Sema::RequireCompleteTypeImpl(clang::SourceLocation Loc,
clang::QualType T, clang::Sema::TypeDiagnoser * Diagnoser) Line 7683      C++
        clang-cpp.exe!clang::Sema::RequireCompleteType(clang::SourceLocation
Loc, clang::QualType T, clang::Sema::TypeDiagnoser & Diagnoser) Line 7449  C++
        clang-cpp.exe!clang::Sema::RequireCompleteType(clang::SourceLocation
Loc, clang::QualType T, unsigned int DiagID) Line 7750     C++
        clang-cpp.exe!clang::Sema::ActOnUninitializedDecl(clang::Decl *
RealDecl) Line 11197    C++
       
clang-cpp.exe!clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator
& D, const clang::Parser::ParsedTemplateInfo & TemplateInfo,
clang::Parser::ForRangeInit * FRI) Line 2372   C++
        clang-cpp.exe!clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec &
DS, clang::DeclaratorContext Context, clang::SourceLocation * DeclEnd,
clang::Parser::ForRangeInit * FRI) Line 2042        C++
       
clang-cpp.exe!clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange
& attrs, clang::ParsingDeclSpec & DS, clang::AccessSpecifier AS) Line 1012 C++
       
clang-cpp.exe!clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange
& attrs, clang::ParsingDeclSpec * DS, clang::AccessSpecifier AS) Line 1028  
C++
       
clang-cpp.exe!clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange
& attrs, clang::ParsingDeclSpec * DS) Line 853   C++
       
clang-cpp.exe!clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>
& Result) Line 609 C++
        clang-cpp.exe!clang::ParseAST(clang::Sema & S, bool PrintStats, bool
SkipFunctionBodies) Line 152       C++
        clang-cpp.exe!clang::ASTFrontendAction::ExecuteAction() Line 1005      
C++
        clang-cpp.exe!clang::CodeGenAction::ExecuteAction() Line 1044   C++
        clang-cpp.exe!clang::FrontendAction::Execute() Line 904 C++
       
clang-cpp.exe!clang::CompilerInstance::ExecuteAction(clang::FrontendAction &
Act) Line 990      C++
        clang-cpp.exe!clang::ExecuteCompilerInvocation(clang::CompilerInstance
* Clang) Line 255        C++
        clang-cpp.exe!cc1_main(llvm::ArrayRef<char const *> Argv, const char *
Argv0, void * MainAddr) Line 222 C++
        clang-cpp.exe!ExecuteCC1Tool(llvm::ArrayRef<char const *> argv,
llvm::StringRef Tool) Line 310  C++

but then the "implicit class DerivedFunctor" CXXRecordDecl is added as the
'latest' decl (returned by MPTy->getMostRecentCXXRecordDecl()), as the template
is instantiated:

<span class="quote">>        clang-cpp.exe!llvm::PointerIntPair<void *,1,bool,llvm::PointerUnionUIntTraits<llvm::PointerUnion<clang::Decl *,void const *>,clang::LazyGenerationalUpdatePtr<clang::Decl const *,clang::Decl *,{clang::ExternalASTSource::`vcall'{60}',0}> >,llvm::PointerIntPairInfo<void *,1,llvm::PointerUnionUIntTraits<llvm::PointerUnion<clang::Decl *,void const *>,clang::LazyGenerationalUpdatePtr<clang::Decl const *,clang::Decl *,{clang::ExternalASTSource::`vcall'{60}',0}> > > >::setPointerAndInt(void * PtrVal, bool IntVal) Line 75  C++</span >
        clang-cpp.exe!llvm::PointerUnion<llvm::PointerUnion<clang::Decl *,void
const *>,clang::LazyGenerationalUpdatePtr<clang::Decl const *,clang::Decl
*,{clang::ExternalASTSource::`vcall'{60}',0}> >::operator=(const
clang::LazyGenerationalUpdatePtr<clang::Decl const *,clang::Decl
*,{clang::ExternalASTSource::`vcall'{60}',0}> & RHS) Line 182        C++
       
clang-cpp.exe!clang::Redeclarable<clang::TagDecl>::DeclLink::setLatest(clang::TagDecl
* D) Line 159     C++
       
clang-cpp.exe!clang::Redeclarable<clang::TagDecl>::setPreviousDecl(clang::TagDecl
* PrevDecl) Line 4285 C++
        clang-cpp.exe!clang::TagDecl::TagDecl(clang::Decl::Kind DK,
clang::TagTypeKind TK, const clang::ASTContext & C, clang::DeclContext * DC,
clang::SourceLocation L, clang::IdentifierInfo * Id, clang::TagDecl * PrevDecl,
clang::SourceLocation StartL) Line 3093        C++
        clang-cpp.exe!clang::RecordDecl::RecordDecl(clang::Decl::Kind DK,
clang::TagTypeKind TK, const clang::ASTContext & C, clang::DeclContext * DC,
clang::SourceLocation StartLoc, clang::SourceLocation IdLoc,
clang::IdentifierInfo * Id, clang::RecordDecl * PrevDecl) Line 3968 C++
        clang-cpp.exe!clang::CXXRecordDecl::CXXRecordDecl(clang::Decl::Kind K,
clang::TagTypeKind TK, const clang::ASTContext & C, clang::DeclContext * DC,
clang::SourceLocation StartLoc, clang::SourceLocation IdLoc,
clang::IdentifierInfo * Id, clang::CXXRecordDecl * PrevDecl) Line 122  C++
        clang-cpp.exe!clang::CXXRecordDecl::Create(const clang::ASTContext & C,
clang::TagTypeKind TK, clang::DeclContext * DC, clang::SourceLocation StartLoc,
clang::SourceLocation IdLoc, clang::IdentifierInfo * Id, clang::CXXRecordDecl *
PrevDecl, bool DelayTypeCreation) Line 129      C++
       
clang-cpp.exe!clang::TemplateDeclInstantiator::VisitCXXRecordDecl(clang::CXXRecordDecl
* D) Line 1489   C++
       
clang-cpp.exe!clang::declvisitor::Base<clang::declvisitor::make_ptr,clang::TemplateDeclInstantiator,clang::Decl
*>::Visit(clang::Decl * D) Line 251     C++
        clang-cpp.exe!clang::Sema::InstantiateClass(clang::SourceLocation
PointOfInstantiation, clang::CXXRecordDecl * Instantiation,
clang::CXXRecordDecl * Pattern, const clang::MultiLevelTemplateArgumentList &
TemplateArgs, clang::TemplateSpecializationKind TSK, bool Complain) Line 2091  
    C++
       
clang-cpp.exe!clang::Sema::InstantiateClassTemplateSpecialization(clang::SourceLocation
PointOfInstantiation, clang::ClassTemplateSpecializationDecl *
ClassTemplateSpec, clang::TemplateSpecializationKind TSK, bool Complain) Line
2542       C++
       
clang-cpp.exe!clang::Sema::RequireCompleteTypeImpl(clang::SourceLocation Loc,
clang::QualType T, clang::Sema::TypeDiagnoser * Diagnoser) Line 7683      C++
        clang-cpp.exe!clang::Sema::RequireCompleteType(clang::SourceLocation
Loc, clang::QualType T, clang::Sema::TypeDiagnoser & Diagnoser) Line 7449  C++
        clang-cpp.exe!clang::Sema::RequireCompleteType(clang::SourceLocation
Loc, clang::QualType T, unsigned int DiagID) Line 7750     C++
        clang-cpp.exe!clang::Sema::ActOnUninitializedDecl(clang::Decl *
RealDecl) Line 11197    C++
       
clang-cpp.exe!clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator
& D, const clang::Parser::ParsedTemplateInfo & TemplateInfo,
clang::Parser::ForRangeInit * FRI) Line 2372   C++
        clang-cpp.exe!clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec &
DS, clang::DeclaratorContext Context, clang::SourceLocation * DeclEnd,
clang::Parser::ForRangeInit * FRI) Line 2042        C++
       
clang-cpp.exe!clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange
& attrs, clang::ParsingDeclSpec & DS, clang::AccessSpecifier AS) Line 1012 C++
       
clang-cpp.exe!clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange
& attrs, clang::ParsingDeclSpec * DS, clang::AccessSpecifier AS) Line 1028  
C++
       
clang-cpp.exe!clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange
& attrs, clang::ParsingDeclSpec * DS) Line 853   C++
       
clang-cpp.exe!clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>
& Result) Line 609 C++
        clang-cpp.exe!clang::ParseAST(clang::Sema & S, bool PrintStats, bool
SkipFunctionBodies) Line 152       C++
        clang-cpp.exe!clang::ASTFrontendAction::ExecuteAction() Line 1005      
C++
        clang-cpp.exe!clang::CodeGenAction::ExecuteAction() Line 1044   C++
        clang-cpp.exe!clang::FrontendAction::Execute() Line 904 C++
       
clang-cpp.exe!clang::CompilerInstance::ExecuteAction(clang::FrontendAction &
Act) Line 990      C++
        clang-cpp.exe!clang::ExecuteCompilerInvocation(clang::CompilerInstance
* Clang) Line 255        C++
        clang-cpp.exe!cc1_main(llvm::ArrayRef<char const *> Argv, const char *
Argv0, void * MainAddr) Line 222 C++
        clang-cpp.exe!ExecuteCC1Tool(llvm::ArrayRef<char const *> argv,
llvm::StringRef Tool) Line 310  C++

Since the "implicit class DerivedFunctor" CXXRecordDecl doesn't have a
MSInheritanceAttr (but the "class DerivedFunctor" CXXRecordDecl does), when the
"implicit class DerivedFunctor" CXXRecordDecl is later selected by
MPTy->getMostRecentCXXRecordDecl() no MSInheritanceAttr can be found.

I debugged this and TemplateDeclInstantiator::VisitCXXRecordDecl() looks like
an ideal place to move information forward from the "class DerivedFunctor"
CXXRecordDecl to the "implicit class DerivedFunctor" CXXRecordDecl. I have
created a fix which calls back into the semantic analysis code and check if the
previous decl has a MSInheritanceAttr, and if so to just add a
MSInheritanceAttr to the new decl being created.

<span class="quote">>        clang-cpp.exe!clang::Sema::CheckCXXRecordDecl(clang::CXXRecordDecl * Record, clang::CXXRecordDecl * Prev) Line 7083     C++</span >
       
clang-cpp.exe!clang::TemplateDeclInstantiator::VisitCXXRecordDecl(clang::CXXRecordDecl
* D) Line 1556   C++
       
clang-cpp.exe!clang::declvisitor::Base<clang::declvisitor::make_ptr,clang::TemplateDeclInstantiator,clang::Decl
*>::Visit(clang::Decl * D) Line 251     C++
        clang-cpp.exe!clang::Sema::InstantiateClass(clang::SourceLocation
PointOfInstantiation, clang::CXXRecordDecl * Instantiation,
clang::CXXRecordDecl * Pattern, const clang::MultiLevelTemplateArgumentList &
TemplateArgs, clang::TemplateSpecializationKind TSK, bool Complain) Line 2091  
    C++
       
clang-cpp.exe!clang::Sema::InstantiateClassTemplateSpecialization(clang::SourceLocation
PointOfInstantiation, clang::ClassTemplateSpecializationDecl *
ClassTemplateSpec, clang::TemplateSpecializationKind TSK, bool Complain) Line
2542       C++
       
clang-cpp.exe!clang::Sema::RequireCompleteTypeImpl(clang::SourceLocation Loc,
clang::QualType T, clang::Sema::TypeDiagnoser * Diagnoser) Line 7683      C++
        clang-cpp.exe!clang::Sema::RequireCompleteType(clang::SourceLocation
Loc, clang::QualType T, clang::Sema::TypeDiagnoser & Diagnoser) Line 7449  C++
        clang-cpp.exe!clang::Sema::RequireCompleteType(clang::SourceLocation
Loc, clang::QualType T, unsigned int DiagID) Line 7750     C++
        clang-cpp.exe!clang::Sema::ActOnUninitializedDecl(clang::Decl *
RealDecl) Line 11197    C++
       
clang-cpp.exe!clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator
& D, const clang::Parser::ParsedTemplateInfo & TemplateInfo,
clang::Parser::ForRangeInit * FRI) Line 2372   C++
        clang-cpp.exe!clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec &
DS, clang::DeclaratorContext Context, clang::SourceLocation * DeclEnd,
clang::Parser::ForRangeInit * FRI) Line 2042        C++
       
clang-cpp.exe!clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange
& attrs, clang::ParsingDeclSpec & DS, clang::AccessSpecifier AS) Line 1012 C++
       
clang-cpp.exe!clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange
& attrs, clang::ParsingDeclSpec * DS, clang::AccessSpecifier AS) Line 1028  
C++
       
clang-cpp.exe!clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange
& attrs, clang::ParsingDeclSpec * DS) Line 853   C++
       
clang-cpp.exe!clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>
& Result) Line 609 C++
        clang-cpp.exe!clang::ParseAST(clang::Sema & S, bool PrintStats, bool
SkipFunctionBodies) Line 152       C++
        clang-cpp.exe!clang::ASTFrontendAction::ExecuteAction() Line 1005      
C++
        clang-cpp.exe!clang::CodeGenAction::ExecuteAction() Line 1044   C++
        clang-cpp.exe!clang::FrontendAction::Execute() Line 904 C++
       
clang-cpp.exe!clang::CompilerInstance::ExecuteAction(clang::FrontendAction &
Act) Line 990      C++
        clang-cpp.exe!clang::ExecuteCompilerInvocation(clang::CompilerInstance
* Clang) Line 255        C++
        clang-cpp.exe!cc1_main(llvm::ArrayRef<char const *> Argv, const char *
Argv0, void * MainAddr) Line 222 C++
        clang-cpp.exe!ExecuteCC1Tool(llvm::ArrayRef<char const *> argv,
llvm::StringRef Tool) Line 310  C++

This fix resolves this crash, which was hit over multiple different source
files in some code I'mm porting to build with clang / MS ABI.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>