From 9c34473ecf87a6f541b9f6404b782eaa484033d7 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 25 May 2019 22:29:18 +0100 Subject: [PATCH] Special-case `.llvm` in mangler to fix segfaults 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`. --- src/librustc_codegen_utils/symbol_names.rs | 3 ++ src/test/ui/issue-53912.rs | 37 +++++++++++++++++++ src/test/ui/symbol-names/issue-60925.rs | 39 +++++++++++++++++++++ src/test/ui/symbol-names/issue-60925.stderr | 8 +++++ 4 files changed, 87 insertions(+) create mode 100644 src/test/ui/issue-53912.rs create mode 100644 src/test/ui/symbol-names/issue-60925.rs create mode 100644 src/test/ui/symbol-names/issue-60925.stderr diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 1a8647ed197b5..5a342114fe834 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -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), diff --git a/src/test/ui/issue-53912.rs b/src/test/ui/issue-53912.rs new file mode 100644 index 0000000000000..d2347c3077cf3 --- /dev/null +++ b/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); + + 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() {} diff --git a/src/test/ui/symbol-names/issue-60925.rs b/src/test/ui/symbol-names/issue-60925.rs new file mode 100644 index 0000000000000..e9f763ad7cf67 --- /dev/null +++ b/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); + + 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() {} diff --git a/src/test/ui/symbol-names/issue-60925.stderr b/src/test/ui/symbol-names/issue-60925.stderr new file mode 100644 index 0000000000000..84a18745e2ea7 --- /dev/null +++ b/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 +