diff options
author | Siarhei Siamashka <siarhei.siamashka@gmail.com> | 2012-12-16 04:19:47 +0200 |
---|---|---|
committer | Siarhei Siamashka <siarhei.siamashka@gmail.com> | 2012-12-20 04:01:44 +0200 |
commit | 1d3075734798c845df386016f134cb8b60731925 (patch) | |
tree | 45377a5328998047acc003875f7a08b40b53f2d2 | |
parent | 5a7cafaf54225b0adaf17467b4dd42b9ece9a93d (diff) |
Fix "malloc/calloc return values need explicit casts" C++ errors
There are a number of places in pixman code which are using
functions malloc/calloc/pixman_malloc_ab/pixman_malloc_abc:
pixman-access.c: argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t));
pixman-bits-image.c: if ((alpha = malloc (width * sizeof (uint32_t))))
pixman-bits-image.c: if ((alpha = malloc (width * sizeof (argb_t))))
pixman-bits-image.c: return malloc (buf_size);
pixman.c: boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
pixman-filter.c: p = params = malloc (*width * n_phases * sizeof (pixman_fixed_t));
pixman-filter.c: params = malloc (*n_values * sizeof (pixman_fixed_t));
pixman-general.c: scanline_buffer = pixman_malloc_abc (width, 3, Bpp);
pixman-glyph.c: if (!(cache = malloc (sizeof *cache)))
pixman-glyph.c: if (!(glyph = malloc (sizeof *glyph)))
pixman-image.c: pixman_malloc_ab (n_stops + 2, sizeof (pixman_gradient_stop_t));
pixman-image.c: pixman_image_t *image = malloc (sizeof (pixman_image_t));
pixman-image.c: common->transform = malloc (sizeof (pixman_transform_t));
pixman-image.c: new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
pixman-implementation.c: if ((imp = malloc (sizeof (pixman_implementation_t))))
pixman-region.c: return malloc (sz);
pixman-region.c: rit = malloc (data_size);
pixman-trap.c: traps = pixman_malloc_ab (n_tris, 2 * sizeof (pixman_trapezoid_t));
pixman-utils.c: return malloc (a * b);
pixman-utils.c: return malloc (a * b * c);
pixman-utils.c: boxes16 = pixman_malloc_ab (n_boxes, sizeof (pixman_box16_t));
pixman-utils.c: boxes32 = pixman_malloc_ab (n_boxes, sizeof (pixman_box32_t));
pixman-bits-image.c: return calloc (buf_size, 1);
pixman-compiler.h: type *value = calloc (1, sizeof (type));
pixman-compiler.h: type *value = calloc (1, sizeof (type));
Unfortunately they fail to compile in C++ mode because the compiler wants
explicit type casts for the returned pointers:
http://stackoverflow.com/questions/3477741/why-does-c-require-a-cast-for-malloc-but-c-doesnt
This patch tries to solve the problem in a less invasive way by
adding some compatibility wrappers which allow compiling such
C code without modifications.
-rw-r--r-- | pixman/pixman-private.h | 79 | ||||
-rw-r--r-- | pixman/pixman-utils.c | 23 |
2 files changed, 75 insertions, 27 deletions
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 04b94fb..bf16461 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -28,6 +28,7 @@ #include <stdio.h> #include <string.h> #include <stddef.h> +#include <stdlib.h> #include "pixman-compiler.h" @@ -773,11 +774,29 @@ PIXMAN_EXPORT pixman_implementation_t * _pixman_internal_only_get_implementation (void); /* Memory allocation helpers */ -void * -pixman_malloc_ab (unsigned int n, unsigned int b); -void * -pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c); +static inline void * +pixman_malloc_ab (unsigned int a, + unsigned int b) +{ + if (a >= INT32_MAX / b) + return NULL; + + return malloc (a * b); +} + +static inline void * +pixman_malloc_abc (unsigned int a, + unsigned int b, + unsigned int c) +{ + if (a >= INT32_MAX / b) + return NULL; + else if (a * b >= INT32_MAX / c) + return NULL; + else + return malloc (a * b * c); +} pixman_bool_t _pixman_multiply_overflows_size (size_t a, size_t b); @@ -1160,6 +1179,58 @@ void pixman_timer_register (pixman_timer_t *timer); #endif /* PIXMAN_TIMERS */ +/* + * C++ compatibility wrappers, which simulate implicit cast from void* to + * any pointer for the return value from malloc(), calloc() and friends. + */ + +#ifdef __cplusplus + +class pixman_implicitly_castable_pointer +{ + void *data; +public: + pixman_implicitly_castable_pointer (void *p) : data(p) { } + template<typename T> operator T * () const { return (T *)data; } +}; + +static inline pixman_implicitly_castable_pointer +pixman_malloc (size_t size) +{ + return pixman_implicitly_castable_pointer (malloc (size)); +} + +static inline pixman_implicitly_castable_pointer +pixman_calloc (size_t n, size_t size) +{ + return pixman_implicitly_castable_pointer (calloc (n, size)); +} + +static inline pixman_implicitly_castable_pointer +pixman_malloc_ab_wrapper (unsigned int a, unsigned int b) +{ + return pixman_implicitly_castable_pointer (pixman_malloc_ab (a, b)); +} + +static inline pixman_implicitly_castable_pointer +pixman_malloc_abc_wrapper (unsigned int a, unsigned int b, unsigned int c) +{ + return pixman_implicitly_castable_pointer (pixman_malloc_abc (a, b, c)); +} + +/* + * This is a hack to override malloc/calloc functions using defines. Because + * we have already included stdlib.h here, there should be no risk for these + * macros to conflict with the standard headers (as long as stdlib.h has proper + * safeguards against double inclusion). + */ +#define malloc(a) pixman_malloc(a) +#define calloc(a, b) pixman_calloc((a), (b)) +#define pixman_malloc_ab(a, b) pixman_malloc_ab_wrapper((a), (b)) +#define pixman_malloc_abc(a, b, c) pixman_malloc_abc_wrapper((a), (b), (c)) + +#endif + #endif /* __ASSEMBLER__ */ #endif /* PIXMAN_PRIVATE_H */ diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c index b1e9fb6..9ed9697 100644 --- a/pixman/pixman-utils.c +++ b/pixman/pixman-utils.c @@ -48,29 +48,6 @@ _pixman_addition_overflows_int (unsigned int a, unsigned int b) return a > INT32_MAX - b; } -void * -pixman_malloc_ab (unsigned int a, - unsigned int b) -{ - if (a >= INT32_MAX / b) - return NULL; - - return malloc (a * b); -} - -void * -pixman_malloc_abc (unsigned int a, - unsigned int b, - unsigned int c) -{ - if (a >= INT32_MAX / b) - return NULL; - else if (a * b >= INT32_MAX / c) - return NULL; - else - return malloc (a * b * c); -} - static force_inline uint16_t float_to_unorm (float f, int n_bits) { |