[LLVMbugs] [Bug 21183] New: Incorrectly clobbering stack slot for a local variable used after longjmp

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Oct 7 04:23:25 PDT 2014


http://llvm.org/bugs/show_bug.cgi?id=21183

            Bug ID: 21183
           Summary: Incorrectly clobbering stack slot for a local variable
                    used after longjmp
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: MacOS X
            Status: NEW
          Severity: normal
          Priority: P
         Component: Common Code Generator Code
          Assignee: unassignedbugs at nondot.org
          Reporter: glider at google.com
                CC: kcc at google.com, llvmbugs at cs.uiuc.edu
    Classification: Unclassified

For the following class method (see decoder.ii attached) Clang appears to
generate incorrect code:

  void decode() {
    PNGImageDecoder* decoder =
        static_cast<PNGImageDecoder*>(wk_png_get_progressive_ptr(m_void));
    const char* segment;
    if (setjmp(m_png->jmpbuf)) {
      decoder->setFailed();
      return;
    }   
    while (true) {
      getSomeData(segment, m_readOffset);
      m_readOffset++;
      wk_png_process_data(m_info, segment);
      if (decoder->ImageDecoder::isSizeAvailable())
        return;
    }   
  }

$ clang++ -O3 -gdwarf-2 -fvisibility=hidden  -mmacosx-version-min=10.6 -arch
i386  -std=gnu++11 -fno-rtti -fno-exceptions -fvisibility-inlines-hidden
-fno-threadsafe-statics -fsanitize=address -mllvm -asan-globals=0
-gline-tables-only -c decoder.ii -o decoder.o

# See decoder.o.dump attached.
$ gobjdump -rd decoder.o

00000260 <__ZN14PNGImageReader6decodeEv>:
...
 2f2:   e8 09 fd ff ff          call   0 <__ZN15PNGImageDecoder6decodeEv>
                        2f3: DISP32     _wk_png_get_progressive_ptr
 2f7:   89 44 24 0c             mov    %eax,0xc(%esp)
...
 319:   e8 e2 fc ff ff          call   0 <__ZN15PNGImageDecoder6decodeEv>
                        31a: DISP32     _setjmp
 31e:   85 c0                   test   %eax,%eax
 320:   74 41                   je     363
<__ZN14PNGImageReader6decodeEv+0x103>
 322:   8b 54 24 0c             mov    0xc(%esp),%edx
...
 341:   8b 02                   mov    (%edx),%eax
 343:   83 c0 04                add    $0x4,%eax
 346:   89 c1                   mov    %eax,%ecx
...
 35c:   ff 10                   call   *(%eax)
 35e:   e9 6a 01 00 00          jmp    4cd
<__ZN14PNGImageReader6decodeEv+0x26d>
 363:   89 7c 24 14             mov    %edi,0x14(%esp)
...
 36e:   8b 44 24 0c             mov    0xc(%esp),%eax
 372:   8d 88 89 00 00 00       lea    0x89(%eax),%ecx
 378:   89 4c 24 08             mov    %ecx,0x8(%esp)
 37c:   8d 7e 0c                lea    0xc(%esi),%edi
 37f:   83 c6 08                add    $0x8,%esi
 382:   89 74 24 10             mov    %esi,0x10(%esp)
 386:   05 8a 00 00 00          add    $0x8a,%eax
 38b:   89 44 24 0c             mov    %eax,0xc(%esp)
 38f:   90                      nop

In the assembly above the value of |decoder| is stored in 0xc(%esp) before the
call to setjmp().
If setjmp() returns non-zero (i.e. after longjmp()) then |decoder| is loaded
from the stack slot and dereferenced.
But if setjmp returns zero then in the infinite loop the value of |decoder| is
loaded (at address 36e), incremented by 0x8a and stored back to the stack slot
0xc(%esp) (at address 38b).

Because the infinite loop calls getSomeData() and wk_png_process_data() which
may potentially call longjmp(), I believe that such optimization is incorrect
and 0xc(%esp) should not be clobbered.
Note that |decoder| isn't being changed between setjmp() and longjmp(), so the
following part of the C11 Standard (7.13.2.1) does not apply:

> All accessible objects have values, and all other components of the abstract machine249)
> have state, as of the time the longjmp function was called, except that the values of
> objects of automatic storage duration that are local to the function containing the
> invocation of the corresponding setjmp macro that do not have volatile-qualified type
> and have been changed between the setjmp invocation and longjmp call are
> indeterminate.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20141007/c843bfbe/attachment.html>


More information about the llvm-bugs mailing list