]> granicus.if.org Git - clang/commitdiff
Sema: delay the DLL exported member referencing
authorSaleem Abdulrasool <compnerd@compnerd.org>
Sat, 3 Dec 2016 01:57:47 +0000 (01:57 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Sat, 3 Dec 2016 01:57:47 +0000 (01:57 +0000)
An explicit template specialization can cause the implicit template
specialization of a type which inherits the attributes.  In such a case, we
would end up with a delayed template specialization for a dll exported type
which we would fail to reference.  This would trigger an assertion.

We now propagate the dll storage attributes through the inheritance
chain.  Only after having done so do we reference the delayed template
specializations.  This allows any implicit specializations which inherit dll
storage to also be referenced.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@288570 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
test/CodeGenCXX/windows-implicit-dllexport-template-specialization.cpp [new file with mode: 0644]

index 9a6434579f4dee61662d5ef792e0950930182f15..3438b5f89fffc33ed9d1c9bfd045e1bae6194cd2 100644 (file)
@@ -7687,7 +7687,6 @@ Sema::ActOnExplicitInstantiation(Scope *S,
         assert(DelayedDllExportClasses.empty() &&
                "delayed exports present at explicit instantiation");
         checkClassLevelDLLAttribute(Def);
-        referenceDLLExportedClassMethods();
 
         // Propagate attribute to base class templates.
         for (auto &B : Def->bases()) {
@@ -7695,6 +7694,8 @@ Sema::ActOnExplicitInstantiation(Scope *S,
                   B.getType()->getAsCXXRecordDecl()))
             propagateDLLAttrToBaseClassTemplate(Def, A, BT, B.getLocStart());
         }
+
+        referenceDLLExportedClassMethods();
       }
     }
 
diff --git a/test/CodeGenCXX/windows-implicit-dllexport-template-specialization.cpp b/test/CodeGenCXX/windows-implicit-dllexport-template-specialization.cpp
new file mode 100644 (file)
index 0000000..c2f2a07
--- /dev/null
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -triple i686-windows -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-MS
+// RUN: %clang_cc1 -std=c++11 -triple i686-windows-itanium -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-IA
+
+template <typename>
+struct s {};
+
+template <typename T_>
+class t : s<T_> {};
+
+extern template class t<char>;
+template class __declspec(dllexport) t<char>;
+
+// CHECK-MS: dllexport {{.*}} @"\01??4?$t@D@@QAEAAV0@ABV0@@Z"
+// CHECK-MS: dllexport {{.*}} @"\01??4?$s@D@@QAEAAU0@ABU0@@Z"
+
+// CHECK-IA: dllexport {{.*}} @_ZN1tIcEaSERKS0_
+// CHECK-IA: dllexport {{.*}} @_ZN1sIcEaSERKS0_
+