]> granicus.if.org Git - clang/commitdiff
Make sure that vtables referenced from delay-parsed templates get referenced.
authorNico Weber <nicolasweber@gmx.de>
Fri, 15 Aug 2014 23:21:41 +0000 (23:21 +0000)
committerNico Weber <nicolasweber@gmx.de>
Fri, 15 Aug 2014 23:21:41 +0000 (23:21 +0000)
This fixes PR20671, see the bug for details. In short, ActOnTranslationUnit()
calls DefineUsedVTables() and only then PerformPendingInstantiations(). But
PerformPendingInstantiations() is what does delayed template parsing, so
vtables only references from late-parsed templates weren't marked used.

As a fix, move the SavePendingInstantiationsAndVTableUsesRAII in
PerformPendingInstantiations() up above the delayed template parsing code.
That way, vtables referenced from templates end up in the RAII object, and the
call to DefineUsedVTables() in PerformPendingInstantiations() marks them used.

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

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/CodeGenCXX/microsoft-abi-structors-delayed-template.cpp [new file with mode: 0644]

index b73c2b137c43e319ef9d74a5bf8a2ea5c138c64a..747eaf6d96fa966f575cb2bcc7cc9e0c05870fab 100644 (file)
@@ -3319,6 +3319,20 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
     return;
   }
 
+  // If we're performing recursive template instantiation, create our own
+  // queue of pending implicit instantiations that we will instantiate later,
+  // while we're still within our own instantiation context.
+  // This has to happen before LateTemplateParser below is called, so that
+  // it marks vtables used in late parsed templates as used.
+  SavePendingLocalImplicitInstantiationsRAII
+      SavedPendingLocalImplicitInstantiations(*this);
+  std::unique_ptr<SavePendingInstantiationsAndVTableUsesRAII>
+      SavePendingInstantiationsAndVTableUses;
+  if (Recursive) {
+    SavePendingInstantiationsAndVTableUses.reset(
+        new SavePendingInstantiationsAndVTableUsesRAII(*this));
+  }
+
   // Call the LateTemplateParser callback if there is a need to late parse
   // a templated function definition.
   if (!Pattern && PatternDecl->isLateTemplateParsed() &&
@@ -3350,6 +3364,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
       Function->setInvalidDecl();
     } else if (Function->getTemplateSpecializationKind()
                  == TSK_ExplicitInstantiationDefinition) {
+      assert(!Recursive);
       PendingInstantiations.push_back(
         std::make_pair(Function, PointOfInstantiation));
     }
@@ -3386,18 +3401,6 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
   // Copy the inner loc start from the pattern.
   Function->setInnerLocStart(PatternDecl->getInnerLocStart());
 
-  // If we're performing recursive template instantiation, create our own
-  // queue of pending implicit instantiations that we will instantiate later,
-  // while we're still within our own instantiation context.
-  SavePendingLocalImplicitInstantiationsRAII
-      SavedPendingLocalImplicitInstantiations(*this);
-  std::unique_ptr<SavePendingInstantiationsAndVTableUsesRAII>
-      SavePendingInstantiationsAndVTableUses;
-  if (Recursive) {
-    SavePendingInstantiationsAndVTableUses.reset(
-        new SavePendingInstantiationsAndVTableUsesRAII(*this));
-  }
-
   EnterExpressionEvaluationContext EvalContext(*this,
                                                Sema::PotentiallyEvaluated);
 
diff --git a/test/CodeGenCXX/microsoft-abi-structors-delayed-template.cpp b/test/CodeGenCXX/microsoft-abi-structors-delayed-template.cpp
new file mode 100644 (file)
index 0000000..f9e1880
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm -fdelayed-template-parsing -std=c++11 -o - -triple=i386-pc-win32 %s > %t
+// RUN: FileCheck %s < %t
+
+// PR20671
+namespace vtable_referenced_from_template {
+struct ImplicitCtor {
+  virtual ~ImplicitCtor();
+};
+template <class T> void foo(T t) { new ImplicitCtor; }
+void bar() { foo(0); }
+// CHECK: store {{.*}} @"\01??_7ImplicitCtor@vtable_referenced_from_template@@6B@"
+}