<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 - WinException: Off-by-one building IP2state table"
href="https://bugs.llvm.org/show_bug.cgi?id=46358">46358</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>WinException: Off-by-one building IP2state table
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</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>Backend: X86
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>sneves@dei.uc.pt
</td>
</tr>
<tr>
<th>CC</th>
<td>craig.topper@gmail.com, llvm-bugs@lists.llvm.org, llvm-dev@redking.me.uk, spatel+llvm@rotateright.com
</td>
</tr></table>
<p>
<div>
<pre>Consider the following example C++ code:
#include <cstdio>
int main(int argc, char* argv[]) {
try {
try {
puts(new char[argc]());
} catch(...) {
return -2;
}
} catch(...) {
return -1;
}
}
It doesn't really matter what it does, all it matters is that there are a few
try..catch blocks that don't get elided. Compiling this with `clang-cl.exe -O2
-EHsc /FA /Fatest.asm test.cpp` we get in test.asm
$ip2state$main:
.long .Lfunc_begin0@IMGREL # IP
.long -1 # ToState
.long .Ltmp0@IMGREL+1 # IP
.long 1 # ToState
.long .Ltmp1@IMGREL+1 # IP
.long -1 # ToState
.long "?catch$3@?0?main@4HA"@IMGREL # IP
.long 3 # ToState
.long "?catch$4@?0?main@4HA"@IMGREL # IP
.long 2 # ToState
Now, as you can see, both beginning of the try block offsets in there are off
byte a single byte (the +1). I tracked this down to
<a href="https://github.com/llvm/llvm-project/blob/50155bcd46428eda1551efe9616f6611b0ef779a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp#L885-L937">https://github.com/llvm/llvm-project/blob/50155bcd46428eda1551efe9616f6611b0ef779a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp#L885-L937</a>
In particular, we have
// Emit an entry indicating that PCs after 'Label' have this EH state.
IPToStateTable.push_back(std::make_pair(getLabel(ChangeLabel),
StateChange.NewState));
but looking at the definition of getLabel, we see that (unless the target is
Aarch64, for whatever reason) it adds 1 to the address of its argument. The
following diff appears to fix this issue, although I do not know if it's a
proper fix:
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index 039867557..b0d48458c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -929,7 +929,7 @@ void WinException::computeIP2StateTable(
ChangeLabel = StateChange.PreviousEndLabel;
// Emit an entry indicating that PCs after 'Label' have this EH state.
IPToStateTable.push_back(
- std::make_pair(getLabel(ChangeLabel), StateChange.NewState));
+ std::make_pair(create32bitRef(ChangeLabel), StateChange.NewState));
// FIXME: assert that NewState is between CatchLow and CatchHigh.
}
}
With this patch, the above output becomes
$ip2state$main:
.long .Lfunc_begin0@IMGREL # IP
.long -1 # ToState
.long .Ltmp0@IMGREL # IP
.long 1 # ToState
.long .Ltmp1@IMGREL # IP
.long -1 # ToState
.long "?catch$3@?0?main@4HA"@IMGREL # IP
.long 3 # ToState
.long "?catch$4@?0?main@4HA"@IMGREL # IP
.long 2 # ToState
as expected.</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>