Closed
Description
fn main() {
let _vec: Vec<u8> = Vec::new();
std::fs::create_dir(std::path::Path::new("a")).unwrap();
}
Will crash when compiled with rustc -C opt-level=z main.rs
.
> rustup run nightly-i686-pc-windows-msvc rustc --version -v
rustc 1.22.0-nightly (4502e2aa9 2017-10-03)
binary: rustc
commit-hash: 4502e2aa9c28d8caa610fc1815fd9c5b5a16e91c
commit-date: 2017-10-03
host: i686-pc-windows-msvc
release: 1.22.0-nightly
LLVM version: 4.0
The asm for main is
__ZN4main4main17h0bca12b325d77113E:
Lfunc_begin2:
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %edi
pushl %esi
andl $-8, %esp
subl $72, %esp
movl %esp, %esi
movl %ebp, 48(%esi)
leal 56(%esi), %eax
movl %esp, -4(%eax)
orl $-1, 8(%eax)
movl $___ehhandler$_ZN4main4main17h0bca12b325d77113E, 4(%eax)
movl %fs:0, %ecx
movl %ecx, (%eax)
xorl %ecx, %ecx
movl %eax, %fs:0
andl $0, 8(%eax)
incl %ecx
movl %ecx, 12(%esi)
andl $0, 16(%esi)
andl $0, 20(%esi)
pushl %ecx
pushl $_str.7
calll __ZN3std3ffi6os_str85_$LT$impl$u20$core..convert..AsRef$LT$std..ffi..os_str..OsStr$GT$$u20$for$u20$str$GT$6as_ref17h154d386d199535e3E
popl %ecx
popl %esi
movl %eax, 8(%esi)
movl %edx, 4(%esi)
calll __ZN3std2fs10DirBuilder3new17h2a2d998af5809e7bE
movb %al, 24(%esi)
pushl 4(%esi)
pushl 8(%esi)
calll __ZN79_$LT$std..path..Path$u20$as$u20$core..convert..AsRef$LT$std..path..Path$GT$$GT$6as_ref17hbd919da430f6c47cE
popl %ecx
popl %esi
pushl %edx
pushl %eax
calll __ZN79_$LT$std..path..Path$u20$as$u20$core..convert..AsRef$LT$std..path..Path$GT$$GT$6as_ref17hbd919da430f6c47cE
popl %ecx
popl %esi
leal 24(%esi), %ecx
leal 36(%esi), %edi
pushl %edx
pushl %eax
pushl %ecx
pushl %edi
calll __ZN3std2fs10DirBuilder7_create17h457ad352f6fc1a89E
addl $16, %esp
cmpl $0, 36(%esi)
jne LBB6_6
leal 12(%esi), %ecx
calll __ZN4core3ptr13drop_in_place17h8b2fec8553a09995E
movl 56(%esi), %eax
movl %eax, %fs:0
leal -12(%ebp), %esp
popl %esi
popl %edi
popl %ebx
popl %ebp
retl
LBB6_6:
movl 40(%esi), %eax
movl 44(%esi), %edx
leal 24(%esi), %ecx
movl %edx, 4(%ecx)
movl %eax, (%ecx)
calll __ZN4core6result13unwrap_failed17h0ccedc4bcd16baddE
.def "?dtor$9@?0?_ZN4main4main17h0bca12b325d77113E@4HA";
.scl 3;
.type 32;
.endef
"?dtor$9@?0?_ZN4main4main17h0bca12b325d77113E@4HA":
LBB6_9:
pushl %ebp
subl $16, %esp
leal -68(%ebp), %esi
movl 48(%esi), %ebp
leal 12(%esi), %ecx
calll __ZN4core3ptr13drop_in_place17h8b2fec8553a09995E
addl $16, %esp
popl %ebp
retl
Specifically, the function uses esi
to store a local variable, but after
__ZN79_$LT$std..path..Path$u20$as$u20$core..convert..AsRef$LT$std..path..Path$GT$$GT$6as_ref17hbd919da430f6c47cE
one of the function arguments are popped from stack with popl %esi
..
When using -C panic=abort
, or i686-pc-windows-gnu
, or removing the _vec
, the code compiles correctly (uses only popl %ecx
), so the cause may be related to stack unwinding?
The issue also doesn't occur with -C opt-level=s
, which uses one byte larger addl $8, %esp
instead of two pops.
Not sure if this happens on x86-64, at least the example works fine as the calling convention won't have to use stack there.