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