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)

Reply via email to