From 1d3075734798c845df386016f134cb8b60731925 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Sun, 16 Dec 2012 04:19:47 +0200 Subject: 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. --- pixman/pixman-private.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++--- 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 #include #include +#include #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 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) { -- cgit v1.2.3