Skip to content

Commit

Permalink
Auto merge of #52474 - alexcrichton:better-lto-error, r=eddyb
Browse files Browse the repository at this point in the history
rustc: Handle linker diagnostics 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.
  • Loading branch information
bors committed Aug 1, 2018
2 parents 8c069ce + f0bceba commit 11f812a
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 8 deletions.
12 changes: 10 additions & 2 deletions src/librustc_codegen_llvm/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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
Expand Down
13 changes: 7 additions & 6 deletions src/librustc_codegen_llvm/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 _);
Expand Down Expand Up @@ -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(..) => {},
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_codegen_llvm/llvm/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -168,6 +169,9 @@ impl Diagnostic<'ll> {
Dk::PGOProfile => {
PGO(di)
}
Dk::Linker => {
Linker(di)
}

_ => UnknownDiagnostic(di),
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_codegen_llvm/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ pub enum DiagnosticKind {
OptimizationRemarkOther,
OptimizationFailure,
PGOProfile,
Linker,
}

/// LLVMRustArchiveKind
Expand Down
3 changes: 3 additions & 0 deletions src/rustllvm/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,7 @@ enum class LLVMRustDiagnosticKind {
OptimizationRemarkOther,
OptimizationFailure,
PGOProfile,
Linker,
};

static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
Expand All @@ -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
Expand Down
16 changes: 16 additions & 0 deletions src/test/compile-fail/auxiliary/lto-duplicate-symbols1.rs
Original file line number Diff line number Diff line change
@@ -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() {}
16 changes: 16 additions & 0 deletions src/test/compile-fail/auxiliary/lto-duplicate-symbols2.rs
Original file line number Diff line number Diff line change
@@ -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() {}
20 changes: 20 additions & 0 deletions src/test/compile-fail/lto-duplicate-symbols.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit 11f812a

Please sign in to comment.