On 1/29/16 12:50 PM, Serge Pavlov wrote:
Crash is observed when HandleTranslation unit is not called, clang always calls this method but a clang based project may don't call it if it is not needed. I saw the crash in such project and used this patch to fix it. I do not know how to make a regression test, I am not even sure such test would be practical. The fact that an object is owned by two unique_ptr's may be enought to change implementation. However any thoughts how to test this behavior are wellcome.
This is what the clang/unittests is for (i.e. you can write a testcase that doesn't have to go through the clang driver).
Jon
Thanks, --Serge 2016-01-30 0:54 GMT+06:00 Jonathan Roelofs <jonat...@codesourcery.com <mailto:jonat...@codesourcery.com>>: On 1/29/16 11:51 AM, Serge Pavlov via cfe-commits wrote: Can somebody have a look at this fix? Thank you! Testcase? --Serge 2016-01-11 23:50 GMT+06:00 Serge Pavlov <sepavl...@gmail.com <mailto:sepavl...@gmail.com> <mailto:sepavl...@gmail.com <mailto:sepavl...@gmail.com>>>: Any feedback? Thanks, --Serge 2015-12-11 20:24 GMT+06:00 Serge Pavlov <sepavl...@gmail.com <mailto:sepavl...@gmail.com> <mailto:sepavl...@gmail.com <mailto:sepavl...@gmail.com>>>: sepavloff created this revision. sepavloff added a subscriber: cfe-commits. Llvm module object is shared between CodeGenerator and BackendConsumer, in both classes it is stored as std::unique_ptr, which is not a good design solution and can cause double deletion error. Usually it does not occur because in BackendConsumer::HandleTranslationUnit the ownership of CodeGenerator over the module is taken away. If however this method is not called, the module is deleted twice and compiler crashes. As the module owned by BackendConsumer is always the same as CodeGenerator has, local copy of llvm module can be removed from BackendGenerator. http://reviews.llvm.org/D15450 Files: lib/CodeGen/CodeGenAction.cpp Index: lib/CodeGen/CodeGenAction.cpp =================================================================== --- lib/CodeGen/CodeGenAction.cpp +++ lib/CodeGen/CodeGenAction.cpp @@ -73,7 +73,6 @@ std::unique_ptr<CodeGenerator> Gen; - std::unique_ptr<llvm::Module> TheModule; SmallVector<std::pair<unsigned, std::unique_ptr<llvm::Module>>, 4> LinkModules; @@ -97,7 +96,10 @@ this->LinkModules.push_back( std::make_pair(I.first, std::unique_ptr<llvm::Module>(I.second))); } - std::unique_ptr<llvm::Module> takeModule() { return std::move(TheModule); } + llvm::Module *getModule() const { return Gen->GetModule(); } + std::unique_ptr<llvm::Module> takeModule() { + return std::unique_ptr<llvm::Module>(Gen->ReleaseModule()); + } void releaseLinkModules() { for (auto &I : LinkModules) I.second.release(); @@ -117,8 +119,6 @@ Gen->Initialize(Ctx); - TheModule.reset(Gen->GetModule()); - if (llvm::TimePassesIsEnabled) LLVMIRGeneration.stopTimer(); } @@ -165,27 +165,14 @@ } // Silently ignore if we weren't initialized for some reason. - if (!TheModule) - return; - - // Make sure IR generation is happy with the module. This is released by - // the module provider. - llvm::Module *M = Gen->ReleaseModule(); - if (!M) { - // The module has been released by IR gen on failures, do not double - // free. - TheModule.release(); + if (!getModule()) return; - } - - assert(TheModule.get() == M && - "Unexpected module change during IR generation"); // Link LinkModule into this module if present, preserving its validity. for (auto &I : LinkModules) { unsigned LinkFlags = I.first; llvm::Module *LinkModule = I.second.get(); - if (Linker::linkModules(*M, *LinkModule, + if (Linker::linkModules(*getModule(), *LinkModule, [=](const DiagnosticInfo &DI) { linkerDiagnosticHandler(DI, LinkModule, Diags); }, @@ -195,7 +182,7 @@ // Install an inline asm handler so that diagnostics get printed through // our diagnostics hooks. - LLVMContext &Ctx = TheModule->getContext(); + LLVMContext &Ctx = getModule()->getContext(); LLVMContext::InlineAsmDiagHandlerTy OldHandler = Ctx.getInlineAsmDiagnosticHandler(); void *OldContext = Ctx.getInlineAsmDiagnosticContext(); @@ -208,7 +195,7 @@ EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, C.getTargetInfo().getDataLayoutString(), - TheModule.get(), Action, AsmOutStream); + getModule(), Action, AsmOutStream); Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits -- Jon Roelofs jonat...@codesourcery.com <mailto:jonat...@codesourcery.com> CodeSourcery / Mentor Embedded
-- Jon Roelofs jonat...@codesourcery.com CodeSourcery / Mentor Embedded _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits