1
/* cairo - a vector graphics library with display and print output
2
 *
3
 * Copyright © 2002 University of Southern California
4
 * Copyright © 2005 Red Hat, Inc.
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it either under the terms of the GNU Lesser General Public
8
 * License version 2.1 as published by the Free Software Foundation
9
 * (the "LGPL") or, at your option, under the terms of the Mozilla
10
 * Public License Version 1.1 (the "MPL"). If you do not alter this
11
 * notice, a recipient may use your version of this file under either
12
 * the MPL or the LGPL.
13
 *
14
 * You should have received a copy of the LGPL along with this library
15
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17
 * You should have received a copy of the MPL along with this library
18
 * in the file COPYING-MPL-1.1
19
 *
20
 * The contents of this file are subject to the Mozilla Public License
21
 * Version 1.1 (the "License"); you may not use this file except in
22
 * compliance with the License. You may obtain a copy of the License at
23
 * http://www.mozilla.org/MPL/
24
 *
25
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27
 * the specific language governing rights and limitations.
28
 *
29
 * The Original Code is the cairo graphics library.
30
 *
31
 * The Initial Developer of the Original Code is University of Southern
32
 * California.
33
 *
34
 * Contributor(s):
35
 *	Carl D. Worth <cworth@cworth.org>
36
 */
37

            
38
#ifndef CAIRO_COMPILER_PRIVATE_H
39
#define CAIRO_COMPILER_PRIVATE_H
40

            
41
#include "cairo.h"
42

            
43
#include "config.h"
44

            
45
#include <stddef.h> /* size_t */
46
#include <stdint.h> /* SIZE_MAX */
47

            
48
/* Size in bytes of buffer to use off the stack per functions.
49
 * Mostly used by text functions.  For larger allocations, they'll
50
 * malloc(). */
51
#ifndef CAIRO_STACK_BUFFER_SIZE
52
#define CAIRO_STACK_BUFFER_SIZE (512 * sizeof (int))
53
#endif
54

            
55
#define CAIRO_STACK_ARRAY_LENGTH(T) (CAIRO_STACK_BUFFER_SIZE / sizeof(T))
56

            
57
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
58
#ifdef __MINGW32__
59
#define CAIRO_PRINTF_FORMAT(fmt_index, va_index)                        \
60
	__attribute__((__format__(__MINGW_PRINTF_FORMAT, fmt_index, va_index)))
61
#else
62
#define CAIRO_PRINTF_FORMAT(fmt_index, va_index)                        \
63
	__attribute__((__format__(__printf__, fmt_index, va_index)))
64
#endif
65
#else
66
#define CAIRO_PRINTF_FORMAT(fmt_index, va_index)
67
#endif
68

            
69
#define CAIRO_HAS_HIDDEN_SYMBOLS 1
70
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && \
71
    (defined(__ELF__) || defined(__APPLE__)) &&			\
72
    !defined(__sun)
73
#define cairo_private_no_warn	__attribute__((__visibility__("hidden")))
74
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
75
#define cairo_private_no_warn	__hidden
76
#else /* not gcc >= 3.3 and not Sun Studio >= 8 */
77
#define cairo_private_no_warn
78
#undef CAIRO_HAS_HIDDEN_SYMBOLS
79
#endif
80

            
81
#ifndef WARN_UNUSED_RESULT
82
#define WARN_UNUSED_RESULT
83
#endif
84

            
85
/* Add attribute(warn_unused_result) if supported */
86
#define cairo_warn	    WARN_UNUSED_RESULT
87
#define cairo_private	    cairo_private_no_warn cairo_warn
88

            
89
/* This macro allow us to deprecate a function by providing an alias
90
   for the old function name to the new function name. With this
91
   macro, binary compatibility is preserved. The macro only works on
92
   some platforms --- tough.
93

            
94
   Meanwhile, new definitions in the public header file break the
95
   source code so that it will no longer link against the old
96
   symbols. Instead it will give a descriptive error message
97
   indicating that the old function has been deprecated by the new
98
   function.
99
*/
100
#if __GNUC__ >= 2 && defined(__ELF__)
101
# define CAIRO_FUNCTION_ALIAS(old, new)		\
102
	extern __typeof (new) old		\
