<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Apr 22, 2016 at 11:46 AM, Reid Kleckner via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Fri Apr 22 13:46:33 2016<br>
New Revision: 267186<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=267186&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=267186&view=rev</a><br>
Log:<br>
Fix a bug involving deferred decl emission and PCH<br>
<br>
For various reasons, involving dllexport and class linkage compuations,<br>
we have to wait until after the semicolon after a class declaration to<br>
emit inline methods. These are "deferred" decls. Before this change,<br>
finishing the tag decl would trigger us to deserialize some PCH so that<br>
we could make a "pretty" IR-level type. Deserializing the PCH triggered<br>
calls to HandleTopLevelDecl, which, when done, checked the deferred decl<br>
list, and emitted some dllexported decls that weren't ready.<br>
<br>
Avoid this re-entrancy. Deferred decls should not get emitted when a tag<br>
is finished, they should only be emitted after a real top level decl in<br>
the main file.<br></blockquote><div><br></div><div>What if there is no subsequent top-level decl after such a call? It seems like the deferred decls won't be emitted at all in that case. Is that acceptable?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Added:<br>
    cfe/trunk/test/PCH/Inputs/pr27445.h<br>
    cfe/trunk/test/PCH/pr27445.cpp<br>
Modified:<br>
    cfe/trunk/lib/CodeGen/ModuleBuilder.cpp<br>
<br>
Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=267186&r1=267185&r2=267186&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=267186&r1=267185&r2=267186&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Fri Apr 22 13:46:33 2016<br>
@@ -36,13 +36,21 @@ namespace {<br>
     const CodeGenOptions CodeGenOpts;  // Intentionally copied in.<br>
<br>
     unsigned HandlingTopLevelDecls;<br>
+<br>
+    /// Use this when emitting decls to block re-entrant decl emission. It will<br>
+    /// emit all deferred decls on scope exit. Set EmitDeferred to false if decl<br>
+    /// emission must be deferred longer, like at the end of a tag definition.<br>
     struct HandlingTopLevelDeclRAII {<br>
       CodeGeneratorImpl &Self;<br>
-      HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self) : Self(Self) {<br>
+      bool EmitDeferred;<br>
+      HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,<br>
+                               bool EmitDeferred = true)<br>
+          : Self(Self), EmitDeferred(EmitDeferred) {<br>
         ++Self.HandlingTopLevelDecls;<br>
       }<br>
       ~HandlingTopLevelDeclRAII() {<br>
-        if (--Self.HandlingTopLevelDecls == 0)<br>
+        unsigned Level = --Self.HandlingTopLevelDecls;<br>
+        if (Level == 0 && EmitDeferred)<br>
           Self.EmitDeferredDecls();<br>
       }<br>
     };<br>
@@ -185,6 +193,10 @@ namespace {<br>
       if (Diags.hasErrorOccurred())<br>
         return;<br>
<br>
+      // Don't allow re-entrant calls to CodeGen triggered by PCH<br>
+      // deserialization to emit deferred decls.<br>
+      HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);<br>
+<br>
       Builder->UpdateCompletedType(D);<br>
<br>
       // For MSVC compatibility, treat declarations of static data members with<br>
@@ -214,6 +226,10 @@ namespace {<br>
       if (Diags.hasErrorOccurred())<br>
         return;<br>
<br>
+      // Don't allow re-entrant calls to CodeGen triggered by PCH<br>
+      // deserialization to emit deferred decls.<br>
+      HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);<br>
+<br>
       if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())<br>
         if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))<br>
           DI->completeRequiredType(RD);<br>
<br>
Added: cfe/trunk/test/PCH/Inputs/pr27445.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/Inputs/pr27445.h?rev=267186&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/Inputs/pr27445.h?rev=267186&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/PCH/Inputs/pr27445.h (added)<br>
+++ cfe/trunk/test/PCH/Inputs/pr27445.h Fri Apr 22 13:46:33 2016<br>
@@ -0,0 +1,4 @@<br>
+struct Info {<br>
+  virtual ~Info();<br>
+  void hash() {}<br>
+};<br>
<br>
Added: cfe/trunk/test/PCH/pr27445.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pr27445.cpp?rev=267186&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pr27445.cpp?rev=267186&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/PCH/pr27445.cpp (added)<br>
+++ cfe/trunk/test/PCH/pr27445.cpp Fri Apr 22 13:46:33 2016<br>
@@ -0,0 +1,14 @@<br>
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -x c++ %S/Inputs/pr27445.h -emit-pch -o %t.pch<br>
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions %s -include-pch %t.pch -emit-llvm -o - | FileCheck %s<br>
+<br>
+class A;<br>
+void fn1(A &) {}<br>
+<br>
+class __declspec(dllexport) A {<br>
+  int operator=(A) { return field_; }<br>
+  void (*on_arena_allocation_)(Info);<br>
+  int field_;<br>
+};<br>
+<br>
+// CHECK: %class.A = type { void (%struct.Info*)*, i32 }<br>
+// CHECK: %struct.Info = type { i32 (...)** }<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>