From fe7d5323f5bc734e76179b74d68fcba9b924ba94 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Thu, 19 Feb 2009 16:00:17 -0500 Subject: [PATCH] Relanding: Add CAIRO_ENSURE_UNIQUE macro and use it in _cairo_error() When using MSVC, _cairo_error() can be folded into other identical functions. If that happens, _cairo_error isn't really useful anymore. Using the CAIRO_ENSURE_UNIQUE macro makes sure this doesn't happen. Use __asm to serve as a line delimiter. This allows us to use the __asm{} block in a macro. --- src/cairo-compiler-private.h | 24 ++++++++++++++++++++++++ src/cairo.c | 1 + 2 files changed, 25 insertions(+) diff --git a/src/cairo-compiler-private.h b/src/cairo-compiler-private.h index bd7cccd9b..f796e1380 100644 --- a/src/cairo-compiler-private.h +++ b/src/cairo-compiler-private.h @@ -172,6 +172,30 @@ #define inline __inline #endif +#ifdef _MSC_VER +/* When compiling with /Gy and /OPT:ICF identical functions will be folded in together. + The CAIRO_ENSURE_UNIQUE macro ensures that a function is always unique and + will never be folded into another one. Something like this might eventually + be needed for GCC but it seems fine for now. */ +#define CAIRO_ENSURE_UNIQUE \ + do { \ + char func[] = __FUNCTION__; \ + char file[] = __FILE__; \ + __asm { \ + __asm jmp __internal_skip_line_no \ + __asm _emit (__LINE__ & 0xff) \ + __asm _emit ((__LINE__>>8) & 0xff) \ + __asm _emit ((__LINE__>>16) & 0xff) \ + __asm _emit ((__LINE__>>24) & 0xff) \ + __asm lea eax, func \ + __asm lea eax, file \ + __asm __internal_skip_line_no: \ + }; \ + } while (0) +#else +#define CAIRO_ENSURE_UNIQUE do { } while (0) +#endif + #ifdef __STRICT_ANSI__ #undef inline #define inline __inline__ diff --git a/src/cairo.c b/src/cairo.c index 4aa52f698..ddc8d4a96 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -82,6 +82,7 @@ static const cairo_t _cairo_nil = { cairo_status_t _cairo_error (cairo_status_t status) { + CAIRO_ENSURE_UNIQUE; assert (_cairo_status_is_error (status)); return status;