From 770b6e2fc2f8749466487e4c2ae031b8ceecae04 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 14 Mar 2014 10:29:13 -0700 Subject: [PATCH 1/2] rustc: Fix cfg(not(a, b)) to be not(a && b) Previously, the cfg attribute `cfg(not(a, b))` was translated to `(!a && !b)`, but this isn't very useful because that can already be expressed as `cfg(not(a), not(b))`. This commit changes the translation to `!(a && b)` which is more symmetrical of the rest of the `cfg` attribute. Put another way, I would expect `cfg(clause)` to be the opposite of `cfg(not(clause))`, but this is not currently the case with multiple element clauses. --- src/libsyntax/attr.rs | 4 ++-- src/test/run-pass/cfgs-on-items.rs | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index ed56ef15a1c8..7ff9a73f29d9 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -317,9 +317,9 @@ pub fn test_cfg> debug!("not!"); // inside #[cfg(not(...))], so these need to all // not match. - not_cfgs.iter().all(|mi| { + !not_cfgs.iter().all(|mi| { debug!("cfg(not({}[...]))", mi.name()); - !contains(cfg, *mi) + contains(cfg, *mi) }) } _ => contains(cfg, *cfg_mi) diff --git a/src/test/run-pass/cfgs-on-items.rs b/src/test/run-pass/cfgs-on-items.rs index 72d12b56c5c9..f1c91dbaf354 100644 --- a/src/test/run-pass/cfgs-on-items.rs +++ b/src/test/run-pass/cfgs-on-items.rs @@ -16,7 +16,7 @@ fn foo1() -> int { 1 } // !fooA AND !bar -#[cfg(not(fooA, bar))] +#[cfg(not(fooA), not(bar))] fn foo2() -> int { 2 } // fooC OR (fooB AND !bar) @@ -24,8 +24,16 @@ fn foo2() -> int { 2 } #[cfg(fooB, not(bar))] fn foo2() -> int { 3 } +// fooA AND bar +#[cfg(fooA, bar)] +fn foo3() -> int { 2 } + +// !(fooA AND bar) +#[cfg(not(fooA, bar))] +fn foo3() -> int { 3 } pub fn main() { assert_eq!(1, foo1()); assert_eq!(3, foo2()); + assert_eq!(3, foo3()); } From 8e5ca4b793e928b5a7545f6d1010b7663a9d30ae Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 14 Mar 2014 10:34:29 -0700 Subject: [PATCH 2/2] std: Fix backtraces on arm linux On android, libgcc is missing the _Unwind_GetIP symbol because it's defined as a macro. This is the same case for arm linux, so this commit adds the necessary cfgs in place to use the "expanded macro" in rust for arm linux. --- src/libstd/rt/libunwind.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libstd/rt/libunwind.rs b/src/libstd/rt/libunwind.rs index bdb049fbb5f7..a556db2a0538 100644 --- a/src/libstd/rt/libunwind.rs +++ b/src/libstd/rt/libunwind.rs @@ -98,9 +98,18 @@ extern "C" { pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn, trace_argument: *libc::c_void) -> _Unwind_Reason_Code; - #[cfg(not(target_os = "android"))] + #[cfg(stage0, not(target_os = "android"))] pub fn _Unwind_GetIP(ctx: *_Unwind_Context) -> libc::uintptr_t; - #[cfg(not(target_os = "android"))] + #[cfg(stage0, not(target_os = "android"))] + pub fn _Unwind_FindEnclosingFunction(pc: *libc::c_void) -> *libc::c_void; + + #[cfg(not(stage0), + not(target_os = "android"), + not(target_os = "linux", target_arch = "arm"))] + pub fn _Unwind_GetIP(ctx: *_Unwind_Context) -> libc::uintptr_t; + #[cfg(not(stage0), + not(target_os = "android"), + not(target_os = "linux", target_arch = "arm"))] pub fn _Unwind_FindEnclosingFunction(pc: *libc::c_void) -> *libc::c_void; } @@ -108,6 +117,7 @@ extern "C" { // of the macro. This is all copy/pasted directly from the header file with the // definition of _Unwind_GetIP. #[cfg(target_os = "android")] +#[cfg(target_os = "linux", target_os = "arm")] pub unsafe fn _Unwind_GetIP(ctx: *_Unwind_Context) -> libc::uintptr_t { #[repr(C)] enum _Unwind_VRS_Result { @@ -151,6 +161,7 @@ pub unsafe fn _Unwind_GetIP(ctx: *_Unwind_Context) -> libc::uintptr_t { // This function also doesn't exist on android, so make it a no-op #[cfg(target_os = "android")] +#[cfg(target_os = "linux", target_os = "arm")] pub unsafe fn _Unwind_FindEnclosingFunction(pc: *libc::c_void) -> *libc::c_void{ pc }