[Pixman] [PATCH 3/4] Fix "malloc/calloc return values need explicit casts" C++ errors
Siarhei Siamashka
siarhei.siamashka at gmail.com
Sat Dec 15 21:13:49 PST 2012
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 416d2a1..38e8b6c 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);
@@ -1110,6 +1129,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)
{
--
1.7.8.6
More information about the Pixman
mailing list