Skip to content

Commit

Permalink
Special-case .llvm in mangler to fix segfaults
Browse files Browse the repository at this point in the history
This commit special cases `.llvm` in the mangler to print `.llvm$6d$`
instead. This will avoid segfaults when names in a user's Rust code are
`llvm`.
  • Loading branch information
davidtwco committed May 28, 2019
1 parent 02f5786 commit 9c34473
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/librustc_codegen_utils/symbol_names.rs
Expand Up @@ -613,6 +613,9 @@ impl fmt::Write for SymbolPrinter<'_, '_> {
// for ':' and '-'
'-' | ':' => self.path.temp_buf.push('.'),

// Avoid segmentation fault on some platforms, see #60925.
'm' if self.path.temp_buf.ends_with(".llv") => self.path.temp_buf.push_str("$6d$"),

// These are legal symbols
'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => self.path.temp_buf.push(c),

Expand Down
37 changes: 37 additions & 0 deletions src/test/ui/issue-53912.rs
@@ -0,0 +1,37 @@
// compile-pass

// This test is the same code as in ui/symbol-names/issue-60925.rs but this checks that the
// reproduction compiles successfully and doesn't segfault, whereas that test just checks that the
// symbol mangling fix produces the correct result.

fn dummy() {}

mod llvm {
pub(crate) struct Foo;
}
mod foo {
pub(crate) struct Foo<T>(T);

impl Foo<::llvm::Foo> {
pub(crate) fn foo() {
for _ in 0..0 {
for _ in &[::dummy()] {
::dummy();
::dummy();
::dummy();
}
}
}
}

pub(crate) fn foo() {
Foo::foo();
Foo::foo();
}
}

pub fn foo() {
foo::foo();
}

fn main() {}
39 changes: 39 additions & 0 deletions src/test/ui/symbol-names/issue-60925.rs
@@ -0,0 +1,39 @@
#![feature(rustc_attrs)]

// This test is the same code as in ui/issue-53912.rs but this test checks that the symbol mangling
// fix produces the correct result, whereas that test just checks that the reproduction compiles
// successfully and doesn't segfault

fn dummy() {}

mod llvm {
pub(crate) struct Foo;
}
mod foo {
pub(crate) struct Foo<T>(T);

impl Foo<::llvm::Foo> {
#[rustc_symbol_name]
//~^ ERROR _ZN11issue_609253foo36Foo$LT$issue_60925..llv$6d$..Foo$GT$3foo17h059a991a004536adE
pub(crate) fn foo() {
for _ in 0..0 {
for _ in &[::dummy()] {
::dummy();
::dummy();
::dummy();
}
}
}
}

pub(crate) fn foo() {
Foo::foo();
Foo::foo();
}
}

pub fn foo() {
foo::foo();
}

fn main() {}
8 changes: 8 additions & 0 deletions src/test/ui/symbol-names/issue-60925.stderr
@@ -0,0 +1,8 @@
error: symbol-name(_ZN11issue_609253foo36Foo$LT$issue_60925..llv$6d$..Foo$GT$3foo17h059a991a004536adE)
--> $DIR/issue-60925.rs:16:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

0 comments on commit 9c34473

Please sign in to comment.