summaryrefslogtreecommitdiff
path: root/include/mupdf/fitz/context.h
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2015-09-28 15:24:00 +0100
committerRobin Watts <robin.watts@artifex.com>2015-09-30 17:35:42 +0100
commit1f15bade3112bfdc8ddbae9c4b06047427c2367f (patch)
tree3a7b21fd984e2b16040939fbab6022e0fe7f12cd /include/mupdf/fitz/context.h
parent399a04b4af991c71826ce0e6962a23b4f8fa127d (diff)
downloadmupdf-1f15bade3112bfdc8ddbae9c4b06047427c2367f.tar.xz
Bug 696115: Further fix for setjmp/longjmp.
Tor turned up an interesting section in the C spec about this. See page 275 of http://open-std.org/jtc1/sc22/wg14/www/docs/n1494.pdf regarding acceptable places for setjmp to occur. It seems that: if (setjmp(buf)) if (!setjmp(buf)) if (setjmp(buf) {==,!=,<,>} <integer constant>) etc are all valid things to do, but assignments (and subsequent testing of values) like: if ((code = setjmp(buf)) == 0) are not allowed. Further, it's not even clear that: if (a() && setjmp(buf)) is permissible. We therefore recast the macros into the form: a(); if (setjmp((buf)) == 0) which should be acceptable under the C spec. To keep try atomic, we introduce a block '{{{' around this, along with a matching close block '}}}' in the catch clause. This has the nifty extra effect of giving us a compile time error if we mismatch our try/catches.
Diffstat (limited to 'include/mupdf/fitz/context.h')
-rw-r--r--include/mupdf/fitz/context.h22
1 files changed, 4 insertions, 18 deletions
diff --git a/include/mupdf/fitz/context.h b/include/mupdf/fitz/context.h
index 905a82ef..cb083f87 100644
--- a/include/mupdf/fitz/context.h
+++ b/include/mupdf/fitz/context.h
@@ -49,18 +49,9 @@ void fz_var_imp(void *);
attention to the man behind the curtain.
*/
-/*
- OK, so you looked behind the curtain, and you're wondering why we use
- an inline function for fz_trying, rather than doing a bare assignment
- and test. See bug 696115. Various versions of gcc (depressingly,
- modern ones) cause problems under optimisation whereby the value
- returned from setjmp is not written correctly. This causes the rest
- of the try/catch to behave incorrectly. The use of a function call
- here suffices to solve it.
-*/
#define fz_try(ctx) \
- if (fz_push_try(ctx->error) && \
- fz_trying(ctx->error, fz_setjmp(ctx->error->stack[ctx->error->top].buffer)))\
+ {{{ fz_push_try(ctx->error); \
+ if (fz_setjmp(ctx->error->stack[ctx->error->top].buffer) == 0)\
{ do {
#define fz_always(ctx) \
@@ -73,15 +64,10 @@ void fz_var_imp(void *);
#define fz_catch(ctx) \
} while(0); \
- } \
+ } }}} \
if (ctx->error->stack[ctx->error->top--].code > 1)
-int fz_push_try(fz_error_context *ex);
-static inline int fz_trying(fz_error_context *error, int value)
-{
- error->stack[error->top].code = value;
- return value == 0;
-}
+void fz_push_try(fz_error_context *ex);
FZ_NORETURN void fz_throw(fz_context *, int errcode, const char *, ...) __printflike(3, 4);
FZ_NORETURN void fz_rethrow(fz_context *);
FZ_NORETURN void fz_rethrow_message(fz_context *, const char *, ...) __printflike(2, 3);