103
	__asm__ ("" #old)			\
104
	__attribute__((__alias__("" #new)))
105
#else
106
# define CAIRO_FUNCTION_ALIAS(old, new)
107
#endif
108

            
109
/*
110
 * Cairo uses the following function attributes in order to improve the
111
 * generated code (effectively by manual inter-procedural analysis).
112
 *
113
 *   'cairo_pure': The function is only allowed to read from its arguments
114
 *                 and global memory (i.e. following a pointer argument or
115
 *                 accessing a shared variable). The return value should
116
 *                 only depend on its arguments, and for an identical set of
117
 *                 arguments should return the same value.
118
 *
119
 *   'cairo_const': The function is only allowed to read from its arguments.
120
 *                  It is not allowed to access global memory. The return
121
 *                  value should only depend its arguments, and for an
122
 *                  identical set of arguments should return the same value.
123
 *                  This is currently the most strict function attribute.
124
 *
125
 * Both these function attributes allow gcc to perform CSE and
126
 * constant-folding, with 'cairo_const 'also guaranteeing that pointer contents
127
 * do not change across the function call.
128
 */
129
#if __GNUC__ >= 3
130
#define cairo_pure __attribute__((pure))
131
#define cairo_const __attribute__((const))
132
#define cairo_always_inline inline __attribute__((always_inline))
133
#else
134
#define cairo_pure
135
#define cairo_const
136
#define cairo_always_inline inline
137
#endif
138

            
139
#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
140
#define likely(expr) (__builtin_expect (!!(expr), 1))
141
#define unlikely(expr) (__builtin_expect (!!(expr), 0))
142
#else
143
#define likely(expr) (expr)
144
#define unlikely(expr) (expr)
145
#endif
146

            
147
#ifndef __GNUC__
148
#undef __attribute__
149
#define __attribute__(x)
150
#endif
151

            
152
#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER)
153
#define access _access
154
#ifndef R_OK
155
#define R_OK 4
156
#endif
157
#define fdopen _fdopen
158
#define hypot _hypot
159
#define pclose _pclose
160
#define popen _popen
161
#define strdup _strdup
162
#define unlink _unlink
163
#if _MSC_VER < 1900
164
  #define vsnprintf _vsnprintf
165
  #define snprintf _snprintf
166
#endif
167
#endif
168

            
169
#ifdef _MSC_VER
170
#ifndef __cplusplus
171
#undef inline
172
#define inline __inline
173
#endif
174
#endif
175

            
176
#if defined(_MSC_VER) && defined(_M_IX86)
177
/* When compiling with /Gy and /OPT:ICF identical functions will be folded in together.
178
   The CAIRO_ENSURE_UNIQUE macro ensures that a function is always unique and
179
   will never be folded into another one. Something like this might eventually
180
   be needed for GCC but it seems fine for now. */
181
#define CAIRO_ENSURE_UNIQUE                       \
182
    do {                                          \
183
	char file[] = __FILE__;                   \
184
	__asm {                                   \
185
	    __asm jmp __internal_skip_line_no     \
186
	    __asm _emit (__COUNTER__ & 0xff)      \
187
	    __asm _emit ((__COUNTER__>>8) & 0xff) \
188
	    __asm _emit ((__COUNTER__>>16) & 0xff)\
189
	    __asm _emit ((__COUNTER__>>24) & 0xff)\
190
	    __asm lea eax, dword ptr file         \
191
	    __asm __internal_skip_line_no:        \
192
	};                                        \
193
    } while (0)
194
#else
195
#define CAIRO_ENSURE_UNIQUE    do { } while (0)
196
#endif
197

            
198
#ifdef __STRICT_ANSI__
199
#undef inline
200
#define inline __inline__
201
#endif
202

            
203
/* size_t add/multiply with overflow check.
204
 *
205
 * These _cairo_fallback_*_size_t_overflow() functions are always defined
206
 * to allow them to be tested in the test suite.  They are used
207
 * if no compiler builtin is available.
208
 */
209
static cairo_always_inline cairo_bool_t
210
_cairo_fallback_add_size_t_overflow(size_t a, size_t b, size_t *c)
211
{
212
9
    if (b > SIZE_MAX - a)
213
3
        return 1;
214

            
215
6
    *c = a + b;
216
6
    return 0;
217
}
218

            
219
static cairo_always_inline cairo_bool_t
220
_cairo_fallback_mul_size_t_overflow(size_t a, size_t b, size_t *c)
221
{
222
6
    if (b != 0 && a > SIZE_MAX / b)
223
3
        return 1;
224

            
225
3
    *c = a * b;
226
3
    return 0;
227
}
228

            
229
/* Clang defines __GNUC__ so check clang builtins before gcc.
230
 * MSVC does not support feature macros so hide the __has_builtin inside the #if __clang__ block
231
 */
232
#ifdef __clang__
233
#if defined(__has_builtin) && __has_builtin(__builtin_add_overflow)
234
#define _cairo_add_size_t_overflow(a, b, c)  __builtin_add_overflow((size_t)(a), (size_t)(b), (size_t*)(c))
235
#define _cairo_mul_size_t_overflow(a, b, c)  __builtin_mul_overflow((size_t)(a), (size_t)(b), (size_t*)(c))
236
#endif
237
#elif __GNUC__ >= 8 || (__GNUC__ >= 5 && (INTPTR_MAX == INT64_MAX))
238
/* Overflow builtins are available in gcc 5 but the 32-bit version is broken on gcc < 8.
239
 *   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82274
240
 */
241
#define _cairo_add_size_t_overflow(a, b, c)  __builtin_add_overflow((size_t)(a), (size_t)(b), (size_t*)(c))
242
#define _cairo_mul_size_t_overflow(a, b, c)  __builtin_mul_overflow((size_t)(a), (size_t)(b), (size_t*)(c))
243
#elif defined(_MSC_VER) && defined(HAVE_INTSAFE_H)
244
#include <intsafe.h>
245
#define _cairo_add_size_t_overflow(a,b,c) (SizeTAdd((size_t)(a), (size_t)(b), (size_t*)(c)) != S_OK)
246
#define _cairo_mul_size_t_overflow(a,b,c) (SizeTMult((size_t)(a), (size_t)(b), (size_t*)(c)) != S_OK)
247
#endif
248

            
249
#ifndef _cairo_add_size_t_overflow
250
#define _cairo_add_size_t_overflow _cairo_fallback_add_size_t_overflow
251
#define _cairo_mul_size_t_overflow _cairo_fallback_mul_size_t_overflow
252
#endif
253

            
254
#endif