about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2018-07-18 12:12:53 -0700
committerAlex Crichton <alex@alexcrichton.com>2018-07-18 12:12:53 -0700
commite08fcbbd8d241ab68d72dc8b288ca55b8c1114fe (patch)
treeeddeeb70161b48a90aa6b3e2e79d9395830df24d /src/test
parent12ed235adc62e63b16bb4f715b143c37a5efa00d (diff)
downloadrust-e08fcbbd8d241ab68d72dc8b288ca55b8c1114fe.tar.gz
rust-e08fcbbd8d241ab68d72dc8b288ca55b8c1114fe.zip
rustc: Work around an upstream wasm ThinLTO bug
This commit implements a workaround for an [upstream LLVM bug][1] where custom
sections were accidentally duplicated amongst codegen units when ThinLTO passes
were performed. This is due to the fact that custom sections for wasm are stored
as metadata nodes which are automatically imported into modules when ThinLTO
happens. The fix here is to forcibly delete the metadata node from imported
modules before LLVM has a chance to try to copy it over.

[1]: https://bugs.llvm.org/show_bug.cgi?id=38184
Diffstat (limited to 'src/test')
-rw-r--r--src/test/run-make/wasm-custom-sections-opt/Makefile9
-rw-r--r--src/test/run-make/wasm-custom-sections-opt/foo.js25
-rw-r--r--src/test/run-make/wasm-custom-sections-opt/foo.rs31
3 files changed, 65 insertions, 0 deletions
diff --git a/src/test/run-make/wasm-custom-sections-opt/Makefile b/src/test/run-make/wasm-custom-sections-opt/Makefile
new file mode 100644
index 00000000000..63644c513c3
--- /dev/null
+++ b/src/test/run-make/wasm-custom-sections-opt/Makefile
@@ -0,0 +1,9 @@
+-include ../../run-make-fulldeps/tools.mk
+
+ifeq ($(TARGET),wasm32-unknown-unknown)
+all:
+	$(RUSTC) foo.rs -O --target wasm32-unknown-unknown
+	$(NODE) foo.js $(TMPDIR)/foo.wasm
+else
+all:
+endif
diff --git a/src/test/run-make/wasm-custom-sections-opt/foo.js b/src/test/run-make/wasm-custom-sections-opt/foo.js
new file mode 100644
index 00000000000..1d1a9bd13ee
--- /dev/null
+++ b/src/test/run-make/wasm-custom-sections-opt/foo.js
@@ -0,0 +1,25 @@
+// 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.
+
+const fs = require('fs');
+const process = require('process');
+const assert = require('assert');
+const buffer = fs.readFileSync(process.argv[2]);
+
+let m = new WebAssembly.Module(buffer);
+
+sections = WebAssembly.Module.customSections(m, "foo");
+console.log('section foo', sections);
+assert.strictEqual(sections.length, 1, "didn't create `foo` section");
+section = new Uint8Array(sections[0]);
+console.log('contents', section);
+assert.strictEqual(section.length, 4, "didn't concatenate `foo` sections");
+
+process.exit(0);
diff --git a/src/test/run-make/wasm-custom-sections-opt/foo.rs b/src/test/run-make/wasm-custom-sections-opt/foo.rs
new file mode 100644
index 00000000000..4d983514a23
--- /dev/null
+++ b/src/test/run-make/wasm-custom-sections-opt/foo.rs
@@ -0,0 +1,31 @@
+// 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 = "cdylib"]
+#![deny(warnings)]
+
+#[link_section = "foo"]
+pub static A: [u8; 2] = [1, 2];
+
+// make sure this is in another CGU
+pub mod another {
+    #[link_section = "foo"]
+    pub static FOO: [u8; 2] = [3, 4];
+
+    pub fn foo() {}
+}
+
+#[no_mangle]
+pub extern fn foo() {
+    // This will import `another::foo` through ThinLTO passes, and it better not
+    // also accidentally import the `FOO` custom section into this module as
+    // well
+    another::foo();
+}