Fixed double-free in case of module loading error.
authorArtem Belevich <tra@google.com>
Tue, 12 May 2015 17:44:15 +0000 (17:44 +0000)
committerArtem Belevich <tra@google.com>
Tue, 12 May 2015 17:44:15 +0000 (17:44 +0000)
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
clang/test/CodeGen/link-bitcode-file.c

index 075832f..7216f94 100644 (file)
@@ -632,7 +632,7 @@ GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {
 std::unique_ptr<ASTConsumer>
 CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   BackendAction BA = static_cast<BackendAction>(Act);
-  std::unique_ptr<raw_pwrite_stream> 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<BackendConsumer> 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);
 }
index fb97b4d..92b1a88 100644 (file)
@@ -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'