r267186 - Fix a bug involving deferred decl emission and PCH

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 22 12:29:35 PDT 2016


On Fri, Apr 22, 2016 at 11:46 AM, Reid Kleckner via cfe-commits <
cfe-commits at 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 at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160422/f575c14b/attachment.html>


More information about the cfe-commits mailing list