<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - MSVC: noexcept aborts with longjmp"
href="https://bugs.llvm.org/show_bug.cgi?id=36508">36508</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>MSVC: noexcept aborts with longjmp
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Windows NT
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>LLVM Codegen
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>alex@crichton.co
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org, rnk@google.com
</td>
</tr></table>
<p>
<div>
<pre>This is a sort of roundabout bug with respect to where it originated from, but
the gist of it is that this program:
#include <assert.h>
#include <setjmp.h>
#include <stdio.h>
static jmp_buf ENV;
static void test_end() {
longjmp(ENV, 1);
assert(0);
}
static void test_middle() noexcept {
test_end();
}
static void test_start() {
if (setjmp(ENV) != 0)
return;
test_middle();
assert(0);
}
int main() {
test_start();
printf("good\n");
return 0;
}
will abort when compiled with Clang and succeed when compiled with cl.exe. More
specifically when compiled with `cl.exe foo.cpp /EHsc` the program will succeed
and print "good", but when compiled with `clang-cl.exe foo.cpp /EHsc` it will
instead abort.
I believe the issue here is that the `test_middle` function, declared with
`noexcept`, will abort thinking that it threw an exception. It appears that on
MSVC the `longjmp` function is implemented with an exception-like mechanism
which I believe triggers the landing pad generated by `test_middle` to abort
when an exception is thrown.
This bug actually came from an upstream Rust bug [1] which has quite a long
thread! The gist of it is that in Rust 1.24.0 we effectively turned on
`noexcept` for a certain class of Rust functions by default. This change
regressed on MSVC for us in that it broke users who wanted to longjmp across
Rust frames back to C (for example with other languages like Lua and Ruby).
I did some investigation to see what Clang did (as right now Rust's
exception-related MSVC codegen attempts to closely match what Clang does) and I
figured y'all may be interested in this as well! This may or may not be a bug
in
Clang (I'm not sure), so feel free to close if this isn't relevant for clang.
[1]: <a href="https://github.com/rust-lang/rust/issues/48251">https://github.com/rust-lang/rust/issues/48251</a></pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>