-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #54451 - alexcrichton:no-mangle-extern-linkage, r=micha…
…elwoerister rustc: Allow `#[no_mangle]` anywhere in a crate This commit updates the compiler to allow the `#[no_mangle]` (and `#[export_name]` attributes) to be located anywhere within a crate. These attributes are unconditionally processed, causing the compiler to always generate an exported symbol with the appropriate name. After some discussion on #54135 it was found that not a great reason this hasn't been allowed already, and it seems to match the behavior that many expect! Previously the compiler would only export a `#[no_mangle]` symbol if it were *publicly reachable*, meaning that it itself is `pub` and it's otherwise publicly reachable from the root of the crate. This new definition is that `#[no_mangle]` *is always reachable*, no matter where it is in a crate or whether it has `pub` or not. This should make it much easier to declare an exported symbol with a known and unique name, even when it's an internal implementation detail of the crate itself. Note that these symbols will persist beyond LTO as well, always making their way to the linker. Along the way this commit removes the `private_no_mangle_functions` lint (also for statics) as there's no longer any need to lint these situations. Furthermore a good number of tests were updated now that symbol visibility has been changed. Closes #54135
- Loading branch information
Showing
22 changed files
with
400 additions
and
307 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// 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. | ||
|
||
#![crate_type = "lib"] | ||
|
||
mod private { | ||
// CHECK: @FOO = | ||
#[no_mangle] | ||
pub static FOO: u32 = 3; | ||
|
||
// CHECK: @BAR = | ||
#[export_name = "BAR"] | ||
static BAR: u32 = 3; | ||
|
||
// CHECK: void @foo() | ||
#[no_mangle] | ||
pub extern fn foo() {} | ||
|
||
// CHECK: void @bar() | ||
#[export_name = "bar"] | ||
extern fn bar() {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// 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. | ||
|
||
// compile-flags: -O | ||
// `#[no_mangle]`d functions always have external linkage, i.e. no `internal` in their `define`s | ||
|
||
#![crate_type = "lib"] | ||
#![no_std] | ||
|
||
// CHECK: define void @a() | ||
#[no_mangle] | ||
fn a() {} | ||
|
||
// CHECK: define void @b() | ||
#[no_mangle] | ||
pub fn b() {} | ||
|
||
mod private { | ||
// CHECK: define void @c() | ||
#[no_mangle] | ||
fn c() {} | ||
|
||
// CHECK: define void @d() | ||
#[no_mangle] | ||
pub fn d() {} | ||
} | ||
|
||
const HIDDEN: () = { | ||
// CHECK: define void @e() | ||
#[no_mangle] | ||
fn e() {} | ||
|
||
// CHECK: define void @f() | ||
#[no_mangle] | ||
pub fn f() {} | ||
}; | ||
|
||
// The surrounding item should not accidentally become external | ||
// CHECK: define internal {{.*}} void @_ZN22external_no_mangle_fns1x | ||
#[inline(never)] | ||
fn x() { | ||
// CHECK: define void @g() | ||
#[no_mangle] | ||
fn g() { | ||
x(); | ||
} | ||
|
||
// CHECK: define void @h() | ||
#[no_mangle] | ||
pub fn h() {} | ||
|
||
// side effect to keep `x` around | ||
unsafe { | ||
core::ptr::read_volatile(&42); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// 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. | ||
|
||
// compile-flags: -O | ||
// `#[no_mangle]`d static variables always have external linkage, i.e. no `internal` in their | ||
// definitions | ||
|
||
#![crate_type = "lib"] | ||
#![no_std] | ||
|
||
// CHECK: @A = local_unnamed_addr constant | ||
#[no_mangle] | ||
static A: u8 = 0; | ||
|
||
// CHECK: @B = local_unnamed_addr global | ||
#[no_mangle] | ||
static mut B: u8 = 0; | ||
|
||
// CHECK: @C = local_unnamed_addr constant | ||
#[no_mangle] | ||
pub static C: u8 = 0; | ||
|
||
// CHECK: @D = local_unnamed_addr global | ||
#[no_mangle] | ||
pub static mut D: u8 = 0; | ||
|
||
mod private { | ||
// CHECK: @E = local_unnamed_addr constant | ||
#[no_mangle] | ||
static E: u8 = 0; | ||
|
||
// CHECK: @F = local_unnamed_addr global | ||
#[no_mangle] | ||
static mut F: u8 = 0; | ||
|
||
// CHECK: @G = local_unnamed_addr constant | ||
#[no_mangle] | ||
pub static G: u8 = 0; | ||
|
||
// CHECK: @H = local_unnamed_addr global | ||
#[no_mangle] | ||
pub static mut H: u8 = 0; | ||
} | ||
|
||
const HIDDEN: () = { | ||
// CHECK: @I = local_unnamed_addr constant | ||
#[no_mangle] | ||
static I: u8 = 0; | ||
|
||
// CHECK: @J = local_unnamed_addr global | ||
#[no_mangle] | ||
static mut J: u8 = 0; | ||
|
||
// CHECK: @K = local_unnamed_addr constant | ||
#[no_mangle] | ||
pub static K: u8 = 0; | ||
|
||
// CHECK: @L = local_unnamed_addr global | ||
#[no_mangle] | ||
pub static mut L: u8 = 0; | ||
}; | ||
|
||
// The surrounding item should not accidentally become external | ||
fn x() { | ||
// CHECK: @M = local_unnamed_addr constant | ||
#[no_mangle] | ||
static M: fn() = x; | ||
|
||
// CHECK: @N = local_unnamed_addr global | ||
#[no_mangle] | ||
static mut N: u8 = 0; | ||
|
||
// CHECK: @O = local_unnamed_addr constant | ||
#[no_mangle] | ||
pub static O: u8 = 0; | ||
|
||
// CHECK: @P = local_unnamed_addr global | ||
#[no_mangle] | ||
pub static mut P: u8 = 0; | ||
} | ||
// CHECK: define internal void @_ZN26external_no_mangle_statics1x{{.*$}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.