about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2018-07-17 16:20:51 -0700
committerAlex Crichton <alex@alexcrichton.com>2018-07-31 10:47:27 -0700
commitf0bceba669159f7bac581d03412cf69ce4558685 (patch)
tree272b110894f0ea6ab0c5c8b786f10610eb7a7e7c
parentf89817997ac0aa100bf91997194ad85a7e59f743 (diff)
downloadrust-f0bceba669159f7bac581d03412cf69ce4558685.tar.gz
rust-f0bceba669159f7bac581d03412cf69ce4558685.zip
rustc: Handle linker diagnostic from LLVM
Previously linker diagnostic were being hidden when two modules were linked
together but failed to link. This commit fixes the situation by ensuring that we
have a diagnostic handler installed and also adds support for handling linker
diagnostics.
-rw-r--r--src/librustc_codegen_llvm/back/lto.rs12
-rw-r--r--src/librustc_codegen_llvm/back/write.rs13
-rw-r--r--src/librustc_codegen_llvm/llvm/diagnostic.rs4
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs1
-rw-r--r--src/rustllvm/RustWrapper.cpp3
-rw-r--r--src/test/compile-fail/auxiliary/lto-duplicate-symbols1.rs16
-rw-r--r--src/test/compile-fail/auxiliary/lto-duplicate-symbols2.rs16
-rw-r--r--src/test/compile-fail/lto-duplicate-symbols.rs20
8 files changed, 77 insertions, 8 deletions
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs
index daa2fb05280..b644422e795 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -11,7 +11,7 @@
 use back::bytecode::{DecodedBytecode, RLIB_BYTECODE_EXTENSION};
 use back::symbol_export;
 use back::write::{ModuleConfig, with_llvm_pmb, CodegenContext};
-use back::write;
+use back::write::{self, DiagnosticHandlers};
 use errors::{FatalError, Handler};
 use llvm::archive_ro::ArchiveRO;
 use llvm::{True, False};
@@ -234,9 +234,17 @@ fn fat_lto(cgcx: &CodegenContext,
     let module = modules.remove(costliest_module);
     let mut serialized_bitcode = Vec::new();
     {
-        let llmod = module.llvm().expect("can't lto pre-codegened modules").llmod();
+        let (llcx, llmod) = {
+            let llvm = module.llvm().expect("can't lto pre-codegened modules");
+            (&llvm.llcx, llvm.llmod())
+        };
         info!("using {:?} as a base module", module.llmod_id);
 
+        // The linking steps below may produce errors and diagnostics within LLVM
+        // which we'd like to handle and print, so set up our diagnostic handlers
+        // (which get unregistered when they go out of scope below).
+        let _handler = DiagnosticHandlers::new(cgcx, diag_handler, llcx);
+
         // For all other modules we codegened we'll need to link them into our own
         // bitcode. All modules were codegened in their own LLVM context, however,
         // and we want to move everything to the same LLVM context. Currently the
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index db044878fe7..209c3a23c5c 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -397,15 +397,15 @@ impl CodegenContext {
     }
 }
 
-struct DiagnosticHandlers<'a> {
+pub struct DiagnosticHandlers<'a> {
     data: *mut (&'a CodegenContext, &'a Handler),
     llcx: &'a llvm::Context,
 }
 
 impl<'a> DiagnosticHandlers<'a> {
-    fn new(cgcx: &'a CodegenContext,
-           handler: &'a Handler,
-           llcx: &'a llvm::Context) -> Self {
+    pub fn new(cgcx: &'a CodegenContext,
+               handler: &'a Handler,
+               llcx: &'a llvm::Context) -> Self {
         let data = Box::into_raw(Box::new((cgcx, handler)));
         unsafe {
             llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, data as *mut _);
@@ -475,10 +475,11 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
                                                 opt.message));
             }
         }
