https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77448
Bug ID: 77448 Summary: Incorrect code generation for calling stack object's method Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: nfitzgerald at mozilla dot com CC: j...@red-bean.com Target Milestone: --- Created attachment 39536 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39536&action=edit zipped testcase.ii Here is the source of `JS::CallArgs::create` (full, pre-processed test case in attachment): > class MOZ_STACK_CLASS CallArgs : public > detail::CallArgsBase<detail::IncludeUsedRval> > { > private: > friend CallArgs CallArgsFromVp(unsigned argc, Value* vp); > friend CallArgs CallArgsFromSp(unsigned stackSlots, Value* sp, bool > constructing); > > static CallArgs create(unsigned argc, Value* argv, bool constructing) { > CallArgs args; > args.clearUsedRval(); > args.argv_ = argv; > args.argc_ = argc; > args.constructing_ = constructing; > return args; > } > > public: > /* > * Returns true if there are at least |required| arguments passed in. If > * false, it reports an error message on the context. > */ > bool requireAtLeast(JSContext* cx, const char* fnname, unsigned required) > const; > > }; Here is the disassembly: > Dump of assembler code for function JS::CallArgs::create(unsigned int, > JS::Value*, bool): > 0x000055df6e6f5c0a <+0>: push rbp > 0x000055df6e6f5c0b <+1>: mov rbp,rsp > 0x000055df6e6f5c0e <+4>: sub rsp,0x20 > 0x000055df6e6f5c12 <+8>: mov QWORD PTR [rbp-0x8],rdi > 0x000055df6e6f5c16 <+12>: mov DWORD PTR [rbp-0xc],esi > 0x000055df6e6f5c19 <+15>: mov QWORD PTR [rbp-0x18],rdx > 0x000055df6e6f5c1d <+19>: mov eax,ecx > 0x000055df6e6f5c1f <+21>: mov BYTE PTR [rbp-0x10],al > 0x000055df6e6f5c22 <+24>: mov rax,QWORD PTR [rbp-0x8] > 0x000055df6e6f5c26 <+28>: mov rdi,rax > 0x000055df6e6f5c29 <+31>: call 0x55df6e6f5bf8 > <JS::detail::IncludeUsedRval::clearUsedRval() const> > 0x000055df6e6f5c2e <+36>: mov rax,QWORD PTR [rbp-0x8] > 0x000055df6e6f5c32 <+40>: mov rdx,QWORD PTR [rbp-0x18] > 0x000055df6e6f5c36 <+44>: mov QWORD PTR [rax+0x8],rdx > 0x000055df6e6f5c3a <+48>: mov rax,QWORD PTR [rbp-0x8] > 0x000055df6e6f5c3e <+52>: mov edx,DWORD PTR [rbp-0xc] > 0x000055df6e6f5c41 <+55>: mov DWORD PTR [rax+0x10],edx > 0x000055df6e6f5c44 <+58>: mov rax,QWORD PTR [rbp-0x8] > 0x000055df6e6f5c48 <+62>: movzx edx,BYTE PTR [rbp-0x10] > 0x000055df6e6f5c4c <+66>: mov BYTE PTR [rax+0x14],dl > 0x000055df6e6f5c4f <+69>: nop > 0x000055df6e6f5c50 <+70>: mov rax,QWORD PTR [rbp-0x8] > 0x000055df6e6f5c54 <+74>: leave > 0x000055df6e6f5c55 <+75>: ret > End of assembler dump. Notice how %rdi, the first parameter, is saved onto the stack, then the value is read back from the stack into %rdi and passed as the `this` parameter to the `clearUsedRval` method. This is incorrect. ----------------------------------------- Invoked with these flags: > $ /usr/lib64/ccache/g++ -std=gnu++11 -S > -I/home/fitzgen/src/rust-mozjs/target/debug/build/mozjs_sys-e6acb629d67eff9a/out/dist/system_wrappers > -include > /home/fitzgen/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/smup/mozjs/config/gcc_hidden.h > -DDEBUG=1 -DTRACING=1 -DENABLE_BINARYDATA -DENABLE_SIMD > -DENABLE_SHARED_ARRAY_BUFFER -DEXPORT_JS_API > -I/home/fitzgen/.cargo/git/checkouts/mozjs-fa11ffc7d4f1cc2d/smup/mozjs/js/src > -I/home/fitzgen/src/rust-mozjs/target/debug/build/mozjs_sys-e6acb629d67eff9a/out/js/src > > -I/home/fitzgen/src/rust-mozjs/target/debug/build/mozjs_sys-e6acb629d67eff9a/out/dist/include > -fPIC -DMOZILLA_CLIENT -include > /home/fitzgen/src/rust-mozjs/target/debug/build/mozjs_sys-e6acb629d67eff9a/out/js/src/js-confdefs.h > -MD -MP -MF .deps/Unified_cpp_js_src4.o.pp -Wall -Wc++11-compat > -Wempty-body -Wignored-qualifiers -Woverloaded-virtual -Wpointer-arith > -Wsign-compare -Wtype-limits -Wunreachable-code -Wwrite-strings > -Wno-invalid-offsetof -Wc++14-compat -Wno-error=maybe-uninitialized > -Wno-error=deprecated-declarations -Wno-error=array-bounds -fno-rtti > -fno-exceptions -fno-math-errno -pthread -pipe -g -fno-omit-frame-pointer > -Wno-shadow ~/scratch/testcase.ii ----------------------------------------- > $ gcc -v > Using built-in specs. > COLLECT_GCC=/usr/bin/gcc > COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/6.1.1/lto-wrapper > Target: x86_64-redhat-linux > Configured with: ../configure --enable-bootstrap > --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --prefix=/usr > --mandir=/usr/share/man --infodir=/usr/share/info > --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared > --enable-threads=posix --enable-checking=release --enable-multilib > --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions > --enable-gnu-unique-object --enable-linker-build-id > --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array > --disable-libgcj --with-isl --enable-libmpx --enable-gnu-indirect-function > --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux > Thread model: posix > gcc version 6.1.1 20160621 (Red Hat 6.1.1-3) (GCC)