summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiarhei Siamashka <siarhei.siamashka@gmail.com>2012-12-16 04:19:47 +0200
committerSiarhei Siamashka <siarhei.siamashka@gmail.com>2012-12-20 04:01:44 +0200
commit1d3075734798c845df386016f134cb8b60731925 (patch)
tree45377a5328998047acc003875f7a08b40b53f2d2
parent5a7cafaf54225b0adaf17467b4dd42b9ece9a93d (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.h79
-rw-r--r--pixman/pixman-utils.c23
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)
{