[LLVMbugs] [Bug 18206] New: Inliner wrongly inlines functions that invoke setjmp()

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Dec 10 20:47:12 PST 2013


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

            Bug ID: 18206
           Summary: Inliner wrongly inlines functions that invoke setjmp()
           Product: tools
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: opt
          Assignee: mseaborn at chromium.org
          Reporter: mseaborn at chromium.org
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

The inliner will avoid inlining functions that call setjmp() using a "call"
instruction, but it doesn't do the same for functions that call setjmp() using
an "invoke" instruction.

Here's an example of a miscompilation that can result:

#include <stdio.h>

typedef char jmp_buf[1000];
extern "C" {
  // Declare setjmp() without "__attribute__((nothrow))":
  int setjmp(jmp_buf env);
  void longjmp(jmp_buf env, int val);
}

jmp_buf buf;

static void inner(int *ptr) throw() {
  *ptr = 0;
  if (!setjmp(buf)) {
    *ptr = 1;
    longjmp(buf, 1);
  } else {
    puts(*ptr ? "passed" : "failed");
  }
}

int main() {
  int ptr;
  inner(&ptr);
  return 0;
}

This currently prints "passed" when compiled with -O0, but "failed" when
compiled with -O2.

An "invoke" of setjmp() can occur if:
 * setjmp() is called in an exception-handling context, e.g. in C++ a
destructor implicitly declared as "nothrow".
 * setjmp() is declared without "nothrow".  e.g. glibc's headers declare
setjmp() with "nothrow", but not all headers do.

I'll prepare a fix.

-- 
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/20131211/4e601f0d/attachment.html>


More information about the llvm-bugs mailing list