From ed0577cc6d3a15b4951111e5565a2964b85ab8f4 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 llvm-svn: 237159 --- clang/lib/CodeGen/CodeGenAction.cpp | 4 ++-- clang/test/CodeGen/link-bitcode-file.c | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 075832f07655..7216f94765ef 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/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/clang/test/CodeGen/link-bitcode-file.c b/clang/test/CodeGen/link-bitcode-file.c index fb97b4d1f585..92b1a88ffb2d 100644 --- a/clang/test/CodeGen/link-bitcode-file.c +++ b/clang/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'