Skip to content

Commit 11f812a

Browse files
committed
Auto merge of #52474 - alexcrichton:better-lto-error, r=eddyb
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.
2 parents 8c069ce + f0bceba commit 11f812a

File tree

8 files changed

+77
-8
lines changed

8 files changed

+77
-8
lines changed

src/librustc_codegen_llvm/back/lto.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use back::bytecode::{DecodedBytecode, RLIB_BYTECODE_EXTENSION};
1212
use back::symbol_export;
1313
use back::write::{ModuleConfig, with_llvm_pmb, CodegenContext};
14-
use back::write;
14+
use back::write::{self, DiagnosticHandlers};
1515
use errors::{FatalError, Handler};
1616
use llvm::archive_ro::ArchiveRO;
1717
use llvm::{True, False};
@@ -234,9 +234,17 @@ fn fat_lto(cgcx: &CodegenContext,
234234
let module = modules.remove(costliest_module);
235235
let mut serialized_bitcode = Vec::new();
236236
{
237-
let llmod = module.llvm().expect("can't lto pre-codegened modules").llmod();
237+
let (llcx, llmod) = {
238+
let llvm = module.llvm().expect("can't lto pre-codegened modules");
239+
(&llvm.llcx, llvm.llmod())
240+
};
238241
info!("using {:?} as a base module", module.llmod_id);
239242

243+
// The linking steps below may produce errors and diagnostics within LLVM
244+
// which we'd like to handle and print, so set up our diagnostic handlers
245+
// (which get unregistered when they go out of scope below).
246+
let _handler = DiagnosticHandlers::new(cgcx, diag_handler, llcx);
247+
240248
// For all other modules we codegened we'll need to link them into our own
241249
// bitcode. All modules were codegened in their own LLVM context, however,
242250
// and we want to move everything to the same LLVM context. Currently the

src/librustc_codegen_llvm/back/write.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -397,15 +397,15 @@ impl CodegenContext {
397397
}
398398
}
399399

400-
struct DiagnosticHandlers<'a> {
400+
pub struct DiagnosticHandlers<'a> {
401401
data: *mut (&'a CodegenContext, &'a Handler),
402402
llcx: &'a llvm::Context,
403403
}
404404

405405
impl<'a> DiagnosticHandlers<'a> {
406-
fn new(cgcx: &'a CodegenContext,
407-
handler: &'a Handler,
408-
llcx: &'a llvm::Context) -> Self {
406+
pub fn new(cgcx: &'a CodegenContext,
407+
handler: &'a Handler,
408+
llcx: &'a llvm::Context) -> Self {
409409
let data = Box::into_raw(Box::new((cgcx, handler)));
410410
unsafe {
411411
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
475475
opt.message));
476476
}
477477
}
478-
llvm::diagnostic::PGO(diagnostic_ref) => {
478+
llvm::diagnostic::PGO(diagnostic_ref) |
479+
llvm::diagnostic::Linker(diagnostic_ref) => {
479480
let msg = llvm::build_string(|s| {
480481
llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s)
481-
}).expect("non-UTF8 PGO diagnostic");
482+
}).expect("non-UTF8 diagnostic");
482483
diag_handler.warn(&msg);
483484
}
484485
llvm::diagnostic::UnknownDiagnostic(..) => {},

src/librustc_codegen_llvm/llvm/diagnostic.rs

+4
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ pub enum Diagnostic<'ll> {
126126
Optimization(OptimizationDiagnostic<'ll>),
127127
InlineAsm(InlineAsmDiagnostic<'ll>),
128128
PGO(&'ll DiagnosticInfo),
129+
Linker(&'ll DiagnosticInfo),
129130

130131
/// LLVM has other types that we do not wrap here.
131132
UnknownDiagnostic(&'ll DiagnosticInfo),
@@ -168,6 +169,9 @@ impl Diagnostic<'ll> {
168169
Dk::PGOProfile => {
169170
PGO(di)
170171
}
172+
Dk::Linker => {
173+
Linker(di)
174+
}
171175

172176
_ => UnknownDiagnostic(di),
173177
}

src/librustc_codegen_llvm/llvm/ffi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ pub enum DiagnosticKind {
332332
OptimizationRemarkOther,
333333
OptimizationFailure,
334334
PGOProfile,
335+
Linker,
335336
}
336337

337338
/// LLVMRustArchiveKind

src/rustllvm/RustWrapper.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,7 @@ enum class LLVMRustDiagnosticKind {
984984
OptimizationRemarkOther,
985985
OptimizationFailure,
986986
PGOProfile,
987+
Linker,
987988
};
988989

989990
static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
@@ -1008,6 +1009,8 @@ static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) {
10081009
return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
10091010
case DK_PGOProfile:
10101011
return LLVMRustDiagnosticKind::PGOProfile;
1012+
case DK_Linker:
1013+
return LLVMRustDiagnosticKind::Linker;
10111014
default:
10121015
return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark)
10131016
? LLVMRustDiagnosticKind::OptimizationRemarkOther
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// no-prefer-dynamic
12+
13+
#![crate_type = "rlib"]
14+
15+
#[no_mangle]
16+
pub extern fn foo() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// no-prefer-dynamic
12+
13+
#![crate_type = "rlib"]
14+
15+
#[no_mangle]
16+
pub extern fn foo() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// aux-build:lto-duplicate-symbols1.rs
12+
// aux-build:lto-duplicate-symbols2.rs
13+
// error-pattern:Linking globals named 'foo': symbol multiply defined!
14+
// compile-flags: -C lto
15+
// no-prefer-dynamic
16+
17+
extern crate lto_duplicate_symbols1;
18+
extern crate lto_duplicate_symbols2;
19+
20+
fn main() {}

0 commit comments

Comments
 (0)