diff options
| author | Mara Bos <m-ou.se@m-ou.se> | 2020-10-01 16:49:55 +0200 |
|---|---|---|
| committer | Mara Bos <m-ou.se@m-ou.se> | 2020-10-01 16:52:11 +0200 |
| commit | 63b6007d5b68023e02a43c2f9c2ed21762cd8011 (patch) | |
| tree | e5b1e2750ae03e5baf17186c9b52a353175576f9 /library/std/src | |
| parent | 09cbaf436713ddb864725a50ccdff67e2ab9bc77 (diff) | |
| download | rust-63b6007d5b68023e02a43c2f9c2ed21762cd8011.tar.gz rust-63b6007d5b68023e02a43c2f9c2ed21762cd8011.zip | |
Work around potential merging/duplication issues in sys/windows/compat.
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/sys/windows/compat.rs | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/library/std/src/sys/windows/compat.rs b/library/std/src/sys/windows/compat.rs index 897f49445ee..3f25f05e1b9 100644 --- a/library/std/src/sys/windows/compat.rs +++ b/library/std/src/sys/windows/compat.rs @@ -38,11 +38,28 @@ macro_rules! compat_fn { use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::mem; + type F = unsafe extern "system" fn($($argtype),*) -> $rettype; + static PTR: AtomicUsize = AtomicUsize::new(0); #[allow(unused_variables)] unsafe extern "system" fn fallback($($argname: $argtype),*) -> $rettype $body + /// This address is stored in `PTR` to incidate an unavailable API. + /// + /// This way, call() will end up calling fallback() if it is unavailable. + /// + /// This is a `static` to avoid rustc duplicating `fn fallback()` + /// into both load() and is_available(), which would break + /// is_available()'s comparison. By using the same static variable + /// in both places, they'll refer to the same (copy of the) + /// function. + /// + /// LLVM merging the address of fallback with other functions + /// (because of unnamed_addr) is fine, since it's only compared to + /// an address from GetProcAddress from an external dll. + static FALLBACK: F = fallback; + #[cold] fn load() -> usize { // There is no locking here. It's okay if this is executed by multiple threads in @@ -51,7 +68,7 @@ macro_rules! compat_fn { // about memory ordering, as this involves just a single atomic variable which is // not used to protect or order anything else. let addr = crate::sys::compat::lookup($module, stringify!($symbol)) - .unwrap_or(fallback as usize); + .unwrap_or(FALLBACK as usize); PTR.store(addr, Ordering::Relaxed); addr } @@ -65,11 +82,10 @@ macro_rules! compat_fn { #[allow(dead_code)] pub fn is_available() -> bool { - addr() != fallback as usize + addr() != FALLBACK as usize } pub unsafe fn call($($argname: $argtype),*) -> $rettype { - type F = unsafe extern "system" fn($($argtype),*) -> $rettype; mem::transmute::<usize, F>(addr())($($argname),*) } } |
