From 8d0b5a9315b26436acce0096df1fe93586b5d09f Mon Sep 17 00:00:00 2001 From: cezarbbb Date: Tue, 4 Nov 2025 10:33:44 +0800 Subject: [PATCH 1/6] Check the coexistence of stack-protector and safe-stack. --- .../stack-protector-safe-stack.rs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/assembly-llvm/stack-protector/stack-protector-safe-stack.rs diff --git a/tests/assembly-llvm/stack-protector/stack-protector-safe-stack.rs b/tests/assembly-llvm/stack-protector/stack-protector-safe-stack.rs new file mode 100644 index 0000000000000..93c638b0527d6 --- /dev/null +++ b/tests/assembly-llvm/stack-protector/stack-protector-safe-stack.rs @@ -0,0 +1,39 @@ +//@ revisions: all strong none safestack safestack_strong safestack_all +//@ assembly-output: emit-asm +//@ ignore-msvc safestack sanitizer not supported +//@ ignore-nvptx64 stack protector is not supported +//@ ignore-wasm32-bare +//@ ignore-aarch64 +//@ [all] compile-flags: -Z stack-protector=all +//@ [strong] compile-flags: -Z stack-protector=strong +//@ [none] compile-flags: -Z stack-protector=none +//@ [safestack] compile-flags: -Z stack-protector=none -Z sanitizer=safestack +//@ [safestack_strong] compile-flags: -Z stack-protector=strong -Z sanitizer=safestack +//@ [safestack_all] compile-flags: -Z stack-protector=all -Z sanitizer=safestack +//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled + +#![crate_type = "lib"] +#![allow(internal_features)] +#![feature(unsized_fn_params)] + +// Check the coexistence of stack-protector and safe-stack. +// CHECK-LABEL: test1{{:|\[}} +#[no_mangle] +pub unsafe fn test1(src: *const u8, len: usize) -> u8 { + let mut buf = [0u8; 64]; + std::ptr::copy_nonoverlapping(src, buf.as_mut_ptr(), len.min(buf.len())); + buf[0] + + // none-NOT: __stack_chk_fail + // strong: __stack_chk_fail + // all: __stack_chk_fail + + // safestack: __safestack_unsafe_stack_ptr + // safestack-NOT: __stack_chk_fail + + // safestack_strong: __safestack_unsafe_stack_ptr + // safestack_strong: __stack_chk_fail + + // safestack_all: __safestack_unsafe_stack_ptr + // safestack_all: __stack_chk_fail +} From 3086cb275b2d8cfb41b40755ad657418cc41d3d2 Mon Sep 17 00:00:00 2001 From: cezarbbb Date: Tue, 4 Nov 2025 10:33:58 +0800 Subject: [PATCH 2/6] tests for linux. --- .../stack-protector-heuristics-effect-2.rs | 481 ++++++++++++++++++ 1 file changed, 481 insertions(+) create mode 100644 tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-2.rs diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-2.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-2.rs new file mode 100644 index 0000000000000..63d3e23654b55 --- /dev/null +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-2.rs @@ -0,0 +1,481 @@ +//@ revisions: all strong none missing +//@ assembly-output: emit-asm +//@ ignore-apple slightly different policy on stack protection of arrays +//@ ignore-msvc stack check code uses different function names +//@ ignore-nvptx64 stack protector is not supported +//@ ignore-wasm32-bare +//@ [all] compile-flags: -Z stack-protector=all +//@ [strong] compile-flags: -Z stack-protector=strong +//@ [none] compile-flags: -Z stack-protector=none +//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled + +#![crate_type = "lib"] +#![allow(internal_features)] +#![feature(unsized_fn_params)] + +extern "C" { + fn strcpy(dest: *mut u8, src: *const u8) -> *mut u8; + fn printf(fmt: *const u8, ...) -> i32; + fn funcall(p: *mut i32); + fn funcall2(p: *mut *mut i32); + fn funfloat(p: *mut f64); + fn funfloat2(p: *mut *mut f64); + fn testi_aux() -> f64; + fn getp() -> *mut i32; + fn dummy(_: ...) -> i32; + + static STR: [u8; 1]; +} + +extern "C-unwind" { + fn except(p: *mut i32); +} + +#[repr(C)] +struct Pair { + a: i32, + b: i32, +} + +#[repr(C)] +struct Nest { + first: Pair, + second: Pair, +} + +// test1: array of [16 x i8] +// CHECK-LABEL: test1{{:|\[}} +#[no_mangle] +pub fn test1(a: *const u8) { + let mut buf: [u8; 16] = [0; 16]; + + unsafe { + strcpy(buf.as_mut_ptr(), a); + printf(STR.as_ptr(), buf.as_ptr()); + } + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test3: array [4 x i8] +// CHECK-LABEL: test3{{:|\[}} +#[no_mangle] +pub fn test3(a: *const u8) { + let mut buf: [u8; 4] = [0; 4]; + + unsafe { + strcpy(buf.as_mut_ptr(), a); + printf(STR.as_ptr(), buf.as_ptr()); + } + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test5: no arrays / no nested arrays +// CHECK-LABEL: test5{{:|\[}} +#[no_mangle] +pub fn test5(a: *const u8) { + unsafe { + printf(STR.as_ptr(), a); + } + + // all: __stack_chk_fail + // strong-NOT: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test6: Address-of local taken (j = &a) +// CHECK-LABEL: test6{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test6() { + let mut a: i32 = 0; + + let mut j: *mut i32 = std::ptr::null_mut(); + + let tmp = std::ptr::read_volatile(&a); + let tmp2 = tmp.wrapping_add(1); + std::ptr::write_volatile(&mut a, tmp2); + + std::ptr::write_volatile(&mut j, &mut a); + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test7: PtrToInt Cast +// CHECK-LABEL: test7{{:|\[}} +#[no_mangle] +pub fn test7(a: i32) { + let ptr_val: usize = &a as *const i32 as usize; + + unsafe { + printf(STR.as_ptr(), ptr_val); + } + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test8: Passing addr-of to function call +// CHECK-LABEL: test8{{:|\[}} +#[no_mangle] +pub fn test8(mut b: i32) { + unsafe { + funcall(&mut b as *mut i32); + } + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test9: Addr-of in select instruction +// CHECK-LABEL: test9{{:|\[}} +#[no_mangle] +pub fn test9() { + let x: f64; + + unsafe { + let call = testi_aux(); + x = call; + + let y: *const f64 = if call > 0.0 { &x as *const f64 } else { std::ptr::null() }; + + printf(STR.as_ptr(), y); + } + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test10: Addr-of in phi instruction +// CHECK-LABEL: test10{{:|\[}} +#[no_mangle] +pub fn test10() { + let mut _x: f64; + + unsafe { + let call = testi_aux(); + _x = call; + + let y: *const f64; + + if call > 3.14 { + let call1 = testi_aux(); + _x = call1; + y = std::ptr::null(); + } else { + if call > 1.0 { + y = &_x; + } else { + y = std::ptr::null(); + } + } + + printf(STR.as_ptr(), y); + } + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test11: Addr-of struct element(GEP followed by store) +// CHECK-LABEL: test11{{:|\[}} +#[no_mangle] +pub fn test11() { + let mut c = Pair { a: 0, b: 0 }; + let b: *mut i32; + + unsafe { + let y: *mut i32 = &mut c.b; + + b = y; + + printf(STR.as_ptr(), b); + } + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test12: Addr-of struct element, GEP followed by ptrtoint +// CHECK-LABEL: test12{{:|\[}} +#[no_mangle] +pub fn test12() { + let mut c = Pair { a: 0, b: 0 }; + + unsafe { + let y: *mut i32 = &mut c.b; + + let addr: i64 = y as i64; + + printf(STR.as_ptr(), addr); + } + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test13: Addr-of struct element, GEP followed by callinst +// CHECK-LABEL: test13{{:|\[}} +#[no_mangle] +pub fn test13() { + let mut c = Pair { a: 0, b: 0 }; + + unsafe { + let y: *mut i32 = &mut c.b; + + printf(STR.as_ptr(), y); + } + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test14: Addr-of a local, optimized into a GEP (e.g., &a - 12) +// CHECK-LABEL: test14{{:|\[}} +#[no_mangle] +pub fn test14() { + let mut a: i32 = 0; + + unsafe { + let add_ptr = (&mut a as *mut i32).offset(-12); + + printf(STR.as_ptr(), add_ptr); + } + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test15: Addr-of a local cast to a ptr of a different type +// (e.g., int a; ... ; ptr b = &a;) +// CHECK-LABEL: test15{{:|\[}} +#[no_mangle] +pub fn test15() { + let mut a: i32 = 0; + + unsafe { + let mut b: *mut i32 = std::ptr::null_mut(); + + std::ptr::write_volatile(&mut b, &mut a); // avoid ptr b from optimization + let tmp = std::ptr::read_volatile(&b); + + printf(STR.as_ptr(), tmp); + } + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test16: Addr-of a local cast to a ptr of a different type (optimized) +// (e.g., int a; ... ; ptr b = &a;) +// CHECK-LABEL: test16{{:|\[}} +#[no_mangle] +pub fn test16() { + let a: i32 = 0; + unsafe { + funfloat((&a as *const i32).cast::() as *mut f64); + } + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test18: Addr-of a variable passed into an invoke instruction +// CHECK-LABEL: test18{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test18() -> i32 { + let mut a: i32 = 0; + + except(&mut a as *mut i32); + + 0 + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test19: Addr-of a struct element passed into an invoke instruction +// (GEP followed by an invoke) +// CHECK-LABEL: test19{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test19() -> i32 { + let mut c = Pair { a: 0, b: 0 }; + + except(&mut c.a as *mut i32); + + 0 + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test20: Addr-of a pointer +// CHECK-LABEL: test20{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test20() { + let mut a: *mut i32 = getp(); + + let mut _b: *mut *mut i32 = std::ptr::null_mut(); + + std::ptr::write_volatile(&mut _b, &mut a); + + let tmp = std::ptr::read_volatile(&_b); + + funcall2(tmp); + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test21: Addr-of a casted pointer +// CHECK-LABEL: test21{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test21() { + let mut a: *mut i32 = getp(); + + let mut _b: *mut *mut i32 = std::ptr::null_mut(); + + std::ptr::write_volatile(&mut _b, &mut a); + + let tmp = std::ptr::read_volatile(&_b); + + funfloat2(tmp as *mut *mut f64); + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test25: array of [4 x i32] +// CHECK-LABEL: test25{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test25() -> i32 { + let a: [i32; 4] = [0; 4]; + + let _whole = std::ptr::read_volatile(&a as *const _); // avoid array a from optimization + + std::ptr::read_volatile(&a[0]) + + // all: __stack_chk_fail + // strong: __stack_chk_fail + // none-NOT: __stack_chk_fail + // missing-NOT: __stack_chk_fail +} + +// test26: Nested structure, no arrays, no address-of expressions +// Verify that the resulting gep-of-gep does not incorrectly trigger +// a stack protector +// CHECK-LABEL: test26{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test26() { + let c = Nest { first: Pair { a: 10, b: 11 }, second: Pair { a: 20, b: 21 } }; + + let whole: Nest = std::ptr::read_volatile(&c); + + let v: i32 = whole.second.a; + + printf(STR.as_ptr(), v); + + // strong-NOT: __stack_chk_fail +} + +// test27: Address-of a structure taken in a function with a loop where +// the alloca is an incoming value to a PHI node and a use of that PHI +// node is also an incoming value +// Verify that the address-of analysis does not get stuck in infinite +// recursion when chasing the alloca through the PHI nodes +// CHECK-LABEL: test27{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test27() -> i32 { + let mut tmp: *mut u8 = std::ptr::null_mut(); + let tmp_ptr: *mut *mut u8 = &mut tmp; + + let tmp1 = dummy(tmp_ptr); + + let cur = std::ptr::read_volatile(tmp_ptr); + + let v = (cur as usize as i64) as i32; + + if v > 0 { + let mut phi_ptr: *mut u8 = cur; + let mut phi_idx: i64 = 1; + let mut phi_acc: i32 = tmp1; + + loop { + let b = std::ptr::read_volatile(phi_ptr as *const u8); + let cond = b == 1u8; + let plus = phi_acc.wrapping_add(8); + let next_acc = if cond { plus } else { phi_acc }; + + if (phi_idx as i32) == v { + dummy(next_acc); + break; + } + + let slot = tmp_ptr.add(phi_idx as usize); + let next = std::ptr::read_volatile(slot); + phi_ptr = next; + phi_idx += 1; + phi_acc = next_acc; + } + } else { + dummy(tmp1); + } + + 0 + + // strong: __stack_chk_fail +} + +// CHECK-LABEL: IgnoreIntrinsicTest{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn IgnoreIntrinsicTest() -> i32 { + let mut x: i32 = 0; + + std::ptr::write_volatile(&mut x, 1); + + let y = std::ptr::read_volatile(&x); + + let result = y.wrapping_mul(42); + + result + + // strong-NOT: __stack_chk_fail +} From 8e59eb35df8d383007f796fed80da0d88b55a5a5 Mon Sep 17 00:00:00 2001 From: cezarbbb Date: Tue, 4 Nov 2025 10:34:10 +0800 Subject: [PATCH 3/6] tests for windows 32bit. --- ...ector-heuristics-effect-windows-32bit-2.rs | 484 ++++++++++++++++++ 1 file changed, 484 insertions(+) create mode 100644 tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit-2.rs diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit-2.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit-2.rs new file mode 100644 index 0000000000000..1926c5039e449 --- /dev/null +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit-2.rs @@ -0,0 +1,484 @@ +//@ revisions: all strong none missing +//@ assembly-output: emit-asm +//@ only-windows +//@ only-msvc +//@ ignore-64bit 64-bit table based SEH has slightly different behaviors than classic SEH +//@ [all] compile-flags: -Z stack-protector=all +//@ [strong] compile-flags: -Z stack-protector=strong +//@ [none] compile-flags: -Z stack-protector=none +//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled + +#![crate_type = "lib"] +#![allow(internal_features)] +#![feature(unsized_fn_params)] + +extern "C" { + fn strcpy(dest: *mut u8, src: *const u8) -> *mut u8; + fn printf(fmt: *const u8, ...) -> i32; + fn funcall(p: *mut i32); + fn funcall2(p: *mut *mut i32); + fn funfloat(p: *mut f64); + fn funfloat2(p: *mut *mut f64); + fn testi_aux() -> f64; + fn getp() -> *mut i32; + fn dummy(_: ...) -> i32; + + static STR: [u8; 1]; +} + +extern "C-unwind" { + fn except(p: *mut i32); +} + +#[repr(C)] +struct Pair { + a: i32, + b: i32, +} + +#[repr(C)] +struct Nest { + first: Pair, + second: Pair, +} + +// test1: array of [16 x i8] +// CHECK-LABEL: test1{{:|\[}} +#[no_mangle] +pub fn test1(a: *const u8) { + let mut buf: [u8; 16] = [0; 16]; + + unsafe { + strcpy(buf.as_mut_ptr(), a); + printf(STR.as_ptr(), buf.as_ptr()); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test3: array [4 x i8] +// CHECK-LABEL: test3{{:|\[}} +#[no_mangle] +pub fn test3(a: *const u8) { + let mut buf: [u8; 4] = [0; 4]; + + unsafe { + strcpy(buf.as_mut_ptr(), a); + printf(STR.as_ptr(), buf.as_ptr()); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test5: no arrays / no nested arrays +// CHECK-LABEL: test5{{:|\[}} +#[no_mangle] +pub fn test5(a: *const u8) { + unsafe { + printf(STR.as_ptr(), a); + } + + // all: __security_check_cookie + // strong-NOT: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test6: Address-of local taken (j = &a) +// CHECK-LABEL: test6{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test6() { + let mut a: i32 = 0; + + let mut j: *mut i32 = std::ptr::null_mut(); + + let tmp = std::ptr::read_volatile(&a); + let tmp2 = tmp.wrapping_add(1); + std::ptr::write_volatile(&mut a, tmp2); + + std::ptr::write_volatile(&mut j, &mut a); + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test7: PtrToInt Cast +// CHECK-LABEL: test7{{:|\[}} +#[no_mangle] +pub fn test7(a: i32) { + let ptr_val: usize = &a as *const i32 as usize; + + unsafe { + printf(STR.as_ptr(), ptr_val); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test8: Passing addr-of to function call +// CHECK-LABEL: test8{{:|\[}} +#[no_mangle] +pub fn test8(mut b: i32) { + unsafe { + funcall(&mut b as *mut i32); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test9: Addr-of in select instruction +// CHECK-LABEL: test9{{:|\[}} +#[no_mangle] +pub fn test9() { + let x: f64; + + unsafe { + let call = testi_aux(); + x = call; + + let y: *const f64 = if call > 0.0 { &x as *const f64 } else { std::ptr::null() }; + + printf(STR.as_ptr(), y); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test10: Addr-of in phi instruction +// CHECK-LABEL: test10{{:|\[}} +#[no_mangle] +pub fn test10() { + let mut _x: f64; + + unsafe { + let call = testi_aux(); + _x = call; + + let y: *const f64; + + if call > 3.14 { + let call1 = testi_aux(); + _x = call1; + y = std::ptr::null(); + } else { + if call > 1.0 { + y = &_x; + } else { + y = std::ptr::null(); + } + } + + printf(STR.as_ptr(), y); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test11: Addr-of struct element(GEP followed by store) +// CHECK-LABEL: test11{{:|\[}} +#[no_mangle] +pub fn test11() { + let mut c = Pair { a: 0, b: 0 }; + let b: *mut i32; + + unsafe { + let y: *mut i32 = &mut c.b; + + b = y; + + printf(STR.as_ptr(), b); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test12: Addr-of struct element, GEP followed by ptrtoint +// CHECK-LABEL: test12{{:|\[}} +#[no_mangle] +pub fn test12() { + let mut c = Pair { a: 0, b: 0 }; + + unsafe { + let y: *mut i32 = &mut c.b; + + let addr: i64 = y as i64; + + printf(STR.as_ptr(), addr); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test13: Addr-of struct element, GEP followed by callinst +// CHECK-LABEL: test13{{:|\[}} +#[no_mangle] +pub fn test13() { + let mut c = Pair { a: 0, b: 0 }; + + unsafe { + let y: *mut i32 = &mut c.b; + + printf(STR.as_ptr(), y); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test14: Addr-of a local, optimized into a GEP (e.g., &a - 12) +// CHECK-LABEL: test14{{:|\[}} +#[no_mangle] +pub fn test14() { + let mut a: i32 = 0; + + unsafe { + let add_ptr = (&mut a as *mut i32).offset(-12); + + printf(STR.as_ptr(), add_ptr); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test15: Addr-of a local cast to a ptr of a different type +// (e.g., int a; ... ; ptr b = &a;) +// CHECK-LABEL: test15{{:|\[}} +#[no_mangle] +pub fn test15() { + let mut a: i32 = 0; + + unsafe { + let mut b: *mut i32 = std::ptr::null_mut(); + + std::ptr::write_volatile(&mut b, &mut a); // avoid ptr b from optimization + let tmp = std::ptr::read_volatile(&b); + + printf(STR.as_ptr(), tmp); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test16: Addr-of a local cast to a ptr of a different type (optimized) +// (e.g., int a; ... ; ptr b = &a;) +// CHECK-LABEL: test16{{:|\[}} +#[no_mangle] +pub fn test16() { + let a: i32 = 0; + unsafe { + funfloat((&a as *const i32).cast::() as *mut f64); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test18: Addr-of a variable passed into an invoke instruction +// CHECK-LABEL: test18{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test18() -> i32 { + let mut a: i32 = 0; + + except(&mut a as *mut i32); + + 0 + + // stack protector does not generated by LLVM because of Windows SEH. + + // all-NOT: __security_check_cookie + // strong-NOT: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test19: Addr-of a struct element passed into an invoke instruction +// (GEP followed by an invoke) +// CHECK-LABEL: test19{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test19() -> i32 { + let mut c = Pair { a: 0, b: 0 }; + + except(&mut c.a as *mut i32); + + 0 + + // stack protector does not generated by LLVM because of Windows SEH. + + // all-NOT: __security_check_cookie + // strong-NOT: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test20: Addr-of a pointer +// CHECK-LABEL: test20{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test20() { + let mut a: *mut i32 = getp(); + + let mut _b: *mut *mut i32 = std::ptr::null_mut(); + + std::ptr::write_volatile(&mut _b, &mut a); + + let tmp = std::ptr::read_volatile(&_b); + + funcall2(tmp); + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test21: Addr-of a casted pointer +// CHECK-LABEL: test21{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test21() { + let mut a: *mut i32 = getp(); + + let mut _b: *mut *mut i32 = std::ptr::null_mut(); + + std::ptr::write_volatile(&mut _b, &mut a); + + let tmp = std::ptr::read_volatile(&_b); + + funfloat2(tmp as *mut *mut f64); + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test25: array of [4 x i32] +// CHECK-LABEL: test25{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test25() -> i32 { + let a: [i32; 4] = [0; 4]; + + let _whole = std::ptr::read_volatile(&a as *const _); // avoid array a from optimization + + std::ptr::read_volatile(&a[0]) + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test26: Nested structure, no arrays, no address-of expressions +// Verify that the resulting gep-of-gep does not incorrectly trigger +// a stack protector +// CHECK-LABEL: test26{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test26() { + let c = Nest { first: Pair { a: 10, b: 11 }, second: Pair { a: 20, b: 21 } }; + + let whole: Nest = std::ptr::read_volatile(&c); + + let v: i32 = whole.second.a; + + printf(STR.as_ptr(), v); + + // strong-NOT: __security_check_cookie +} + +// test27: Address-of a structure taken in a function with a loop where +// the alloca is an incoming value to a PHI node and a use of that PHI +// node is also an incoming value +// Verify that the address-of analysis does not get stuck in infinite +// recursion when chasing the alloca through the PHI nodes +// CHECK-LABEL: test27{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test27() -> i32 { + let mut tmp: *mut u8 = std::ptr::null_mut(); + let tmp_ptr: *mut *mut u8 = &mut tmp; + + let tmp1 = dummy(tmp_ptr); + + let cur = std::ptr::read_volatile(tmp_ptr); + + let v = (cur as usize as i64) as i32; + + if v > 0 { + let mut phi_ptr: *mut u8 = cur; + let mut phi_idx: i64 = 1; + let mut phi_acc: i32 = tmp1; + + loop { + let b = std::ptr::read_volatile(phi_ptr as *const u8); + let cond = b == 1u8; + let plus = phi_acc.wrapping_add(8); + let next_acc = if cond { plus } else { phi_acc }; + + if (phi_idx as i32) == v { + dummy(next_acc); + break; + } + + let slot = tmp_ptr.add(phi_idx as usize); + let next = std::ptr::read_volatile(slot); + phi_ptr = next; + phi_idx += 1; + phi_acc = next_acc; + } + } else { + dummy(tmp1); + } + + 0 + + // strong: __security_check_cookie +} + +// CHECK-LABEL: IgnoreIntrinsicTest{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn IgnoreIntrinsicTest() -> i32 { + let mut x: i32 = 0; + + std::ptr::write_volatile(&mut x, 1); + + let y = std::ptr::read_volatile(&x); + + let result = y.wrapping_mul(42); + + result + + // strong-NOT: __security_check_cookie +} From 670871a49d43c3a745f9225b3f813fa744a74fe7 Mon Sep 17 00:00:00 2001 From: cezarbbb Date: Tue, 4 Nov 2025 10:34:27 +0800 Subject: [PATCH 4/6] tests for windows 64bit. --- ...ector-heuristics-effect-windows-64bit-2.rs | 491 ++++++++++++++++++ 1 file changed, 491 insertions(+) create mode 100644 tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit-2.rs diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit-2.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit-2.rs new file mode 100644 index 0000000000000..a38b7025c5ae3 --- /dev/null +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit-2.rs @@ -0,0 +1,491 @@ +//@ revisions: all strong none missing +//@ assembly-output: emit-asm +//@ only-windows +//@ only-msvc +//@ ignore-32bit 64-bit table based SEH has slightly different behaviors than classic SEH +//@ [all] compile-flags: -Z stack-protector=all +//@ [strong] compile-flags: -Z stack-protector=strong +//@ [none] compile-flags: -Z stack-protector=none +//@ compile-flags: -C opt-level=2 -Z merge-functions=disabled + +#![crate_type = "lib"] +#![feature(unsized_fn_params)] + +extern "C" { + fn strcpy(dest: *mut u8, src: *const u8) -> *mut u8; + fn printf(fmt: *const u8, ...) -> i32; + fn funcall(p: *mut i32); + fn funcall2(p: *mut *mut i32); + fn funfloat(p: *mut f64); + fn funfloat2(p: *mut *mut f64); + fn testi_aux() -> f64; + fn getp() -> *mut i32; + fn dummy(_: ...) -> i32; + + static STR: [u8; 1]; +} + +extern "C-unwind" { + fn except(p: *mut i32); +} + +#[repr(C)] +struct Pair { + a: i32, + b: i32, +} + +#[repr(C)] +struct Nest { + first: Pair, + second: Pair, +} + +// test1: array of [16 x i8] +// CHECK-LABEL: test1{{:|\[}} +#[no_mangle] +pub fn test1(a: *const u8) { + let mut buf: [u8; 16] = [0; 16]; + + unsafe { + strcpy(buf.as_mut_ptr(), a); + printf(STR.as_ptr(), buf.as_ptr()); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test3: array [4 x i8] +// CHECK-LABEL: test3{{:|\[}} +#[no_mangle] +pub fn test3(a: *const u8) { + let mut buf: [u8; 4] = [0; 4]; + + unsafe { + strcpy(buf.as_mut_ptr(), a); + printf(STR.as_ptr(), buf.as_ptr()); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test5: no arrays / no nested arrays +// CHECK-LABEL: test5{{:|\[}} +#[no_mangle] +pub fn test5(a: *const u8) { + unsafe { + printf(STR.as_ptr(), a); + } + + // all: __security_check_cookie + // strong-NOT: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test6: Address-of local taken (j = &a) +// CHECK-LABEL: test6{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test6() { + let mut a: i32 = 0; + + let mut j: *mut i32 = std::ptr::null_mut(); + + let tmp = std::ptr::read_volatile(&a); + let tmp2 = tmp.wrapping_add(1); + std::ptr::write_volatile(&mut a, tmp2); + + std::ptr::write_volatile(&mut j, &mut a); + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test7: PtrToInt Cast +// CHECK-LABEL: test7{{:|\[}} +#[no_mangle] +pub fn test7(a: i32) { + let ptr_val: usize = &a as *const i32 as usize; + + unsafe { + printf(STR.as_ptr(), ptr_val); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test8: Passing addr-of to function call +// CHECK-LABEL: test8{{:|\[}} +#[no_mangle] +pub fn test8(mut b: i32) { + unsafe { + funcall(&mut b as *mut i32); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test9: Addr-of in select instruction +// CHECK-LABEL: test9{{:|\[}} +#[no_mangle] +pub fn test9() { + let x: f64; + + unsafe { + let call = testi_aux(); + x = call; + + let y: *const f64 = if call > 0.0 { &x as *const f64 } else { std::ptr::null() }; + + printf(STR.as_ptr(), y); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test10: Addr-of in phi instruction +// CHECK-LABEL: test10{{:|\[}} +#[no_mangle] +pub fn test10() { + let mut _x: f64; + + unsafe { + let call = testi_aux(); + _x = call; + + let y: *const f64; + + if call > 3.14 { + let call1 = testi_aux(); + _x = call1; + y = std::ptr::null(); + } else { + if call > 1.0 { + y = &_x; + } else { + y = std::ptr::null(); + } + } + + printf(STR.as_ptr(), y); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test11: Addr-of struct element(GEP followed by store) +// CHECK-LABEL: test11{{:|\[}} +#[no_mangle] +pub fn test11() { + let mut c = Pair { a: 0, b: 0 }; + let b: *mut i32; + + unsafe { + let y: *mut i32 = &mut c.b; + + b = y; + + printf(STR.as_ptr(), b); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test12: Addr-of struct element, GEP followed by ptrtoint +// CHECK-LABEL: test12{{:|\[}} +#[no_mangle] +pub fn test12() { + let mut c = Pair { a: 0, b: 0 }; + + unsafe { + let y: *mut i32 = &mut c.b; + + let addr: i64 = y as i64; + + printf(STR.as_ptr(), addr); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test13: Addr-of struct element, GEP followed by callinst +// CHECK-LABEL: test13{{:|\[}} +#[no_mangle] +pub fn test13() { + let mut c = Pair { a: 0, b: 0 }; + + unsafe { + let y: *mut i32 = &mut c.b; + + printf(STR.as_ptr(), y); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test14: Addr-of a local, optimized into a GEP (e.g., &a - 12) +// CHECK-LABEL: test14{{:|\[}} +#[no_mangle] +pub fn test14() { + let mut a: i32 = 0; + + unsafe { + let add_ptr = (&mut a as *mut i32).offset(-12); + + printf(STR.as_ptr(), add_ptr); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test15: Addr-of a local cast to a ptr of a different type +// (e.g., int a; ... ; ptr b = &a;) +// CHECK-LABEL: test15{{:|\[}} +#[no_mangle] +pub fn test15() { + let mut a: i32 = 0; + + unsafe { + let mut b: *mut i32 = std::ptr::null_mut(); + + std::ptr::write_volatile(&mut b, &mut a); // avoid ptr b from optimization + let tmp = std::ptr::read_volatile(&b); + + printf(STR.as_ptr(), tmp); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test16: Addr-of a local cast to a ptr of a different type (optimized) +// (e.g., int a; ... ; ptr b = &a;) +// CHECK-LABEL: test16{{:|\[}} +#[no_mangle] +pub fn test16() { + let a: i32 = 0; + unsafe { + funfloat((&a as *const i32).cast::() as *mut f64); + } + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test18: Addr-of a variable passed into an invoke instruction +// CHECK-LABEL: test18{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test18() -> i32 { + // CHECK-DAG: .seh_endprologue + + let mut a: i32 = 0; + + except(&mut a as *mut i32); + + 0 + + // stack protector does not generated by LLVM because of Windows SEH. + + // all-NOT: __security_check_cookie + // strong-NOT: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc +} + +// test19: Addr-of a struct element passed into an invoke instruction +// (GEP followed by an invoke) +// CHECK-LABEL: test19{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test19() -> i32 { + // CHECK-DAG: .seh_endprologue + + let mut c = Pair { a: 0, b: 0 }; + + except(&mut c.a as *mut i32); + + 0 + + // stack protector does not generated by LLVM because of Windows SEH. + + // all-NOT: __security_check_cookie + // strong-NOT: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie + + // CHECK-DAG: .seh_endproc +} + +// test20: Addr-of a pointer +// CHECK-LABEL: test20{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test20() { + let mut a: *mut i32 = getp(); + + let mut _b: *mut *mut i32 = std::ptr::null_mut(); + + std::ptr::write_volatile(&mut _b, &mut a); + + let tmp = std::ptr::read_volatile(&_b); + + funcall2(tmp); + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test21: Addr-of a casted pointer +// CHECK-LABEL: test21{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test21() { + let mut a: *mut i32 = getp(); + + let mut _b: *mut *mut i32 = std::ptr::null_mut(); + + std::ptr::write_volatile(&mut _b, &mut a); + + let tmp = std::ptr::read_volatile(&_b); + + funfloat2(tmp as *mut *mut f64); + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test25: array of [4 x i32] +// CHECK-LABEL: test25{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test25() -> i32 { + let a: [i32; 4] = [0; 4]; + + let _whole = std::ptr::read_volatile(&a as *const _); // avoid array a from optimization + + std::ptr::read_volatile(&a[0]) + + // all: __security_check_cookie + // strong: __security_check_cookie + // none-NOT: __security_check_cookie + // missing-NOT: __security_check_cookie +} + +// test26: Nested structure, no arrays, no address-of expressions +// Verify that the resulting gep-of-gep does not incorrectly trigger +// a stack protector +// CHECK-LABEL: test26{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test26() { + let c = Nest { first: Pair { a: 10, b: 11 }, second: Pair { a: 20, b: 21 } }; + + let whole: Nest = std::ptr::read_volatile(&c); + + let v: i32 = whole.second.a; + + printf(STR.as_ptr(), v); + + // strong-NOT: __security_check_cookie +} + +// test27: Address-of a structure taken in a function with a loop where +// the alloca is an incoming value to a PHI node and a use of that PHI +// node is also an incoming value +// Verify that the address-of analysis does not get stuck in infinite +// recursion when chasing the alloca through the PHI nodes +// CHECK-LABEL: test27{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn test27() -> i32 { + let mut tmp: *mut u8 = std::ptr::null_mut(); + let tmp_ptr: *mut *mut u8 = &mut tmp; + + let tmp1 = dummy(tmp_ptr); + + let cur = std::ptr::read_volatile(tmp_ptr); + + let v = (cur as usize as i64) as i32; + + if v > 0 { + let mut phi_ptr: *mut u8 = cur; + let mut phi_idx: i64 = 1; + let mut phi_acc: i32 = tmp1; + + loop { + let b = std::ptr::read_volatile(phi_ptr as *const u8); + let cond = b == 1u8; + let plus = phi_acc.wrapping_add(8); + let next_acc = if cond { plus } else { phi_acc }; + + if (phi_idx as i32) == v { + dummy(next_acc); + break; + } + + let slot = tmp_ptr.add(phi_idx as usize); + let next = std::ptr::read_volatile(slot); + phi_ptr = next; + phi_idx += 1; + phi_acc = next_acc; + } + } else { + dummy(tmp1); + } + + 0 + + // strong: __security_check_cookie +} + +// CHECK-LABEL: IgnoreIntrinsicTest{{:|\[}} +#[no_mangle] +pub unsafe extern "C" fn IgnoreIntrinsicTest() -> i32 { + let mut x: i32 = 0; + + std::ptr::write_volatile(&mut x, 1); + + let y = std::ptr::read_volatile(&x); + + let result = y.wrapping_mul(42); + + result + + // strong-NOT: __security_check_cookie +} From c49f4e1b7ca979cfeb9fe7d6484abffa280b5eee Mon Sep 17 00:00:00 2001 From: cezarbbb Date: Wed, 5 Nov 2025 11:30:57 +0800 Subject: [PATCH 5/6] test function name order correction --- .../stack-protector-heuristics-effect-2.rs | 120 +++++++++--------- ...ector-heuristics-effect-windows-32bit-2.rs | 120 +++++++++--------- ...ector-heuristics-effect-windows-64bit-2.rs | 120 +++++++++--------- 3 files changed, 180 insertions(+), 180 deletions(-) diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-2.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-2.rs index 63d3e23654b55..9d4ce84e93d23 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-2.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-2.rs @@ -60,10 +60,10 @@ pub fn test1(a: *const u8) { // missing-NOT: __stack_chk_fail } -// test3: array [4 x i8] -// CHECK-LABEL: test3{{:|\[}} +// test2: array [4 x i8] +// CHECK-LABEL: test2{{:|\[}} #[no_mangle] -pub fn test3(a: *const u8) { +pub fn test2(a: *const u8) { let mut buf: [u8; 4] = [0; 4]; unsafe { @@ -77,10 +77,10 @@ pub fn test3(a: *const u8) { // missing-NOT: __stack_chk_fail } -// test5: no arrays / no nested arrays -// CHECK-LABEL: test5{{:|\[}} +// test3: no arrays / no nested arrays +// CHECK-LABEL: test3{{:|\[}} #[no_mangle] -pub fn test5(a: *const u8) { +pub fn test3(a: *const u8) { unsafe { printf(STR.as_ptr(), a); } @@ -91,10 +91,10 @@ pub fn test5(a: *const u8) { // missing-NOT: __stack_chk_fail } -// test6: Address-of local taken (j = &a) -// CHECK-LABEL: test6{{:|\[}} +// test4: Address-of local taken (j = &a) +// CHECK-LABEL: test4{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test6() { +pub unsafe extern "C" fn test4() { let mut a: i32 = 0; let mut j: *mut i32 = std::ptr::null_mut(); @@ -111,10 +111,10 @@ pub unsafe extern "C" fn test6() { // missing-NOT: __stack_chk_fail } -// test7: PtrToInt Cast -// CHECK-LABEL: test7{{:|\[}} +// test5: PtrToInt Cast +// CHECK-LABEL: test5{{:|\[}} #[no_mangle] -pub fn test7(a: i32) { +pub fn test5(a: i32) { let ptr_val: usize = &a as *const i32 as usize; unsafe { @@ -127,10 +127,10 @@ pub fn test7(a: i32) { // missing-NOT: __stack_chk_fail } -// test8: Passing addr-of to function call -// CHECK-LABEL: test8{{:|\[}} +// test6: Passing addr-of to function call +// CHECK-LABEL: test6{{:|\[}} #[no_mangle] -pub fn test8(mut b: i32) { +pub fn test6(mut b: i32) { unsafe { funcall(&mut b as *mut i32); } @@ -141,10 +141,10 @@ pub fn test8(mut b: i32) { // missing-NOT: __stack_chk_fail } -// test9: Addr-of in select instruction -// CHECK-LABEL: test9{{:|\[}} +// test7: Addr-of in select instruction +// CHECK-LABEL: test7{{:|\[}} #[no_mangle] -pub fn test9() { +pub fn test7() { let x: f64; unsafe { @@ -162,10 +162,10 @@ pub fn test9() { // missing-NOT: __stack_chk_fail } -// test10: Addr-of in phi instruction -// CHECK-LABEL: test10{{:|\[}} +// test8: Addr-of in phi instruction +// CHECK-LABEL: test8{{:|\[}} #[no_mangle] -pub fn test10() { +pub fn test8() { let mut _x: f64; unsafe { @@ -195,10 +195,10 @@ pub fn test10() { // missing-NOT: __stack_chk_fail } -// test11: Addr-of struct element(GEP followed by store) -// CHECK-LABEL: test11{{:|\[}} +// test9: Addr-of struct element(GEP followed by store) +// CHECK-LABEL: test9{{:|\[}} #[no_mangle] -pub fn test11() { +pub fn test9() { let mut c = Pair { a: 0, b: 0 }; let b: *mut i32; @@ -216,10 +216,10 @@ pub fn test11() { // missing-NOT: __stack_chk_fail } -// test12: Addr-of struct element, GEP followed by ptrtoint -// CHECK-LABEL: test12{{:|\[}} +// test10: Addr-of struct element, GEP followed by ptrtoint +// CHECK-LABEL: test10{{:|\[}} #[no_mangle] -pub fn test12() { +pub fn test10() { let mut c = Pair { a: 0, b: 0 }; unsafe { @@ -236,10 +236,10 @@ pub fn test12() { // missing-NOT: __stack_chk_fail } -// test13: Addr-of struct element, GEP followed by callinst -// CHECK-LABEL: test13{{:|\[}} +// test11: Addr-of struct element, GEP followed by callinst +// CHECK-LABEL: test11{{:|\[}} #[no_mangle] -pub fn test13() { +pub fn test11() { let mut c = Pair { a: 0, b: 0 }; unsafe { @@ -254,10 +254,10 @@ pub fn test13() { // missing-NOT: __stack_chk_fail } -// test14: Addr-of a local, optimized into a GEP (e.g., &a - 12) -// CHECK-LABEL: test14{{:|\[}} +// test12: Addr-of a local, optimized into a GEP (e.g., &a - 12) +// CHECK-LABEL: test12{{:|\[}} #[no_mangle] -pub fn test14() { +pub fn test12() { let mut a: i32 = 0; unsafe { @@ -272,11 +272,11 @@ pub fn test14() { // missing-NOT: __stack_chk_fail } -// test15: Addr-of a local cast to a ptr of a different type +// test13: Addr-of a local cast to a ptr of a different type // (e.g., int a; ... ; ptr b = &a;) -// CHECK-LABEL: test15{{:|\[}} +// CHECK-LABEL: test13{{:|\[}} #[no_mangle] -pub fn test15() { +pub fn test13() { let mut a: i32 = 0; unsafe { @@ -294,11 +294,11 @@ pub fn test15() { // missing-NOT: __stack_chk_fail } -// test16: Addr-of a local cast to a ptr of a different type (optimized) +// test14: Addr-of a local cast to a ptr of a different type (optimized) // (e.g., int a; ... ; ptr b = &a;) -// CHECK-LABEL: test16{{:|\[}} +// CHECK-LABEL: test14{{:|\[}} #[no_mangle] -pub fn test16() { +pub fn test14() { let a: i32 = 0; unsafe { funfloat((&a as *const i32).cast::() as *mut f64); @@ -310,10 +310,10 @@ pub fn test16() { // missing-NOT: __stack_chk_fail } -// test18: Addr-of a variable passed into an invoke instruction -// CHECK-LABEL: test18{{:|\[}} +// test15: Addr-of a variable passed into an invoke instruction +// CHECK-LABEL: test15{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test18() -> i32 { +pub unsafe extern "C" fn test15() -> i32 { let mut a: i32 = 0; except(&mut a as *mut i32); @@ -326,11 +326,11 @@ pub unsafe extern "C" fn test18() -> i32 { // missing-NOT: __stack_chk_fail } -// test19: Addr-of a struct element passed into an invoke instruction +// test16: Addr-of a struct element passed into an invoke instruction // (GEP followed by an invoke) -// CHECK-LABEL: test19{{:|\[}} +// CHECK-LABEL: test16{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test19() -> i32 { +pub unsafe extern "C" fn test16() -> i32 { let mut c = Pair { a: 0, b: 0 }; except(&mut c.a as *mut i32); @@ -343,10 +343,10 @@ pub unsafe extern "C" fn test19() -> i32 { // missing-NOT: __stack_chk_fail } -// test20: Addr-of a pointer -// CHECK-LABEL: test20{{:|\[}} +// test17: Addr-of a pointer +// CHECK-LABEL: test17{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test20() { +pub unsafe extern "C" fn test17() { let mut a: *mut i32 = getp(); let mut _b: *mut *mut i32 = std::ptr::null_mut(); @@ -363,10 +363,10 @@ pub unsafe extern "C" fn test20() { // missing-NOT: __stack_chk_fail } -// test21: Addr-of a casted pointer -// CHECK-LABEL: test21{{:|\[}} +// test18: Addr-of a casted pointer +// CHECK-LABEL: test18{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test21() { +pub unsafe extern "C" fn test18() { let mut a: *mut i32 = getp(); let mut _b: *mut *mut i32 = std::ptr::null_mut(); @@ -383,10 +383,10 @@ pub unsafe extern "C" fn test21() { // missing-NOT: __stack_chk_fail } -// test25: array of [4 x i32] -// CHECK-LABEL: test25{{:|\[}} +// test19: array of [4 x i32] +// CHECK-LABEL: test19{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test25() -> i32 { +pub unsafe extern "C" fn test19() -> i32 { let a: [i32; 4] = [0; 4]; let _whole = std::ptr::read_volatile(&a as *const _); // avoid array a from optimization @@ -399,12 +399,12 @@ pub unsafe extern "C" fn test25() -> i32 { // missing-NOT: __stack_chk_fail } -// test26: Nested structure, no arrays, no address-of expressions +// test20: Nested structure, no arrays, no address-of expressions // Verify that the resulting gep-of-gep does not incorrectly trigger // a stack protector -// CHECK-LABEL: test26{{:|\[}} +// CHECK-LABEL: test20{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test26() { +pub unsafe extern "C" fn test20() { let c = Nest { first: Pair { a: 10, b: 11 }, second: Pair { a: 20, b: 21 } }; let whole: Nest = std::ptr::read_volatile(&c); @@ -416,14 +416,14 @@ pub unsafe extern "C" fn test26() { // strong-NOT: __stack_chk_fail } -// test27: Address-of a structure taken in a function with a loop where +// test21: Address-of a structure taken in a function with a loop where // the alloca is an incoming value to a PHI node and a use of that PHI // node is also an incoming value // Verify that the address-of analysis does not get stuck in infinite // recursion when chasing the alloca through the PHI nodes -// CHECK-LABEL: test27{{:|\[}} +// CHECK-LABEL: test21{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test27() -> i32 { +pub unsafe extern "C" fn test21() -> i32 { let mut tmp: *mut u8 = std::ptr::null_mut(); let tmp_ptr: *mut *mut u8 = &mut tmp; diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit-2.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit-2.rs index 1926c5039e449..8cd7f730bd5e5 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit-2.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-32bit-2.rs @@ -59,10 +59,10 @@ pub fn test1(a: *const u8) { // missing-NOT: __security_check_cookie } -// test3: array [4 x i8] -// CHECK-LABEL: test3{{:|\[}} +// test2: array [4 x i8] +// CHECK-LABEL: test2{{:|\[}} #[no_mangle] -pub fn test3(a: *const u8) { +pub fn test2(a: *const u8) { let mut buf: [u8; 4] = [0; 4]; unsafe { @@ -76,10 +76,10 @@ pub fn test3(a: *const u8) { // missing-NOT: __security_check_cookie } -// test5: no arrays / no nested arrays -// CHECK-LABEL: test5{{:|\[}} +// test3: no arrays / no nested arrays +// CHECK-LABEL: test3{{:|\[}} #[no_mangle] -pub fn test5(a: *const u8) { +pub fn test3(a: *const u8) { unsafe { printf(STR.as_ptr(), a); } @@ -90,10 +90,10 @@ pub fn test5(a: *const u8) { // missing-NOT: __security_check_cookie } -// test6: Address-of local taken (j = &a) -// CHECK-LABEL: test6{{:|\[}} +// test4: Address-of local taken (j = &a) +// CHECK-LABEL: test4{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test6() { +pub unsafe extern "C" fn test4() { let mut a: i32 = 0; let mut j: *mut i32 = std::ptr::null_mut(); @@ -110,10 +110,10 @@ pub unsafe extern "C" fn test6() { // missing-NOT: __security_check_cookie } -// test7: PtrToInt Cast -// CHECK-LABEL: test7{{:|\[}} +// test5: PtrToInt Cast +// CHECK-LABEL: test5{{:|\[}} #[no_mangle] -pub fn test7(a: i32) { +pub fn test5(a: i32) { let ptr_val: usize = &a as *const i32 as usize; unsafe { @@ -126,10 +126,10 @@ pub fn test7(a: i32) { // missing-NOT: __security_check_cookie } -// test8: Passing addr-of to function call -// CHECK-LABEL: test8{{:|\[}} +// test6: Passing addr-of to function call +// CHECK-LABEL: test6{{:|\[}} #[no_mangle] -pub fn test8(mut b: i32) { +pub fn test6(mut b: i32) { unsafe { funcall(&mut b as *mut i32); } @@ -140,10 +140,10 @@ pub fn test8(mut b: i32) { // missing-NOT: __security_check_cookie } -// test9: Addr-of in select instruction -// CHECK-LABEL: test9{{:|\[}} +// test7: Addr-of in select instruction +// CHECK-LABEL: test7{{:|\[}} #[no_mangle] -pub fn test9() { +pub fn test7() { let x: f64; unsafe { @@ -161,10 +161,10 @@ pub fn test9() { // missing-NOT: __security_check_cookie } -// test10: Addr-of in phi instruction -// CHECK-LABEL: test10{{:|\[}} +// test8: Addr-of in phi instruction +// CHECK-LABEL: test8{{:|\[}} #[no_mangle] -pub fn test10() { +pub fn test8() { let mut _x: f64; unsafe { @@ -194,10 +194,10 @@ pub fn test10() { // missing-NOT: __security_check_cookie } -// test11: Addr-of struct element(GEP followed by store) -// CHECK-LABEL: test11{{:|\[}} +// test9: Addr-of struct element(GEP followed by store) +// CHECK-LABEL: test9{{:|\[}} #[no_mangle] -pub fn test11() { +pub fn test9() { let mut c = Pair { a: 0, b: 0 }; let b: *mut i32; @@ -215,10 +215,10 @@ pub fn test11() { // missing-NOT: __security_check_cookie } -// test12: Addr-of struct element, GEP followed by ptrtoint -// CHECK-LABEL: test12{{:|\[}} +// test10: Addr-of struct element, GEP followed by ptrtoint +// CHECK-LABEL: test10{{:|\[}} #[no_mangle] -pub fn test12() { +pub fn test10() { let mut c = Pair { a: 0, b: 0 }; unsafe { @@ -235,10 +235,10 @@ pub fn test12() { // missing-NOT: __security_check_cookie } -// test13: Addr-of struct element, GEP followed by callinst -// CHECK-LABEL: test13{{:|\[}} +// test11: Addr-of struct element, GEP followed by callinst +// CHECK-LABEL: test11{{:|\[}} #[no_mangle] -pub fn test13() { +pub fn test11() { let mut c = Pair { a: 0, b: 0 }; unsafe { @@ -253,10 +253,10 @@ pub fn test13() { // missing-NOT: __security_check_cookie } -// test14: Addr-of a local, optimized into a GEP (e.g., &a - 12) -// CHECK-LABEL: test14{{:|\[}} +// test12: Addr-of a local, optimized into a GEP (e.g., &a - 12) +// CHECK-LABEL: test12{{:|\[}} #[no_mangle] -pub fn test14() { +pub fn test12() { let mut a: i32 = 0; unsafe { @@ -271,11 +271,11 @@ pub fn test14() { // missing-NOT: __security_check_cookie } -// test15: Addr-of a local cast to a ptr of a different type +// test13: Addr-of a local cast to a ptr of a different type // (e.g., int a; ... ; ptr b = &a;) -// CHECK-LABEL: test15{{:|\[}} +// CHECK-LABEL: test13{{:|\[}} #[no_mangle] -pub fn test15() { +pub fn test13() { let mut a: i32 = 0; unsafe { @@ -293,11 +293,11 @@ pub fn test15() { // missing-NOT: __security_check_cookie } -// test16: Addr-of a local cast to a ptr of a different type (optimized) +// test14: Addr-of a local cast to a ptr of a different type (optimized) // (e.g., int a; ... ; ptr b = &a;) -// CHECK-LABEL: test16{{:|\[}} +// CHECK-LABEL: test14{{:|\[}} #[no_mangle] -pub fn test16() { +pub fn test14() { let a: i32 = 0; unsafe { funfloat((&a as *const i32).cast::() as *mut f64); @@ -309,10 +309,10 @@ pub fn test16() { // missing-NOT: __security_check_cookie } -// test18: Addr-of a variable passed into an invoke instruction -// CHECK-LABEL: test18{{:|\[}} +// test15: Addr-of a variable passed into an invoke instruction +// CHECK-LABEL: test15{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test18() -> i32 { +pub unsafe extern "C" fn test15() -> i32 { let mut a: i32 = 0; except(&mut a as *mut i32); @@ -327,11 +327,11 @@ pub unsafe extern "C" fn test18() -> i32 { // missing-NOT: __security_check_cookie } -// test19: Addr-of a struct element passed into an invoke instruction +// test16: Addr-of a struct element passed into an invoke instruction // (GEP followed by an invoke) -// CHECK-LABEL: test19{{:|\[}} +// CHECK-LABEL: test16{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test19() -> i32 { +pub unsafe extern "C" fn test16() -> i32 { let mut c = Pair { a: 0, b: 0 }; except(&mut c.a as *mut i32); @@ -346,10 +346,10 @@ pub unsafe extern "C" fn test19() -> i32 { // missing-NOT: __security_check_cookie } -// test20: Addr-of a pointer -// CHECK-LABEL: test20{{:|\[}} +// test17: Addr-of a pointer +// CHECK-LABEL: test17{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test20() { +pub unsafe extern "C" fn test17() { let mut a: *mut i32 = getp(); let mut _b: *mut *mut i32 = std::ptr::null_mut(); @@ -366,10 +366,10 @@ pub unsafe extern "C" fn test20() { // missing-NOT: __security_check_cookie } -// test21: Addr-of a casted pointer -// CHECK-LABEL: test21{{:|\[}} +// test18: Addr-of a casted pointer +// CHECK-LABEL: test18{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test21() { +pub unsafe extern "C" fn test18() { let mut a: *mut i32 = getp(); let mut _b: *mut *mut i32 = std::ptr::null_mut(); @@ -386,10 +386,10 @@ pub unsafe extern "C" fn test21() { // missing-NOT: __security_check_cookie } -// test25: array of [4 x i32] -// CHECK-LABEL: test25{{:|\[}} +// test19: array of [4 x i32] +// CHECK-LABEL: test19{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test25() -> i32 { +pub unsafe extern "C" fn test19() -> i32 { let a: [i32; 4] = [0; 4]; let _whole = std::ptr::read_volatile(&a as *const _); // avoid array a from optimization @@ -402,12 +402,12 @@ pub unsafe extern "C" fn test25() -> i32 { // missing-NOT: __security_check_cookie } -// test26: Nested structure, no arrays, no address-of expressions +// test20: Nested structure, no arrays, no address-of expressions // Verify that the resulting gep-of-gep does not incorrectly trigger // a stack protector -// CHECK-LABEL: test26{{:|\[}} +// CHECK-LABEL: test20{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test26() { +pub unsafe extern "C" fn test20() { let c = Nest { first: Pair { a: 10, b: 11 }, second: Pair { a: 20, b: 21 } }; let whole: Nest = std::ptr::read_volatile(&c); @@ -419,14 +419,14 @@ pub unsafe extern "C" fn test26() { // strong-NOT: __security_check_cookie } -// test27: Address-of a structure taken in a function with a loop where +// test21: Address-of a structure taken in a function with a loop where // the alloca is an incoming value to a PHI node and a use of that PHI // node is also an incoming value // Verify that the address-of analysis does not get stuck in infinite // recursion when chasing the alloca through the PHI nodes -// CHECK-LABEL: test27{{:|\[}} +// CHECK-LABEL: test21{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test27() -> i32 { +pub unsafe extern "C" fn test21() -> i32 { let mut tmp: *mut u8 = std::ptr::null_mut(); let tmp_ptr: *mut *mut u8 = &mut tmp; diff --git a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit-2.rs b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit-2.rs index a38b7025c5ae3..ac0f89b8e9c0a 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit-2.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-heuristics-effect-windows-64bit-2.rs @@ -58,10 +58,10 @@ pub fn test1(a: *const u8) { // missing-NOT: __security_check_cookie } -// test3: array [4 x i8] -// CHECK-LABEL: test3{{:|\[}} +// test2: array [4 x i8] +// CHECK-LABEL: test2{{:|\[}} #[no_mangle] -pub fn test3(a: *const u8) { +pub fn test2(a: *const u8) { let mut buf: [u8; 4] = [0; 4]; unsafe { @@ -75,10 +75,10 @@ pub fn test3(a: *const u8) { // missing-NOT: __security_check_cookie } -// test5: no arrays / no nested arrays -// CHECK-LABEL: test5{{:|\[}} +// test3: no arrays / no nested arrays +// CHECK-LABEL: test3{{:|\[}} #[no_mangle] -pub fn test5(a: *const u8) { +pub fn test3(a: *const u8) { unsafe { printf(STR.as_ptr(), a); } @@ -89,10 +89,10 @@ pub fn test5(a: *const u8) { // missing-NOT: __security_check_cookie } -// test6: Address-of local taken (j = &a) -// CHECK-LABEL: test6{{:|\[}} +// test4: Address-of local taken (j = &a) +// CHECK-LABEL: test4{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test6() { +pub unsafe extern "C" fn test4() { let mut a: i32 = 0; let mut j: *mut i32 = std::ptr::null_mut(); @@ -109,10 +109,10 @@ pub unsafe extern "C" fn test6() { // missing-NOT: __security_check_cookie } -// test7: PtrToInt Cast -// CHECK-LABEL: test7{{:|\[}} +// test5: PtrToInt Cast +// CHECK-LABEL: test5{{:|\[}} #[no_mangle] -pub fn test7(a: i32) { +pub fn test5(a: i32) { let ptr_val: usize = &a as *const i32 as usize; unsafe { @@ -125,10 +125,10 @@ pub fn test7(a: i32) { // missing-NOT: __security_check_cookie } -// test8: Passing addr-of to function call -// CHECK-LABEL: test8{{:|\[}} +// test6: Passing addr-of to function call +// CHECK-LABEL: test6{{:|\[}} #[no_mangle] -pub fn test8(mut b: i32) { +pub fn test6(mut b: i32) { unsafe { funcall(&mut b as *mut i32); } @@ -139,10 +139,10 @@ pub fn test8(mut b: i32) { // missing-NOT: __security_check_cookie } -// test9: Addr-of in select instruction -// CHECK-LABEL: test9{{:|\[}} +// test7: Addr-of in select instruction +// CHECK-LABEL: test7{{:|\[}} #[no_mangle] -pub fn test9() { +pub fn test7() { let x: f64; unsafe { @@ -160,10 +160,10 @@ pub fn test9() { // missing-NOT: __security_check_cookie } -// test10: Addr-of in phi instruction -// CHECK-LABEL: test10{{:|\[}} +// test8: Addr-of in phi instruction +// CHECK-LABEL: test8{{:|\[}} #[no_mangle] -pub fn test10() { +pub fn test8() { let mut _x: f64; unsafe { @@ -193,10 +193,10 @@ pub fn test10() { // missing-NOT: __security_check_cookie } -// test11: Addr-of struct element(GEP followed by store) -// CHECK-LABEL: test11{{:|\[}} +// test9: Addr-of struct element(GEP followed by store) +// CHECK-LABEL: test9{{:|\[}} #[no_mangle] -pub fn test11() { +pub fn test9() { let mut c = Pair { a: 0, b: 0 }; let b: *mut i32; @@ -214,10 +214,10 @@ pub fn test11() { // missing-NOT: __security_check_cookie } -// test12: Addr-of struct element, GEP followed by ptrtoint -// CHECK-LABEL: test12{{:|\[}} +// test10: Addr-of struct element, GEP followed by ptrtoint +// CHECK-LABEL: test10{{:|\[}} #[no_mangle] -pub fn test12() { +pub fn test10() { let mut c = Pair { a: 0, b: 0 }; unsafe { @@ -234,10 +234,10 @@ pub fn test12() { // missing-NOT: __security_check_cookie } -// test13: Addr-of struct element, GEP followed by callinst -// CHECK-LABEL: test13{{:|\[}} +// test11: Addr-of struct element, GEP followed by callinst +// CHECK-LABEL: test11{{:|\[}} #[no_mangle] -pub fn test13() { +pub fn test11() { let mut c = Pair { a: 0, b: 0 }; unsafe { @@ -252,10 +252,10 @@ pub fn test13() { // missing-NOT: __security_check_cookie } -// test14: Addr-of a local, optimized into a GEP (e.g., &a - 12) -// CHECK-LABEL: test14{{:|\[}} +// test12: Addr-of a local, optimized into a GEP (e.g., &a - 12) +// CHECK-LABEL: test12{{:|\[}} #[no_mangle] -pub fn test14() { +pub fn test12() { let mut a: i32 = 0; unsafe { @@ -270,11 +270,11 @@ pub fn test14() { // missing-NOT: __security_check_cookie } -// test15: Addr-of a local cast to a ptr of a different type +// test13: Addr-of a local cast to a ptr of a different type // (e.g., int a; ... ; ptr b = &a;) -// CHECK-LABEL: test15{{:|\[}} +// CHECK-LABEL: test13{{:|\[}} #[no_mangle] -pub fn test15() { +pub fn test13() { let mut a: i32 = 0; unsafe { @@ -292,11 +292,11 @@ pub fn test15() { // missing-NOT: __security_check_cookie } -// test16: Addr-of a local cast to a ptr of a different type (optimized) +// test14: Addr-of a local cast to a ptr of a different type (optimized) // (e.g., int a; ... ; ptr b = &a;) -// CHECK-LABEL: test16{{:|\[}} +// CHECK-LABEL: test14{{:|\[}} #[no_mangle] -pub fn test16() { +pub fn test14() { let a: i32 = 0; unsafe { funfloat((&a as *const i32).cast::() as *mut f64); @@ -308,10 +308,10 @@ pub fn test16() { // missing-NOT: __security_check_cookie } -// test18: Addr-of a variable passed into an invoke instruction -// CHECK-LABEL: test18{{:|\[}} +// test15: Addr-of a variable passed into an invoke instruction +// CHECK-LABEL: test15{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test18() -> i32 { +pub unsafe extern "C" fn test15() -> i32 { // CHECK-DAG: .seh_endprologue let mut a: i32 = 0; @@ -330,11 +330,11 @@ pub unsafe extern "C" fn test18() -> i32 { // CHECK-DAG: .seh_endproc } -// test19: Addr-of a struct element passed into an invoke instruction +// test16: Addr-of a struct element passed into an invoke instruction // (GEP followed by an invoke) -// CHECK-LABEL: test19{{:|\[}} +// CHECK-LABEL: test16{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test19() -> i32 { +pub unsafe extern "C" fn test16() -> i32 { // CHECK-DAG: .seh_endprologue let mut c = Pair { a: 0, b: 0 }; @@ -353,10 +353,10 @@ pub unsafe extern "C" fn test19() -> i32 { // CHECK-DAG: .seh_endproc } -// test20: Addr-of a pointer -// CHECK-LABEL: test20{{:|\[}} +// test17: Addr-of a pointer +// CHECK-LABEL: test17{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test20() { +pub unsafe extern "C" fn test17() { let mut a: *mut i32 = getp(); let mut _b: *mut *mut i32 = std::ptr::null_mut(); @@ -373,10 +373,10 @@ pub unsafe extern "C" fn test20() { // missing-NOT: __security_check_cookie } -// test21: Addr-of a casted pointer -// CHECK-LABEL: test21{{:|\[}} +// test18: Addr-of a casted pointer +// CHECK-LABEL: test18{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test21() { +pub unsafe extern "C" fn test18() { let mut a: *mut i32 = getp(); let mut _b: *mut *mut i32 = std::ptr::null_mut(); @@ -393,10 +393,10 @@ pub unsafe extern "C" fn test21() { // missing-NOT: __security_check_cookie } -// test25: array of [4 x i32] -// CHECK-LABEL: test25{{:|\[}} +// test19: array of [4 x i32] +// CHECK-LABEL: test19{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test25() -> i32 { +pub unsafe extern "C" fn test19() -> i32 { let a: [i32; 4] = [0; 4]; let _whole = std::ptr::read_volatile(&a as *const _); // avoid array a from optimization @@ -409,12 +409,12 @@ pub unsafe extern "C" fn test25() -> i32 { // missing-NOT: __security_check_cookie } -// test26: Nested structure, no arrays, no address-of expressions +// test20: Nested structure, no arrays, no address-of expressions // Verify that the resulting gep-of-gep does not incorrectly trigger // a stack protector -// CHECK-LABEL: test26{{:|\[}} +// CHECK-LABEL: test20{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test26() { +pub unsafe extern "C" fn test20() { let c = Nest { first: Pair { a: 10, b: 11 }, second: Pair { a: 20, b: 21 } }; let whole: Nest = std::ptr::read_volatile(&c); @@ -426,14 +426,14 @@ pub unsafe extern "C" fn test26() { // strong-NOT: __security_check_cookie } -// test27: Address-of a structure taken in a function with a loop where +// test21: Address-of a structure taken in a function with a loop where // the alloca is an incoming value to a PHI node and a use of that PHI // node is also an incoming value // Verify that the address-of analysis does not get stuck in infinite // recursion when chasing the alloca through the PHI nodes -// CHECK-LABEL: test27{{:|\[}} +// CHECK-LABEL: test21{{:|\[}} #[no_mangle] -pub unsafe extern "C" fn test27() -> i32 { +pub unsafe extern "C" fn test21() -> i32 { let mut tmp: *mut u8 = std::ptr::null_mut(); let tmp_ptr: *mut *mut u8 = &mut tmp; From c9d0ee10a25e34791c40c8711c9fd7f25fb8bb26 Mon Sep 17 00:00:00 2001 From: cezarbbb Date: Thu, 6 Nov 2025 12:10:45 +0800 Subject: [PATCH 6/6] add -Cunsafe-allow-abi-mismatch=sanitizer to silence ABI mismatch error --- .../stack-protector/stack-protector-safe-stack.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/assembly-llvm/stack-protector/stack-protector-safe-stack.rs b/tests/assembly-llvm/stack-protector/stack-protector-safe-stack.rs index 93c638b0527d6..14e1c3fed6db2 100644 --- a/tests/assembly-llvm/stack-protector/stack-protector-safe-stack.rs +++ b/tests/assembly-llvm/stack-protector/stack-protector-safe-stack.rs @@ -8,8 +8,11 @@ //@ [strong] compile-flags: -Z stack-protector=strong //@ [none] compile-flags: -Z stack-protector=none //@ [safestack] compile-flags: -Z stack-protector=none -Z sanitizer=safestack +// RUSTFLAGS: -Cunsafe-allow-abi-mismatch=sanitizer //@ [safestack_strong] compile-flags: -Z stack-protector=strong -Z sanitizer=safestack +// RUSTFLAGS: -Cunsafe-allow-abi-mismatch=sanitizer //@ [safestack_all] compile-flags: -Z stack-protector=all -Z sanitizer=safestack +// RUSTFLAGS: -Cunsafe-allow-abi-mismatch=sanitizer //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled #![crate_type = "lib"]