]> granicus.if.org Git - clang/commitdiff
Follow-up to r345699: Call CheckStaticLocalForDllExport later for templates
authorHans Wennborg <hans@hanshq.net>
Wed, 31 Oct 2018 10:34:46 +0000 (10:34 +0000)
committerHans Wennborg <hans@hanshq.net>
Wed, 31 Oct 2018 10:34:46 +0000 (10:34 +0000)
Calling it too early might cause dllimport to get inherited onto the
VarDecl before the initializer got attached. See the test case for an
example where this broke things.

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

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/CodeGenCXX/dllimport.cpp

index 1256a6bf5c2e61d7f1e5b495b75b98b2d9f173ac..4f7ecdfcdfda0cf60949493492088f643422080c 100644 (file)
@@ -728,9 +728,6 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D,
                           D->getLocation(), D->getIdentifier(), DI->getType(),
                           DI, D->getStorageClass());
 
-  if (Var->isStaticLocal())
-    SemaRef.CheckStaticLocalForDllExport(Var);
-
   // In ARC, infer 'retaining' for variables of retainable type.
   if (SemaRef.getLangOpts().ObjCAutoRefCount &&
       SemaRef.inferObjCARCLifetime(Var))
@@ -751,6 +748,9 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D,
 
   Var->setImplicit(D->isImplicit());
 
+  if (Var->isStaticLocal())
+    SemaRef.CheckStaticLocalForDllExport(Var);
+
   return Var;
 }
 
index 874f119a43c8bea7ae28cd09c4769531e76cacba..e9f0e4795f79870e67e8c526cf648a30259d185d 100644 (file)
@@ -1008,4 +1008,14 @@ template <typename> struct T { int foo() { static int x; return x++; } };
 extern template struct __declspec(dllimport) T<int>;
 int bar() { T<int> t; return t.foo(); }
 // MO1-DAG: @"?x@?{{1|2}}??foo@?$T@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = available_externally dllimport global i32 0, align 4
+
+template <typename T> struct __declspec(dllimport) U {
+  void foo() {
+    // Don't inherit dllimport to src before attaching the initializer.
+    static constexpr char src[] = {"hello"};
+    T arr[sizeof(src)];
+  }
+};
+void baz() { U<int> u; u.foo(); } // No diagnostic.
+
 }