The bug was found while building llvm self-hosted with modules. The problem is when having one module built, then a use causes the first modules to be deserialized. And when the second module is being created with the same information as in the first module the assertion is triggered. cd /home/biancacr/clang_build_/objmod/lib/CodeGen && /home/biancacr/clang_build_/inst/bin/clang++ -DGTEST_HAS_RTTI=0 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/biancacr/clang_build_/objmod/lib/CodeGen -I/home/biancacr/clang_build_/src/lib/CodeGen -I/home/biancacr/clang_build_/objmod/include -I/home/biancacr/clang_build_/src/include -stdlib=libstdc++ -fPIC -fvisibility-inlines-hidden -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Werror=date-time -std=c++11 -fmodules -Xclang -fmodules-local-submodule-visibility -fmodules-cache-path=module.cache -ffunction-sections -fdata-sections -O3 -DNDEBUG -fno-exceptions -fno-rtti -o CMakeFiles/LLVMCodeGen.dir/CodeGenPrepare.cpp.o -c /home/biancacr/clang_build_/src/lib/CodeGen/CodeGenPrepare.cpp clang-3.9: /home/biancacr/clang_build_/src/tools/clang/lib/Serialization/ASTWriter.cpp:5718: virtual void clang::ASTWriter::ResolvedExceptionSpec(const clang::FunctionDecl*): Assertion `!DoneWritingDeclsAndTypes && "Already done writing updates!"' failed. #0 0x00000000013a5468 llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x13a5468) #1 0x00000000013a3206 llvm::sys::RunSignalHandlers() (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x13a3206) #2 0x00000000013a343c SignalHandler(int) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x13a343c) #3 0x00007f6a612e6d10 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x10d10) #4 0x00007f6a604fe1c7 gsignal /build/glibc-qbmteM/glibc-2.21/signal/../sysdeps/unix/sysv/linux/raise.c:55:0 #5 0x00007f6a604ffe2a abort /build/glibc-qbmteM/glibc-2.21/stdlib/abort.c:91:0 #6 0x00007f6a604f70bd __assert_fail_base /build/glibc-qbmteM/glibc-2.21/assert/assert.c:92:0 #7 0x00007f6a604f7172 (/lib/x86_64-linux-gnu/libc.so.6+0x2e172) #8 0x000000000203ad75 clang::ASTWriter::ResolvedExceptionSpec(clang::FunctionDecl const*) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x203ad75) #9 0x00000000018606c8 clang::MultiplexASTMutationListener::ResolvedExceptionSpec(clang::FunctionDecl const*) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x18606c8) #10 0x0000000001fa064e clang::ASTReader::FinishedDeserializing() [clone .part.2455] (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x1fa064e) #11 0x0000000001fa7483 clang::ASTReader::FindExternalVisibleDeclsByName(clang::DeclContext const*, clang::DeclarationName) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x1fa7483) #12 0x0000000002990911 clang::DeclContext::lookup(clang::DeclarationName) const (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x2990911) #13 0x000000000203615b clang::ASTWriter::GenerateNameLookupTable(clang::DeclContext const*, llvm::SmallVectorImpl<char>&) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x203615b) #14 0x0000000002037b7d clang::ASTWriter::WriteDeclContextVisibleUpdate(clang::DeclContext const*) [clone .part.3192] (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x2037b7d) #15 0x000000000203d310 clang::ASTWriter::WriteASTCore(clang::Sema&, llvm::StringRef, std::string const&, clang::Module*) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x203d310) #16 0x000000000203e29e clang::ASTWriter::WriteAST(clang::Sema&, std::string const&, clang::Module*, llvm::StringRef, bool) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x203e29e) #17 0x000000000205da67 clang::PCHGenerator::HandleTranslationUnit(clang::ASTContext&) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x205da67) #18 0x0000000001860c78 clang::MultiplexConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x1860c78) #19 0x0000000001ec382d clang::ParseAST(clang::Sema&, bool, bool) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x1ec382d) #20 0x000000000183b3ae clang::FrontendAction::Execute() (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x183b3ae) #21 0x00000000018102e6 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x18102e6) #22 0x0000000002bef8d1 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x2bef8d1) #23 0x0000000002bef974 RunSafelyOnThread_Dispatch(void*) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x2bef974) #24 0x00000000013a674d ExecuteOnThread_Dispatch(void*) (/home/biancacr/clang_build_/inst/bin/clang-3.9+0x13a674d) #25 0x00007f6a612dd6aa start_thread /build/glibc-qbmteM/glibc-2.21/nptl/pthread_create.c:333:0 #26 0x00007f6a605d013d clone /build/glibc-qbmteM/glibc-2.21/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:111:0 Stack dump: 0. <eof> parser at end of file clang-3.9: error: unable to execute command: Aborted (core dumped) clang-3.9: error: clang frontend command failed due to signal (use -v to see invocation)
Created attachment 16643 [details] Clang test suite reproducer.
We usually avoid these kinds of issues by either applying the update records in such a way that AST mutation listeners are not informed (which is incorrect if there are mutation listeners other than the AST writer), or by making the AST writer's mutation listener ignore mutations that come from AST files (which is not always detectable). Perhaps we should have a more general mechanism for this, such as an RAII object that turns off writing of update records in the AST writer, and is created for the duration of loading update records in the AST reader.
Fixed in r276473.