-        llvm::diagnostic::PGO(diagnostic_ref) => {
+        llvm::diagnostic::PGO(diagnostic_ref) |
+        llvm::diagnostic::Linker(diagnostic_ref) => {
             let msg = llvm::build_string(|s| {
                 llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s)
-            }).expect("non-UTF8 PGO diagnostic");
+            }).expect("non-UTF8 diagnostic");
             diag_handler.warn(&msg);
         }
         llvm::diagnostic::UnknownDiagnostic(..) => {},
diff --git a/src/librustc_codegen_llvm/llvm/diagnostic.rs b/src/librustc_codegen_llvm/llvm/diagnostic.rs
index 7f2a9d6984a..c41a5f74ae3 100644
--- a/src/librustc_codegen_llvm/llvm/diagnostic.rs
+++ b/src/librustc_codegen_llvm/llvm/diagnostic.rs
@@ -126,6 +126,7 @@ pub enum Diagnostic<'ll> {
     Optimization(OptimizationDiagnostic<'ll>),
     InlineAsm(InlineAsmDiagnostic<'ll>),
     PGO(&'ll DiagnosticInfo),
+    Linker(&'ll DiagnosticInfo),
 
     /// LLVM has other types that we do not wrap here.
     UnknownDiagnostic(&'ll DiagnosticInfo),
@@ -168,6 +169,9 @@ impl Diagnostic<'ll> {
             Dk::PGOProfile => {
                 PGO(di)
             }
+            Dk::Linker => {
+                Linker(di)
+            }
 
             _ => UnknownDiagnostic(di),
         }
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 898d3d67353..989498ea92b 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -332,6 +332,7 @@ pub enum DiagnosticKind {
     OptimizationRemarkOther,
     OptimizationFailure,
     PGOProfile,
+    Linker,
 }
 
 /// LLVMRustArchiveKind
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index f2b5297285c..4bcb4fd7ad3 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -984,6 +984,7 @@ enum class LLVMRustDiagnosticKind {
   OptimizationRemarkOther,
   OptimizationFailure,
   PGOProfile,
+  Linker,
 };
 
 static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
@@ -1008,6 +1009,8 @@ static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
     return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
   case DK_PGOProfile:
     return LLVMRustDiagnosticKind::PGOProfile;
+  case DK_Linker:
+    return LLVMRustDiagnosticKind::Linker;
   default:
     return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
                ? LLVMRustDiagnosticKind::OptimizationRemarkOther
diff --git a/src/test/compile-fail/auxiliary/lto-duplicate-symbols1.rs b/src/test/compile-fail/auxiliary/lto-duplicate-symbols1.rs
new file mode 100644
index 00000000000..ea09327bd19
--- /dev/null
+++ b/src/test/compile-fail/auxiliary/lto-duplicate-symbols1.rs
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+#[no_mangle]
+pub extern fn foo() {}
diff --git a/src/test/compile-fail/auxiliary/lto-duplicate-symbols2.rs b/src/test/compile-fail/auxiliary/lto-duplicate-symbols2.rs
new file mode 100644
index 00000000000..ea09327bd19
--- /dev/null
+++ b/src/test/compile-fail/auxiliary/lto-duplicate-symbols2.rs
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+
+#[no_mangle]
+pub extern fn foo() {}
diff --git a/src/test/compile-fail/lto-duplicate-symbols.rs b/src/test/compile-fail/lto-duplicate-symbols.rs
new file mode 100644
index 00000000000..9c1dbfc2af9
--- /dev/null
+++ b/src/test/compile-fail/lto-duplicate-symbols.rs
@@ -0,0 +1,20 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:lto-duplicate-symbols1.rs
+// aux-build:lto-duplicate-symbols2.rs
+// error-pattern:Linking globals named 'foo': symbol multiply defined!
+// compile-flags: -C lto
+// no-prefer-dynamic
+
+extern crate lto_duplicate_symbols1;
+extern crate lto_duplicate_symbols2;
+
+fn main() {}