#include "excpt.h"
+/* CLANG must safe non-volatiles, because it uses a return-twice algorithm */
+#if defined(__clang__) && !defined(_SEH3$_FRAME_ALL_NONVOLATILES)
+#define _SEH3$_FRAME_ALL_NONVOLATILES 1
+#endif
+
typedef struct _SEH3$_SCOPE_TABLE
{
void *Target;
/* Registers that we need to save */
unsigned long Esp;
unsigned long Ebp;
-
+#ifdef _SEH3$_FRAME_ALL_NONVOLATILES
+ unsigned long Ebx;
+ unsigned long Esi;
+ unsigned long Edi;
+#endif
} SEH3$_REGISTRATION_FRAME ,*PSEH3$_REGISTRATION_FRAME;
/* Prevent gcc from inlining functions that use SEH. */
/* This is an asm wrapper around _SEH3$_RegisterFrame */
#define _SEH3$_RegisterFrame(_TrylevelFrame, _DataTable, _Target) \
- asm goto ("leal %0, %%ecx\n" \
+ asm goto ("leal %0, %%edx\n" \
"call __SEH3$_RegisterFrame\n" \
: \
: "m" (*(_TrylevelFrame)), "a" (_DataTable) \
/* This is an asm wrapper around _SEH3$_EnterTryLevel */
#define _SEH3$_RegisterTryLevel(_TrylevelFrame, _DataTable, _Target) \
- asm goto ("leal %0, %%ecx\n" \
+ asm goto ("leal %0, %%edx\n" \
"call __SEH3$_RegisterTryLevel\n" \
: \
: "m" (*(_TrylevelFrame)), "a" (_DataTable) \
(__builtin_constant_p(_FilterExpression) ? (void*)(unsigned long)(unsigned char)(unsigned long)(_FilterExpression) : _Filter)
#define _SEH3$_DEFINE_DUMMY_FINALLY(_Name) \
- auto inline __attribute__((always_inline,gnu_inline)) int _Name(int Action) { return 0; }
+ auto inline __attribute__((always_inline,gnu_inline)) int _Name(int Action) { (void)Action; return 0; }
#define _SEH3$_DECLARE_CLEANUP_FUNC(_Name) \
auto inline __attribute__((always_inline,gnu_inline)) void _Name(volatile SEH3$_REGISTRATION_FRAME *p)
#define _SEH3$_DEFINE_CLEANUP_FUNC(_Name) \
_SEH3$_DECLARE_CLEANUP_FUNC(_Name) \
{ \
+ (void)p; \
/* Unregister the frame */ \
if (_SEH3$_TryLevel == 1) _SEH3$_UnregisterFrame(&_SEH3$_TrylevelFrame); \
else _SEH3$_UnregisterTryLevel(&_SEH3$_TrylevelFrame); \
\
if (1) \
{ \
+ /* Prevent this block from being optimized away */ \
+ asm volatile ("#\n"); \
do