From 4eac4cf5a9bb94fd948ced441a57edf42e579b7e Mon Sep 17 00:00:00 2001 From: Artem Belevich Date: Tue, 12 May 2015 17:44:15 +0000 Subject: [PATCH] Fixed double-free in case of module loading error. GetOutputStream() owns the stream it returns pointer to and the pointer should never be freed by us. When we fail to load and exit early, unique_ptr still holds the pointer and frees it which leads to compiler crash when CompilerInstance attempts to free it again. Added regression test for failed bitcode linking. Differential Revision: http://reviews.llvm.org/D9625 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237159 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenAction.cpp | 4 ++-- test/CodeGen/link-bitcode-file.c | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp index 075832f076..7216f94765 100644 --- a/lib/CodeGen/CodeGenAction.cpp +++ b/lib/CodeGen/CodeGenAction.cpp @@ -632,7 +632,7 @@ GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) { std::unique_ptr CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { BackendAction BA = static_cast(Act); - std::unique_ptr OS(GetOutputStream(CI, InFile, BA)); + raw_pwrite_stream *OS = GetOutputStream(CI, InFile, BA); if (BA != Backend_EmitNothing && !OS) return nullptr; @@ -669,7 +669,7 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::unique_ptr Result(new BackendConsumer( BA, CI.getDiagnostics(), CI.getCodeGenOpts(), CI.getTargetOpts(), CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, - LinkModuleToUse, OS.release(), *VMContext, CoverageInfo)); + LinkModuleToUse, OS, *VMContext, CoverageInfo)); BEConsumer = Result.get(); return std::move(Result); } diff --git a/test/CodeGen/link-bitcode-file.c b/test/CodeGen/link-bitcode-file.c index fb97b4d1f5..92b1a88ffb 100644 --- a/test/CodeGen/link-bitcode-file.c +++ b/test/CodeGen/link-bitcode-file.c @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -triple i386-pc-linux-gnu -DBITCODE -emit-llvm-bc -o %t.bc %s // RUN: %clang_cc1 -triple i386-pc-linux-gnu -mlink-bitcode-file %t.bc -O3 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NO-BC %s // RUN: not %clang_cc1 -triple i386-pc-linux-gnu -DBITCODE -mlink-bitcode-file %t.bc -O3 -emit-llvm -o - %s 2>&1 | FileCheck -check-prefix=CHECK-BC %s +// Make sure we deal with failure to load the file. +// RUN: not %clang_cc1 -triple i386-pc-linux-gnu -mlink-bitcode-file no-such-file.bc \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck -check-prefix=CHECK-NO-FILE %s int f(void); @@ -22,3 +25,5 @@ int g(void) { // CHECK-NO-BC-LABEL: define i32 @f #endif + +// CHECK-NO-FILE: fatal error: cannot open file 'no-such-file.bc' -- 2.40.0