rsmith added a comment.

In https://reviews.llvm.org/D29753#688834, @bruno wrote:

> > It seems to me that the problem here is that `DeclMustBeEmitted` is not 
> > safe to call in the middle of deserialization if anything 
> > partially-deserialized might be reachable from the declaration we're 
> > querying, and yet we're currently calling it in that case.
>
> `DeclMustBeEmitted` name seems misleading since we does more than just 
> checking, it actually tries to emit stuff.


It doesn't emit anything itself. But like most AST interactions, it *can* 
trigger more declarations being imported lazily from an external AST source, 
which can in turn result in them being passed to the AST consumer. And that's 
why the serialization code generally has to be careful to not call unbounded 
operations on the AST, because it doesn't want to reenter itself. But in this 
case we're violating that principle.

> If it's a local module, shouldn't be everything already available? Do we have 
> non-deserialized items for a local module? Maybe I get the wrong idea of what 
> local means in this context..

With this patch, we're calling `DeclMustBeEmitted` in the *non-local* module 
case (where there can be non-deserialized items).

>> I don't see how this patch actually addresses that problem, though: if you 
>> build this testcase as a module instead of a PCH, won't it still fail in the 
>> same way that it does now?
> 
> `D->getImportedOwningModule` calls `isFromASTFile`, which refers to PCH and 
> modules, shouldn't it work for both then?

It only fixes the cases where `getImportedOwningModule` returns 0, which is the 
normal case for a PCH, but is rare for a declaration from a module.

> I couldn't come up with a testcase that triggered it for modules though.

Something like this triggers it for me:

  $ cat test/PCH/empty-def-fwd-struct.modulemap
  module M { header "empty-def-fwd-struct.h" }
  $ clang -cc1 -x c++ -std=c++14 -fmodules -emit-module -fmodule-name=M 
test/PCH/empty-def-fwd-struct.modulemap -o tmp.pcm
  $ cat use.cpp
  #include "test/PCH/empty-def-fwd-struct.h"
  $ clang -cc1 -x c++ -std=c++14 -fmodules -emit-llvm -fmodule-file=tmp.pcm 
use.cpp -o -
  clang: [...]/src/tools/clang/lib/AST/RecordLayoutBuilder.cpp:2933: const 
clang::ASTRecordLayout &clang::ASTContext::getASTRecordLayout(const 
clang::RecordDecl *) const: Assertion `D && "Cannot get layout of forward 
declarations!"' failed.



================
Comment at: test/PCH/empty-def-fwd-struct.h:2
+// RUN: %clang_cc1 -emit-pch -x c++-header %s -std=c++14 -o %t.pch
+// RUN: %clang_cc1 -emit-llvm -x c++ /dev/null -std=c++14 -include-pch %t.pch 
-o %t.o
+struct FVector;
----------------
Since you don't care about what's in the produced LLVM IR, you can use 
`-emit-llvm-only` instead here.


https://reviews.llvm.org/D29753



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to