diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -10105,6 +10105,13 @@ ClassTemplate, CanonicalConverted, PrevDecl); SetNestedNameSpecifier(*this, Specialization, SS); + // A MSInheritanceAttr attached to the previous declaration must be + // propagated to the new node prior to instantiation. + if (PrevDecl && PrevDecl->hasAttr()) { + Specialization->addAttr(PrevDecl->getAttr()); + Consumer.AssignInheritanceModel(Specialization); + } + if (!HasNoEffect && !PrevDecl) { // Insert the new specialization. ClassTemplate->AddSpecialization(Specialization, InsertPos); @@ -10221,11 +10228,6 @@ dllExportImportClassTemplateSpecialization(*this, Def); } - if (Def->hasAttr()) { - Specialization->addAttr(Def->getAttr()); - Consumer.AssignInheritanceModel(Specialization); - } - // Set the template specialization kind. Make sure it is set before // instantiating the members which will trigger ASTConsumer callbacks. Specialization->setTemplateSpecializationKind(TSK); diff --git a/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp --- a/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck -allow-deprecated-dag-overlap %s // RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-extensions | FileCheck %s -check-prefix=X64 +// RUN: %clang_cc1 -std=c++17 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-extensions | FileCheck %s -check-prefix=X64 // RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify // RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify @@ -934,3 +935,25 @@ void A::printd() { JSMethod(); } // CHECK-LABEL: @"??$JSMethod@VA@PMFInTemplateArgument@@$1?printd@12@AAEHH@Z@PMFInTemplateArgument@@YAXXZ"( } + +namespace MissingMSInheritanceAttr { +// This is a regression test for an assertion failure that occurred when +// compiling for C++17. The issue concerned a failure to propagate a +// MSInheritanceAttr attribute for the explicit template instantiation +// definition prior to it being required to complete the specialization +// definition in order to determine its alignment so as to resolve a +// lookup for a deallocation function for the virtual destructor. +template +class a; +class b { + typedef void (a::*f)(); + f d; +}; +template +class a { + virtual ~a(); + b e; +}; +extern template class a; +template class a; +}