diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index 01fd36867fffb..01ce9d51746db 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -40,6 +40,7 @@ use syntax::attr; use syntax::codemap::Span; use syntax::parse::token::{InternedString, special_idents}; use syntax::ast; +use syntax::attr::AttrMetaMethods; use rustc_front::print::pprust; use rustc_front::hir; @@ -119,8 +120,8 @@ pub fn register_static(ccx: &CrateContext, let llty = type_of::type_of(ccx, ty); let ident = link_name(foreign_item); - match attr::first_attr_value_str_by_name(&foreign_item.attrs, - "linkage") { + let c = match attr::first_attr_value_str_by_name(&foreign_item.attrs, + "linkage") { // If this is a static with a linkage specified, then we need to handle // it a little specially. The typesystem prevents things like &T and // extern "C" fn() from being non-null, so we can't just declare a @@ -165,7 +166,16 @@ pub fn register_static(ccx: &CrateContext, } None => // Generate an external declaration. declare::declare_global(ccx, &ident[..], llty), + }; + + // Handle thread-local external statics. + for attr in foreign_item.attrs.iter() { + if attr.check_name("thread_local") { + llvm::set_thread_local(c, true); + } } + + return c; } // only use this for foreign function ABIs and glue, use `get_extern_rust_fn` for Rust functions diff --git a/src/test/auxiliary/thread-local-extern-static.rs b/src/test/auxiliary/thread-local-extern-static.rs new file mode 100644 index 0000000000000..d1971a5e1aea4 --- /dev/null +++ b/src/test/auxiliary/thread-local-extern-static.rs @@ -0,0 +1,17 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(thread_local)] +#![feature(cfg_target_thread_local)] +#![crate_type = "lib"] + +#[no_mangle] +#[cfg_attr(target_thread_local, thread_local)] +pub static FOO: u32 = 3; diff --git a/src/test/run-pass/thread-local-extern-static.rs b/src/test/run-pass/thread-local-extern-static.rs new file mode 100644 index 0000000000000..92a95cad0d38a --- /dev/null +++ b/src/test/run-pass/thread-local-extern-static.rs @@ -0,0 +1,26 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-windows +// aux-build:thread-local-extern-static.rs + +#![feature(thread_local)] +#![feature(cfg_target_thread_local)] + +extern crate thread_local_extern_static; + +extern { + #[cfg_attr(target_thread_local, thread_local)] + static FOO: u32; +} + +fn main() { + assert_eq!(FOO, 3); +}