Skip to content

rustc: Handle linker diagnostics from LLVM #52474

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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() {}