[cairo] Add attribute(warn_unused_result)

Chris Wilson chris at chris-wilson.co.uk
Tue Mar 27 14:18:25 PDT 2007


Behdad Esfahbod (behdad at behdad.org) said: 
> The only part I really displike is the "cairo_private_no_warn void".
> While cairo_private_no_warn is useful for other places too, can we have
> a cairo_private_void instead?

Fortunately for readability I found the -Wno-attributes flag.
Attached are the changes for the headers and the most trivial cleanups.
The plan is to attack the rest as a series of independent patches -
however any that are not blindingly obvious I'll defer to the intrepid
reader.

I'll leave introducing cairo_static prototypes for a future janitorial
crusade.
--
Chris Wilson
-------------- next part --------------
>From b2da8b40e9cfa16f156b5a482bcadfbf75d885f5 Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue, 27 Mar 2007 19:15:42 +0100
Subject: [PATCH] Add attribute(warn_unused_result)

This adds a compiler check that the function result is used by the caller
and enables it by default for all cairo_private functions and for public
API that returns a cairo_status_t.

To extend the warnings to all functions, a new function type has been
introduced to cover static functions: cairo_static. The preference is
for all static code to be forward declared with a cairo_static prototype.

In order to reduce the warning spew generated by gcc for invalid use of
this attribute, -Wno-attributes is added to CFLAGS. This has the
unfortunate side-effect of masking future warnings for all attributes -
be warned!
---
 configure.in           |   13 ++++++++++++-
 pixman/configure.in    |    3 ++-
 pixman/src/Makefile.am |    1 +
 pixman/src/pixman.h    |    2 +-
 src/cairo.h            |   40 ++++++++++++++++++++--------------------
 src/cairoint.h         |   11 ++++++++---
 src/check-headers.sh   |    2 +-
 7 files changed, 45 insertions(+), 27 deletions(-)

diff --git a/configure.in b/configure.in
index 8acca66..e885b5c 100644
--- a/configure.in
+++ b/configure.in
@@ -621,7 +621,8 @@ MAYBE_WARN="-Wall -Wextra \
 -Wpacked -Wswitch-enum -Wmissing-format-attribute \
 -Wstrict-aliasing=2 -Winit-self -Wunsafe-loop-optimizations \
 -Wdeclaration-after-statement -Wold-style-definition \
--Wno-missing-field-initializers -Wno-unused-parameter"
+-Wno-missing-field-initializers -Wno-unused-parameter \
+-Wno-attributes"
 
 
 # invalidate cached value if MAYBE_WARN has changed
@@ -834,9 +835,19 @@ AC_CONFIG_COMMANDS([src/cairo-features.h],
 # define CAIRO_END_DECLS
 #endif
 
+#if    __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define CAIRO_WARN_UNUSED_RESULT 		\
+  __attribute__((__warn_unused_result__))
+#else
+#define CAIRO_WARN_UNUSED_RESULT
+#endif /* __GNUC__ */
+
 #ifndef cairo_public
 # define cairo_public
 #endif
+#ifndef cairo_public_warn
+# define cairo_public_warn CAIRO_WARN_UNUSED_RESULT
+#endif
 
 #define CAIRO_VERSION_MAJOR $CAIRO_VERSION_MAJOR
 #define CAIRO_VERSION_MINOR $CAIRO_VERSION_MINOR
diff --git a/pixman/configure.in b/pixman/configure.in
index c9cdae8..4cbb5ba 100644
--- a/pixman/configure.in
+++ b/pixman/configure.in
@@ -45,7 +45,8 @@ WARN_CFLAGS=""
 if test "x$GCC" = "xyes"; then
 	WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \
 	-Wmissing-prototypes -Wmissing-declarations \
-	-Wnested-externs -fno-strict-aliasing"
+	-Wnested-externs -fno-strict-aliasing \
+	-Wno-attributes"
 fi
 
 AC_SUBST(WARN_CFLAGS)
diff --git a/pixman/src/Makefile.am b/pixman/src/Makefile.am
index 7b828f5..f1808e3 100644
--- a/pixman/src/Makefile.am
+++ b/pixman/src/Makefile.am
@@ -29,6 +29,7 @@ libpixman_la_SOURCES = \
 	fbcompose.c \
 	renderedge.c \
 	renderedge.h
+libpixman_la_CFLAGS = $(PIXMAN_CFLAGS)
 
 if USE_MMX
 noinst_LTLIBRARIES += libpixman-mmx.la
diff --git a/pixman/src/pixman.h b/pixman/src/pixman.h
index 9120eb6..acf5327 100644
--- a/pixman/src/pixman.h
+++ b/pixman/src/pixman.h
@@ -100,7 +100,7 @@ SOFTWARE.
 #include "pixman-remap.h"
 
 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun__)
-#define pixman_private		__attribute__((__visibility__("hidden")))
+#define pixman_private		__attribute__((__visibility__("hidden"),__warn_unused_result__))
 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
 #define pixman_private		__hidden
 #else /* not gcc >= 3.3 and not Sun Studio >= 8 */
diff --git a/src/cairo.h b/src/cairo.h
index a80efde..5fc05e3 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -313,7 +313,7 @@ cairo_public void *
 cairo_get_user_data (cairo_t			 *cr,
 		     const cairo_user_data_key_t *key);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_set_user_data (cairo_t			 *cr,
 		     const cairo_user_data_key_t *key,
 		     void			 *user_data,
@@ -972,7 +972,7 @@ cairo_font_options_copy (const cairo_font_options_t *original);
 cairo_public void
 cairo_font_options_destroy (cairo_font_options_t *options);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_font_options_status (cairo_font_options_t *options);
 
 cairo_public void
@@ -1088,7 +1088,7 @@ cairo_font_face_destroy (cairo_font_face_t *font_face);
 cairo_public unsigned int
 cairo_font_face_get_reference_count (cairo_font_face_t *font_face);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_font_face_status (cairo_font_face_t *font_face);
 
 /**
@@ -1141,7 +1141,7 @@ cairo_public void *
 cairo_font_face_get_user_data (cairo_font_face_t	   *font_face,
 			       const cairo_user_data_key_t *key);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_font_face_set_user_data (cairo_font_face_t	   *font_face,
 			       const cairo_user_data_key_t *key,
 			       void			   *user_data,
@@ -1164,7 +1164,7 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font);
 cairo_public unsigned int
 cairo_scaled_font_get_reference_count (cairo_scaled_font_t *scaled_font);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_scaled_font_status (cairo_scaled_font_t *scaled_font);
 
 cairo_public cairo_font_type_t
@@ -1174,7 +1174,7 @@ cairo_public void *
 cairo_scaled_font_get_user_data (cairo_scaled_font_t         *scaled_font,
 				 const cairo_user_data_key_t *key);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_scaled_font_set_user_data (cairo_scaled_font_t         *scaled_font,
 				 const cairo_user_data_key_t *key,
 				 void                        *user_data,
@@ -1392,7 +1392,7 @@ cairo_path_destroy (cairo_path_t *path);
 
 /* Error status queries */
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_status (cairo_t *cr);
 
 cairo_public const char *
@@ -1418,7 +1418,7 @@ cairo_surface_destroy (cairo_surface_t *surface);
 cairo_public unsigned int
 cairo_surface_get_reference_count (cairo_surface_t *surface);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_surface_status (cairo_surface_t *surface);
 
 /**
@@ -1482,11 +1482,11 @@ cairo_surface_get_content (cairo_surface_t *surface);
 
 #if CAIRO_HAS_PNG_FUNCTIONS
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_surface_write_to_png (cairo_surface_t	*surface,
 			    const char		*filename);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_surface_write_to_png_stream (cairo_surface_t	*surface,
 				   cairo_write_func_t	write_func,
 				   void			*closure);
@@ -1497,7 +1497,7 @@ cairo_public void *
 cairo_surface_get_user_data (cairo_surface_t		 *surface,
 			     const cairo_user_data_key_t *key);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_surface_set_user_data (cairo_surface_t		 *surface,
 			     const cairo_user_data_key_t *key,
 			     void			 *user_data,
@@ -1642,14 +1642,14 @@ cairo_pattern_destroy (cairo_pattern_t *pattern);
 cairo_public unsigned int
 cairo_pattern_get_reference_count (cairo_pattern_t *pattern);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_status (cairo_pattern_t *pattern);
 
 cairo_public void *
 cairo_pattern_get_user_data (cairo_pattern_t		 *pattern,
 			     const cairo_user_data_key_t *key);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_set_user_data (cairo_pattern_t		 *pattern,
 			     const cairo_user_data_key_t *key,
 			     void			 *user_data,
@@ -1758,32 +1758,32 @@ cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter);
 cairo_public cairo_filter_t
 cairo_pattern_get_filter (cairo_pattern_t *pattern);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_get_rgba (cairo_pattern_t *pattern,
 			double *red, double *green,
 			double *blue, double *alpha);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_get_surface (cairo_pattern_t *pattern,
 			   cairo_surface_t **surface);
 
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_get_color_stop_rgba (cairo_pattern_t *pattern,
 				   int index, double *offset,
 				   double *red, double *green,
 				   double *blue, double *alpha);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_get_color_stop_count (cairo_pattern_t *pattern,
 				    int *count);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_get_linear_points (cairo_pattern_t *pattern,
 				 double *x0, double *y0,
 				 double *x1, double *y1);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_get_radial_circles (cairo_pattern_t *pattern,
 				  double *x0, double *y0, double *r0,
 				  double *x1, double *y1, double *r1);
@@ -1820,7 +1820,7 @@ cairo_matrix_scale (cairo_matrix_t *matrix, double sx, double sy);
 cairo_public void
 cairo_matrix_rotate (cairo_matrix_t *matrix, double radians);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_matrix_invert (cairo_matrix_t *matrix);
 
 cairo_public void
diff --git a/src/cairoint.h b/src/cairoint.h
index 1d2c3c7..ed685e6 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -103,13 +103,18 @@ CAIRO_BEGIN_DECLS
 
 /* slim_internal.h */
 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun)
-#define cairo_private		__attribute__((__visibility__("hidden")))
+#define cairo_private			__attribute__((__visibility__("hidden"),__warn_unused_result__))
 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
-#define cairo_private		__hidden
+#define cairo_private			__hidden CAIRO_WARN_UNUSED_RESULT
 #else /* not gcc >= 3.3 and not Sun Studio >= 8 */
-#define cairo_private
+#define cairo_private			CAIRO_WARN_UNUSED_RESULT
 #endif
 
+/* This allows us to conditionally expose internals during debugging,
+   and forces propagation of return values.
+*/
+#define cairo_static static CAIRO_WARN_UNUSED_RESULT
+
 /* This macro allow us to deprecate a function by providing an alias
    for the old function name to the new function name. With this
    macro, binary compatibility is preserved. The macro only works on
diff --git a/src/check-headers.sh b/src/check-headers.sh
index 1d0ebf8..2ac74fd 100755
--- a/src/check-headers.sh
+++ b/src/check-headers.sh
@@ -12,7 +12,7 @@ xargs grep -B 1 '^cairo_.*[ 	]\+(' |
 awk '
 /^--$/ { context=""; public=0; next; }
 /:cairo_.*[ 	]+\(/ { if (!public) {print context; print; print "--";} next; }
-/-cairo_public[ 	]/ {public=1;}
+/-cairo_public.*[ 	]/ {public=1;}
 { context=$0; }
 ' |
 sed 's/[.]h-/.h:/' |
-- 
1.4.4.2

-------------- next part --------------
>From cfc8b86edd0660a5bcbf8b6b5c977287bc173f47 Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue, 27 Mar 2007 21:52:37 +0100
Subject: [PATCH] Fix up the trivial warnings from warn-unused-result.

For the majority of cases of unchecked status returns the most appropiate
action is to simply propagate the status back up the chain, after
performing all apropiate cleanups.
---
 boilerplate/cairo-boilerplate.c |   10 ++++-
 src/cairo-clip.c                |   19 ++++++---
 src/cairo-ft-font.c             |   82 +++++++++++++++++++++++++-------------
 src/cairo-gstate.c              |   17 ++++++--
 src/cairo-image-surface.c       |    6 ++-
 src/cairo-meta-surface.c        |    4 +-
 src/cairo-paginated-surface.c   |   22 ++++++++---
 src/cairo-path-fill.c           |    2 +-
 src/cairo-path-stroke.c         |   54 +++++++++++++++++++------
 src/cairo-path.c                |   38 +++++++++--------
 src/cairo-pattern.c             |   10 ++++-
 src/cairo-pdf-surface.c         |   25 ++++++------
 src/cairo-pen.c                 |   24 ++++++++---
 src/cairo-polygon.c             |    8 +--
 src/cairo-ps-surface.c          |   54 +++++++++++++++-----------
 src/cairo-scaled-font.c         |   43 +++++++++++++-------
 src/cairo-surface-fallback.c    |   44 ++++++++++++--------
 src/cairo-svg-surface.c         |   34 +++++++++++-----
 src/cairo-type1-fallback.c      |    7 ++-
 src/cairo.c                     |   74 +++++++++++++++++++++++------------
 test/buffer-diff.c              |    5 +-
 21 files changed, 378 insertions(+), 204 deletions(-)

diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index f726d42..858c5c0 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -1095,7 +1095,15 @@ create_ps_surface (const char			 *name,
 	ptc->target = NULL;
     }
 
-    cairo_surface_set_user_data (surface, &ps_closure_key, ptc, NULL);
+    if (cairo_surface_set_user_data (surface,
+	       	                     &ps_closure_key,
+				     ptc,
+				     NULL) != CAIRO_STATUS_SUCCESS) {
+	cairo_surface_destroy (surface);
+	free (ptc->filename);
+	free (ptc);
+	return NULL;
+    }
 
     return surface;
 }
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index efecd89..0ab036b 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -203,6 +203,8 @@ cairo_status_t
 _cairo_clip_intersect_to_region (cairo_clip_t      *clip,
 				 pixman_region16_t *region)
 {
+    pixman_region_status_t pixman_status;
+
     if (!clip)
 	return CAIRO_STATUS_SUCCESS;
 
@@ -210,12 +212,14 @@ _cairo_clip_intersect_to_region (cairo_clip_t      *clip,
 	/* Intersect clip path into region. */
     }
 
-    if (clip->region)
-	pixman_region_intersect (region, clip->region, region);
+    if (clip->region) {
+	pixman_status = pixman_region_intersect (region, clip->region, region);
+	if (pixman_status != PIXMAN_REGION_STATUS_SUCCESS)
+	    return CAIRO_STATUS_NO_MEMORY;
+    }
 
     if (clip->surface) {
 	pixman_region16_t *clip_rect;
-	pixman_region_status_t pixman_status;
 	cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
 	clip_rect = _cairo_region_create_from_rectangle (&clip->surface_rect);
@@ -635,10 +639,11 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
         }
     } else {
         cairo_rectangle_int16_t extents;
-        _cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents);
-        if (!_cairo_clip_rect_to_user(gstate, extents.x, extents.y,
-                                      extents.width, extents.height,
-                                      rectangles)) {
+        if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
+		                        &extents) != CAIRO_STATUS_SUCCESS ||
+		!_cairo_clip_rect_to_user(gstate, extents.x, extents.y,
+                                          extents.width, extents.height,
+                                          rectangles)) {
             free (rectangles);
             return (cairo_rectangle_list_t*)
                 &_cairo_rectangles_not_representable;
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 7f10fd7..73a40f8 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1154,24 +1154,33 @@ _transform_glyph_bitmap (cairo_matrix_t         * shape,
 
     /* Initialize it to empty
      */
-    _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,
-				   CAIRO_COLOR_TRANSPARENT,
-				   0, 0,
-				   width, height);
+    status = _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,
+				            CAIRO_COLOR_TRANSPARENT,
+					    0, 0,
+					    width, height);
+    if (status) {
+	cairo_surface_destroy (image);
+	return status;
+    }
 
     /* Draw the original bitmap transformed into the new bitmap
      */
     _cairo_pattern_init_for_surface (&pattern, &(*surface)->base);
     cairo_pattern_set_matrix (&pattern.base, &transformed_to_original);
 
-    _cairo_surface_composite (CAIRO_OPERATOR_OVER,
-			      &pattern.base, NULL, image,
-			      0, 0, 0, 0, 0, 0,
-			      width,
-			      height);
+    status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
+			               &pattern.base, NULL, image,
+				       0, 0, 0, 0, 0, 0,
+				       width,
+				       height);
 
     _cairo_pattern_fini (&pattern.base);
 
+    if (status) {
+	cairo_surface_destroy (image);
+	return status;
+    }
+
     /* Now update the cache entry for the new bitmap, recomputing
      * the origin based on the final transform.
      */
@@ -1421,6 +1430,7 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t	 *unscaled,
     FT_Face face;
     FT_Size_Metrics *metrics;
     cairo_font_extents_t fs_metrics;
+    cairo_status_t status;
 
     face = _cairo_ft_unscaled_font_lock_face (unscaled);
     if (!face)
@@ -1441,10 +1451,15 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t	 *unscaled,
     _cairo_font_options_init_copy (&scaled_font->ft_options.base, options);
     _cairo_ft_options_merge (&scaled_font->ft_options, &ft_options);
 
-    _cairo_scaled_font_init (&scaled_font->base,
-			     font_face,
-			     font_matrix, ctm, options,
-			     &cairo_ft_scaled_font_backend);
+    status = _cairo_scaled_font_init (&scaled_font->base,
+			              font_face,
+				      font_matrix, ctm, options,
+				      &cairo_ft_scaled_font_backend);
+    if (status) {
+	free (scaled_font);
+	_cairo_ft_unscaled_font_unlock_face (unscaled);
+	return NULL;
+    }
 
     _cairo_ft_unscaled_font_set_scale (unscaled,
 				       &scaled_font->base.scale);
@@ -1620,8 +1635,10 @@ _move_to (FT_Vector *to, void *closure)
     x = _cairo_fixed_from_26_6 (to->x);
     y = _cairo_fixed_from_26_6 (to->y);
 
-    _cairo_path_fixed_close_path (path);
-    _cairo_path_fixed_move_to (path, x, y);
+    if (_cairo_path_fixed_close_path (path) != CAIRO_STATUS_SUCCESS)
+	return 1;
+    if (_cairo_path_fixed_move_to (path, x, y) != CAIRO_STATUS_SUCCESS)
+	return 1;
 
     return 0;
 }
@@ -1635,7 +1652,8 @@ _line_to (FT_Vector *to, void *closure)
     x = _cairo_fixed_from_26_6 (to->x);
     y = _cairo_fixed_from_26_6 (to->y);
 
-    _cairo_path_fixed_line_to (path, x, y);
+    if (_cairo_path_fixed_line_to (path, x, y) != CAIRO_STATUS_SUCCESS)
+	return 1;
 
     return 0;
 }
@@ -1651,7 +1669,9 @@ _conic_to (FT_Vector *control, FT_Vector *to, void *closure)
     cairo_fixed_t x3, y3;
     cairo_point_t conic;
 
-    _cairo_path_fixed_get_current_point (path, &x0, &y0);
+    if (_cairo_path_fixed_get_current_point (path, &x0, &y0) !=
+	    CAIRO_STATUS_SUCCESS)
+	return 1;
 
     conic.x = _cairo_fixed_from_26_6 (control->x);
     conic.y = _cairo_fixed_from_26_6 (control->y);
@@ -1665,10 +1685,11 @@ _conic_to (FT_Vector *control, FT_Vector *to, void *closure)
     x2 = x3 + 2.0/3.0 * (conic.x - x3);
     y2 = y3 + 2.0/3.0 * (conic.y - y3);
 
-    _cairo_path_fixed_curve_to (path,
-				x1, y1,
-				x2, y2,
-				x3, y3);
+    if (_cairo_path_fixed_curve_to (path,
+				    x1, y1,
+				    x2, y2,
+				    x3, y3) != CAIRO_STATUS_SUCCESS)
+	return 1;
 
     return 0;
 }
@@ -1691,10 +1712,11 @@ _cubic_to (FT_Vector *control1, FT_Vector *control2,
     x2 = _cairo_fixed_from_26_6 (to->x);
     y2 = _cairo_fixed_from_26_6 (to->y);
 
-    _cairo_path_fixed_curve_to (path,
-				x0, y0,
-				x1, y1,
-				x2, y2);
+    if (_cairo_path_fixed_curve_to (path,
+				    x0, y0,
+				    x1, y1,
+				    x2, y2) != CAIRO_STATUS_SUCCESS)
+	return 1;
 
     return 0;
 }
@@ -1719,6 +1741,7 @@ _decompose_glyph_outline (FT_Face		  face,
 
     FT_GlyphSlot glyph;
     cairo_path_fixed_t *path;
+    cairo_status_t status;
 
     path = _cairo_path_fixed_create ();
     if (!path)
@@ -1726,15 +1749,18 @@ _decompose_glyph_outline (FT_Face		  face,
 
     glyph = face->glyph;
 
+    status = CAIRO_STATUS_SUCCESS;
     /* Font glyphs have an inverted Y axis compared to cairo. */
     FT_Outline_Transform (&glyph->outline, &invert_y);
-    FT_Outline_Decompose (&glyph->outline, &outline_funcs, path);
+    if (FT_Outline_Decompose (&glyph->outline, &outline_funcs, path))
+	status = CAIRO_STATUS_NO_MEMORY;
 
     _cairo_path_fixed_close_path (path);
 
-    *pathp = path;
+    if (status == CAIRO_STATUS_SUCCESS)
+	*pathp = path;
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 /*
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 377871e..5647f9c 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -64,6 +64,7 @@ cairo_status_t
 _cairo_gstate_init (cairo_gstate_t  *gstate,
 		    cairo_surface_t *target)
 {
+    cairo_status_t status;
     gstate->next = NULL;
 
     gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT;
@@ -90,7 +91,9 @@ _cairo_gstate_init (cairo_gstate_t  *gstate,
     gstate->parent_target = NULL;
     gstate->original_target = cairo_surface_reference (target);
 
-    _cairo_gstate_identity_matrix (gstate);
+    status = _cairo_gstate_identity_matrix (gstate);
+    if (status)
+	return status;
     gstate->source_ctm_inverse = gstate->ctm_inverse;
 
     gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK);
@@ -405,7 +408,7 @@ _cairo_gstate_set_source (cairo_gstate_t  *gstate,
     if (source->status)
 	return source->status;
 
-    cairo_pattern_reference (source);
+    source = cairo_pattern_reference (source);
     cairo_pattern_destroy (gstate->source);
     gstate->source = source;
     gstate->source_ctm_inverse = gstate->ctm_inverse;
@@ -650,13 +653,16 @@ _cairo_gstate_transform (cairo_gstate_t	      *gstate,
 			 const cairo_matrix_t *matrix)
 {
     cairo_matrix_t tmp;
+    cairo_status_t status;
 
     _cairo_gstate_unset_scaled_font (gstate);
 
     tmp = *matrix;
     cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
 
-    cairo_matrix_invert (&tmp);
+    status = cairo_matrix_invert (&tmp);
+    if (status)
+	return status;
     cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp);
 
     return CAIRO_STATUS_SUCCESS;
@@ -1257,12 +1263,15 @@ _cairo_gstate_select_font_face (cairo_gstate_t       *gstate,
 				cairo_font_weight_t   weight)
 {
     cairo_font_face_t *font_face;
+    cairo_status_t status;
 
     font_face = _cairo_toy_font_face_create (family, slant, weight);
     if (font_face->status)
 	return font_face->status;
 
-    _cairo_gstate_set_font_face (gstate, font_face);
+    status = _cairo_gstate_set_font_face (gstate, font_face);
+    if (status)
+	return status;
     cairo_font_face_destroy (font_face);
 
     return CAIRO_STATUS_SUCCESS;
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 6279012..3062533 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -690,7 +690,8 @@ _cairo_image_surface_set_matrix (cairo_image_surface_t	*surface,
 
     _cairo_matrix_to_pixman_matrix (matrix, &pixman_transform);
 
-    pixman_image_set_transform (surface->pixman_image, &pixman_transform);
+    if (pixman_image_set_transform (surface->pixman_image, &pixman_transform))
+	return CAIRO_STATUS_NO_MEMORY;
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1047,7 +1048,8 @@ _cairo_image_surface_set_clip_region (void *abstract_surface,
 {
     cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
 
-    pixman_image_set_clip_region (surface->pixman_image, region);
+    if (pixman_image_set_clip_region (surface->pixman_image, region))
+	return CAIRO_STATUS_NO_MEMORY;
 
     surface->has_clip = region != NULL;
 
diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index e196df2..7bbdc39 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -668,7 +668,9 @@ _cairo_meta_surface_replay (cairo_surface_t *surface,
 
 	dev_path = _cairo_command_get_path (command);
 	if (dev_path && has_device_transform) {
-	    _cairo_path_fixed_init_copy (&path_copy, dev_path);
+	    status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
+	    if (status)
+		break;
 	    _cairo_path_fixed_device_transform (&path_copy, device_transform);
 	    dev_path = &path_copy;
 	}
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index c8e4612..e6702b7 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -201,15 +201,22 @@ _cairo_paginated_surface_acquire_source_image (void	       *abstract_surface,
 {
     cairo_paginated_surface_t *surface = abstract_surface;
     cairo_surface_t *image;
+    cairo_status_t status;
     cairo_rectangle_int16_t extents;
 
-    _cairo_surface_get_extents (surface->target, &extents);
+    status = _cairo_surface_get_extents (surface->target, &extents);
+    if (status)
+	return status;
 
     image = _cairo_paginated_surface_create_image_surface (surface,
 							   extents.width,
 							   extents.height);
 
-    _cairo_meta_surface_replay (surface->meta, image);
+    status = _cairo_meta_surface_replay (surface->meta, image);
+    if (status) {
+	cairo_surface_destroy (image);
+	return status;
+    }
 
     *image_out = (cairo_image_surface_t*) image;
     *image_extra = NULL;
@@ -257,26 +264,29 @@ _paint_page (cairo_paginated_surface_t *surface)
 							       surface->height * y_scale);
 	_cairo_surface_set_device_scale (image, x_scale, y_scale);
 
-	_cairo_meta_surface_replay (surface->meta, image);
+	status = _cairo_meta_surface_replay (surface->meta, image);
+	if (status)
+	    goto CLEANUP_IMAGE;
 
 	pattern = cairo_pattern_create_for_surface (image);
 	cairo_matrix_init_scale (&matrix, x_scale, y_scale);
 	cairo_pattern_set_matrix (pattern, &matrix);
 
-	_cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern);
+	status = _cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern);
 
 	cairo_pattern_destroy (pattern);
 
+CLEANUP_IMAGE:
 	cairo_surface_destroy (image);
     }
     else
     {
-	_cairo_meta_surface_replay (surface->meta, surface->target);
+	status = _cairo_meta_surface_replay (surface->meta, surface->target);
     }
 
     cairo_surface_destroy (analysis);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 static cairo_status_t
diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c
index b1b7a12..d2a9118 100644
--- a/src/cairo-path-fill.c
+++ b/src/cairo-path-fill.c
@@ -138,7 +138,7 @@ _cairo_filler_curve_to (void *closure,
     if (status == CAIRO_INT_STATUS_DEGENERATE)
 	return CAIRO_STATUS_SUCCESS;
 
-    _cairo_spline_decompose (&spline, filler->tolerance);
+    status = _cairo_spline_decompose (&spline, filler->tolerance);
     if (status)
 	goto CLEANUP_SPLINE;
 
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index 09bafbf..3aeb41f 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -205,6 +205,7 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
 {
     int			clockwise = _cairo_stroker_face_clockwise (out, in);
     cairo_point_t	*inpt, *outpt;
+    cairo_status_t status;
 
     if (in->cw.x == out->cw.x
 	&& in->cw.y == out->cw.y
@@ -231,13 +232,21 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
 
 	tri[0] = in->point;
 	if (clockwise) {
-	    _cairo_pen_find_active_ccw_vertex_index (pen, &in->dev_vector, &start);
+	    status = _cairo_pen_find_active_ccw_vertex_index (pen, &in->dev_vector, &start);
+	    if (status)
+		return status;
 	    step = -1;
-	    _cairo_pen_find_active_ccw_vertex_index (pen, &out->dev_vector, &stop);
+	    status = _cairo_pen_find_active_ccw_vertex_index (pen, &out->dev_vector, &stop);
+	    if (status)
+		return status;
 	} else {
-	    _cairo_pen_find_active_cw_vertex_index (pen, &in->dev_vector, &start);
+	    status = _cairo_pen_find_active_cw_vertex_index (pen, &in->dev_vector, &start);
+	    if (status)
+		return status;
 	    step = +1;
-	    _cairo_pen_find_active_cw_vertex_index (pen, &out->dev_vector, &stop);
+	    status = _cairo_pen_find_active_cw_vertex_index (pen, &out->dev_vector, &stop);
+	    if (status)
+		return status;
 	}
 
 	i = start;
@@ -245,7 +254,9 @@ _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_st
 	while (i != stop) {
 	    tri[2] = in->point;
 	    _translate_point (&tri[2], &pen->vertices[i].point);
-	    _cairo_traps_tessellate_triangle (stroker->traps, tri);
+	    status = _cairo_traps_tessellate_triangle (stroker->traps, tri);
+	    if (status)
+		return status;
 	    tri[1] = tri[2];
 	    i += step;
 	    if (i < 0)
@@ -378,17 +389,23 @@ _cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
 	cairo_pen_t *pen = &stroker->pen;
 
 	slope = f->dev_vector;
-	_cairo_pen_find_active_cw_vertex_index (pen, &slope, &start);
+	status = _cairo_pen_find_active_cw_vertex_index (pen, &slope, &start);
+	if (status)
+	    return status;
 	slope.dx = -slope.dx;
 	slope.dy = -slope.dy;
-	_cairo_pen_find_active_cw_vertex_index (pen, &slope, &stop);
+	status = _cairo_pen_find_active_cw_vertex_index (pen, &slope, &stop);
+	if (status)
+	    return status;
 
 	tri[0] = f->point;
 	tri[1] = f->cw;
 	for (i=start; i != stop; i = (i+1) % pen->num_vertices) {
 	    tri[2] = f->point;
 	    _translate_point (&tri[2], &pen->vertices[i].point);
-	    _cairo_traps_tessellate_triangle (stroker->traps, tri);
+	    status = _cairo_traps_tessellate_triangle (stroker->traps, tri);
+	    if (status)
+		return status;
 	    tri[1] = tri[2];
 	}
 	tri[2] = f->ccw;
@@ -414,13 +431,24 @@ _cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f)
 	ocw.y = f->cw.y + fvector.dy;
 
 	_cairo_polygon_init (&polygon);
-	_cairo_polygon_move_to (&polygon, &f->cw);
-	_cairo_polygon_line_to (&polygon, &ocw);
-	_cairo_polygon_line_to (&polygon, &occw);
-	_cairo_polygon_line_to (&polygon, &f->ccw);
-	_cairo_polygon_close (&polygon);
+	status = _cairo_polygon_move_to (&polygon, &f->cw);
+	if (status)
+	    goto CLEANUP_LINE_CAP_SQUARE;
+	status = _cairo_polygon_line_to (&polygon, &ocw);
+	if (status)
+	    goto CLEANUP_LINE_CAP_SQUARE;
+	status = _cairo_polygon_line_to (&polygon, &occw);
+	if (status)
+	    goto CLEANUP_LINE_CAP_SQUARE;
+	status = _cairo_polygon_line_to (&polygon, &f->ccw);
+	if (status)
+	    goto CLEANUP_LINE_CAP_SQUARE;
+	status = _cairo_polygon_close (&polygon);
+	if (status)
+	    goto CLEANUP_LINE_CAP_SQUARE;
 
 	status = _cairo_bentley_ottmann_tessellate_polygon (stroker->traps, &polygon, CAIRO_FILL_RULE_WINDING);
+CLEANUP_LINE_CAP_SQUARE:
 	_cairo_polygon_fini (&polygon);
 
 	return status;
diff --git a/src/cairo-path.c b/src/cairo-path.c
index d79454c..95fe99c 100644
--- a/src/cairo-path.c
+++ b/src/cairo-path.c
@@ -141,15 +141,16 @@ _cairo_path_count (cairo_path_t		*path,
     cpc.current_point.x = 0;
     cpc.current_point.y = 0;
 
-    _cairo_path_fixed_interpret (path_fixed,
-				 CAIRO_DIRECTION_FORWARD,
-				 _cpc_move_to,
-				 _cpc_line_to,
-				 flatten ?
-				 _cpc_curve_to_flatten :
-				 _cpc_curve_to,
-				 _cpc_close_path,
-				 &cpc);
+    if (_cairo_path_fixed_interpret (path_fixed,
+				     CAIRO_DIRECTION_FORWARD,
+				     _cpc_move_to,
+				     _cpc_line_to,
+				     flatten ?
+				     _cpc_curve_to_flatten :
+				     _cpc_curve_to,
+				     _cpc_close_path,
+				     &cpc) != CAIRO_STATUS_SUCCESS)
+	return 0;
 
     return cpc.count;
 }
@@ -318,15 +319,16 @@ _cairo_path_populate (cairo_path_t		*path,
     cpp.current_point.x = 0;
     cpp.current_point.y = 0;
 
-    _cairo_path_fixed_interpret (path_fixed,
-				 CAIRO_DIRECTION_FORWARD,
-				 _cpp_move_to,
-				 _cpp_line_to,
-				 flatten ?
-				 _cpp_curve_to_flatten :
-				 _cpp_curve_to,
-				 _cpp_close_path,
-				 &cpp);
+    if (_cairo_path_fixed_interpret (path_fixed,
+				     CAIRO_DIRECTION_FORWARD,
+				     _cpp_move_to,
+				     _cpp_line_to,
+				     flatten ?
+				     _cpp_curve_to_flatten :
+				     _cpp_curve_to,
+				     _cpp_close_path,
+				     &cpp) != CAIRO_STATUS_SUCCESS)
+	return; /* XXX propagate status */
 
     /* Sanity check the count */
     assert (cpp.data - path->data == path->num_data);
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 2bc5580..3001e10 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1191,7 +1191,11 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
     pixman_image_set_filter (pixman_image, PIXMAN_FILTER_BILINEAR);
 
     _cairo_matrix_to_pixman_matrix (&pattern->base.matrix, &pixman_transform);
-    pixman_image_set_transform (pixman_image, &pixman_transform);
+    if (pixman_image_set_transform (pixman_image, &pixman_transform)) {
+	cairo_surface_destroy (&image->base);
+	pixman_image_destroy (pixman_image);
+	return CAIRO_STATUS_NO_MEMORY;
+    }
 
     switch (pattern->base.extend) {
     case CAIRO_EXTEND_NONE:
@@ -1755,7 +1759,9 @@ _cairo_pattern_get_extents (cairo_pattern_t         *pattern,
 	    return status;
 
 	imatrix = pattern->matrix;
-	cairo_matrix_invert (&imatrix);
+	status = cairo_matrix_invert (&imatrix);
+	if (status)
+	    return status;
 
 	/* XXX Use _cairo_matrix_transform_bounding_box here */
 	for (sy = 0; sy <= 1; sy++) {
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 3e8375f..67cfbc6 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -900,7 +900,9 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
     if (status)
 	goto BAIL;
 
-    _cairo_surface_get_extents (&surface->base, &surface_extents);
+    status = _cairo_surface_get_extents (&surface->base, &surface_extents);
+    if (status)
+	goto BAIL;
 
     switch (extend) {
     /* We implement EXTEND_PAD like EXTEND_NONE for now */
@@ -1253,6 +1255,7 @@ _cairo_pdf_surface_emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_radi
     cairo_pdf_resource_t function, pattern_resource, alpha;
     double x0, y0, x1, y1, r0, r1;
     cairo_matrix_t p2u;
+    cairo_status_t status;
 
     _cairo_pdf_surface_pause_content_stream (surface);
 
@@ -1261,7 +1264,9 @@ _cairo_pdf_surface_emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_radi
 	return CAIRO_STATUS_NO_MEMORY;
 
     p2u = pattern->base.base.matrix;
-    cairo_matrix_invert (&p2u);
+    status = cairo_matrix_invert (&p2u);
+    if (status)
+	return status;
 
     x0 = _cairo_fixed_to_double (pattern->gradient.c1.x);
     y0 = _cairo_fixed_to_double (pattern->gradient.c1.y);
@@ -1822,11 +1827,11 @@ _cairo_pdf_surface_emit_cff_font_subset (cairo_pdf_surface_t		*surface,
     font.font_id = font_subset->font_id;
     font.subset_id = font_subset->subset_id;
     font.subset_resource = subset_resource;
-    _cairo_array_append (&surface->fonts, &font);
+    status = _cairo_array_append (&surface->fonts, &font);
 
     _cairo_cff_subset_fini (&subset);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 static cairo_status_t
@@ -1931,9 +1936,7 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t		*surface,
     font.font_id = font_subset->font_id;
     font.subset_id = font_subset->subset_id;
     font.subset_resource = subset_resource;
-    _cairo_array_append (&surface->fonts, &font);
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_array_append (&surface->fonts, &font);
 }
 
 #if CAIRO_HAS_FT_FONT
@@ -2102,11 +2105,11 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t		*surface,
     font.font_id = font_subset->font_id;
     font.subset_id = font_subset->subset_id;
     font.subset_resource = subset_resource;
-    _cairo_array_append (&surface->fonts, &font);
+    status = _cairo_array_append (&surface->fonts, &font);
 
     _cairo_truetype_subset_fini (&subset);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 static cairo_int_status_t
@@ -2387,9 +2390,7 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t		*surface,
     font.font_id = font_subset->font_id;
     font.subset_id = font_subset->subset_id;
     font.subset_resource = subset_resource;
-    _cairo_array_append (&surface->fonts, &font);
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_array_append (&surface->fonts, &font);
 }
 
 static void
diff --git a/src/cairo-pen.c b/src/cairo-pen.c
index 1af8c36..1bc096b 100644
--- a/src/cairo-pen.c
+++ b/src/cairo-pen.c
@@ -135,6 +135,7 @@ cairo_status_t
 _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points)
 {
     cairo_pen_vertex_t *vertices;
+    cairo_status_t status;
     int num_vertices;
     int i;
 
@@ -150,7 +151,9 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points)
     for (i=0; i < num_points; i++)
 	pen->vertices[pen->num_vertices-num_points+i].point = point[i];
 
-    _cairo_hull_compute (pen->vertices, &pen->num_vertices);
+    status = _cairo_hull_compute (pen->vertices, &pen->num_vertices);
+    if (status)
+	return status;
 
     _cairo_pen_compute_slopes (pen);
 
@@ -388,7 +391,11 @@ _cairo_pen_stroke_spline_half (cairo_pen_t *pen,
 	final_slope.dy = -final_slope.dy;
     }
 
-    _cairo_pen_find_active_cw_vertex_index (pen, &initial_slope, &active);
+    status = _cairo_pen_find_active_cw_vertex_index (pen,
+	                                             &initial_slope,
+						     &active);
+    if (status)
+	return status;
 
     i = start;
     while (i != stop) {
@@ -437,18 +444,21 @@ _cairo_pen_stroke_spline (cairo_pen_t		*pen,
 
     status = _cairo_spline_decompose (spline, tolerance);
     if (status)
-	return status;
+	goto BAIL;
 
     status = _cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_FORWARD, &polygon);
     if (status)
-	return status;
+	goto BAIL;
 
     status = _cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_REVERSE, &polygon);
     if (status)
-	return status;
+	goto BAIL;
 
-    _cairo_polygon_close (&polygon);
-    _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon, CAIRO_FILL_RULE_WINDING);
+    status = _cairo_polygon_close (&polygon);
+    if (status)
+	goto BAIL;
+    status = _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon, CAIRO_FILL_RULE_WINDING);
+BAIL:
     _cairo_polygon_fini (&polygon);
 
     return CAIRO_STATUS_SUCCESS;
diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c
index f36bc71..84be855 100644
--- a/src/cairo-polygon.c
+++ b/src/cairo-polygon.c
@@ -135,9 +135,7 @@ _cairo_polygon_add_edge (cairo_polygon_t *polygon, cairo_point_t *p1, cairo_poin
     polygon->num_edges++;
 
   DONE:
-    _cairo_polygon_move_to (polygon, p2);
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_polygon_move_to (polygon, p2);
 }
 
 cairo_status_t
@@ -154,12 +152,12 @@ _cairo_polygon_move_to (cairo_polygon_t *polygon, cairo_point_t *point)
 cairo_status_t
 _cairo_polygon_line_to (cairo_polygon_t *polygon, cairo_point_t *point)
 {
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_status_t status;
 
     if (polygon->has_current_point) {
 	status = _cairo_polygon_add_edge (polygon, &polygon->current_point, point);
     } else {
-	_cairo_polygon_move_to (polygon, point);
+	status = _cairo_polygon_move_to (polygon, point);
     }
 
     return status;
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 84427e5..ea0f0f4 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -297,7 +297,7 @@ _cairo_ps_surface_emit_path (cairo_ps_surface_t	   *surface,
 			     cairo_line_cap_t	    line_cap)
 {
     cairo_output_stream_t *word_wrap;
-    cairo_status_t status;
+    cairo_status_t status, status2;
     ps_path_info_t path_info;
 
     word_wrap = _word_wrap_stream_create (stream, 79);
@@ -315,7 +315,9 @@ _cairo_ps_surface_emit_path (cairo_ps_surface_t	   *surface,
 
     if (status == CAIRO_STATUS_SUCCESS)
 	status = _cairo_output_stream_get_status (word_wrap);
-    _cairo_output_stream_destroy (word_wrap);
+    status2 = _cairo_output_stream_destroy (word_wrap);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
 
     return status;
 }
@@ -1201,7 +1203,7 @@ cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface)
 static cairo_status_t
 _cairo_ps_surface_finish (void *abstract_surface)
 {
-    cairo_status_t status;
+    cairo_status_t status, status2;
     cairo_ps_surface_t *surface = abstract_surface;
     int i, num_comments;
     char **comments;
@@ -1214,16 +1216,13 @@ _cairo_ps_surface_finish (void *abstract_surface)
 
     _cairo_ps_surface_emit_footer (surface);
 
-    _cairo_output_stream_close (surface->stream);
-    status = _cairo_output_stream_get_status (surface->stream);
-    _cairo_output_stream_destroy (surface->stream);
+    status = _cairo_output_stream_destroy (surface->stream);
 
     fclose (surface->tmpfile);
 
-    _cairo_output_stream_close (surface->final_stream);
+    status2 = _cairo_output_stream_destroy (surface->final_stream);
     if (status == CAIRO_STATUS_SUCCESS)
-	status = _cairo_output_stream_get_status (surface->final_stream);
-    _cairo_output_stream_destroy (surface->final_stream);
+	status = status2;
 
     num_comments = _cairo_array_num_elements (&surface->dsc_header_comments);
     comments = _cairo_array_index (&surface->dsc_header_comments, 0);
@@ -1588,20 +1587,29 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t    *surface,
 
 	_cairo_pattern_init_for_surface (&pattern.surface, &image->base);
 
-	_cairo_surface_fill_rectangle (opaque,
-				       CAIRO_OPERATOR_SOURCE,
-				       CAIRO_COLOR_WHITE,
-				       0, 0, image->width, image->height);
-
-	_cairo_surface_composite (CAIRO_OPERATOR_OVER,
-				  &pattern.base,
-				  NULL,
-				  opaque,
-				  0, 0,
-				  0, 0,
-				  0, 0,
-				  image->width,
-				  image->height);
+	status = _cairo_surface_fill_rectangle (opaque,
+				                CAIRO_OPERATOR_SOURCE,
+						CAIRO_COLOR_WHITE,
+						0, 0,
+					       	image->width, image->height);
+	if (status) {
+	    _cairo_pattern_fini (&pattern.base);
+	    goto bail0;
+	}
+
+	status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
+				           &pattern.base,
+					   NULL,
+					   opaque,
+					   0, 0,
+					   0, 0,
+					   0, 0,
+					   image->width,
+					   image->height);
+	if (status) {
+	    _cairo_pattern_fini (&pattern.base);
+	    goto bail0;
+	}
 
 	_cairo_pattern_fini (&pattern.base);
 	opaque_image = (cairo_image_surface_t *) opaque;
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 963c060..2391457 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -357,7 +357,7 @@ _cairo_scaled_font_init (cairo_scaled_font_t               *scaled_font,
     _cairo_scaled_font_init_key (scaled_font, font_face,
 				 font_matrix, ctm, options);
 
-    cairo_font_face_reference (font_face);
+    font_face = cairo_font_face_reference (font_face);
 
     cairo_matrix_multiply (&scaled_font->scale,
 			   &scaled_font->font_matrix,
@@ -1197,6 +1197,7 @@ _trace_mask_to_path (cairo_image_surface_t *mask,
 		     cairo_path_fixed_t *path)
 {
     cairo_image_surface_t *a1_mask;
+    cairo_status_t status;
     unsigned char *row, *byte_ptr, byte;
     int rows, cols, bytes_per_row;
     int x, y, bit;
@@ -1212,34 +1213,46 @@ _trace_mask_to_path (cairo_image_surface_t *mask,
 
     cairo_surface_get_device_offset (&mask->base, &xoff, &yoff);
 
+    status = CAIRO_STATUS_SUCCESS;
     bytes_per_row = (a1_mask->width + 7) / 8;
     for (y = 0, row = a1_mask->data, rows = a1_mask->height; rows; row += a1_mask->stride, rows--, y++) {
 	for (x = 0, byte_ptr = row, cols = (a1_mask->width + 7) / 8; cols; byte_ptr++, cols--) {
 	    byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte_ptr);
 	    for (bit = 7; bit >= 0 && x < a1_mask->width; bit--, x++) {
 		if (byte & (1 << bit)) {
-		    _cairo_path_fixed_move_to (path,
-					       _cairo_fixed_from_int (x + xoff),
-					       _cairo_fixed_from_int (y + yoff));
-		    _cairo_path_fixed_rel_line_to (path,
-						   _cairo_fixed_from_int (1),
-						   _cairo_fixed_from_int (0));
-		    _cairo_path_fixed_rel_line_to (path,
-						   _cairo_fixed_from_int (0),
-						   _cairo_fixed_from_int (1));
-		    _cairo_path_fixed_rel_line_to (path,
-						   _cairo_fixed_from_int (-1),
-						   _cairo_fixed_from_int (0));
-		    _cairo_path_fixed_close_path (path);
+		    status = _cairo_path_fixed_move_to (path,
+					      _cairo_fixed_from_int (x + xoff),
+					      _cairo_fixed_from_int (y + yoff));
+		    if (status)
+			goto BAIL;
+		    status = _cairo_path_fixed_rel_line_to (path,
+						     _cairo_fixed_from_int (1),
+						     _cairo_fixed_from_int (0));
+		    if (status)
+			goto BAIL;
+		    status = _cairo_path_fixed_rel_line_to (path,
+						     _cairo_fixed_from_int (0),
+						     _cairo_fixed_from_int (1));
+		    if (status)
+			goto BAIL;
+		    status = _cairo_path_fixed_rel_line_to (path,
+						     _cairo_fixed_from_int (-1),
+						     _cairo_fixed_from_int (0));
+		    if (status)
+			goto BAIL;
+		    status = _cairo_path_fixed_close_path (path);
+		    if (status)
+			goto BAIL;
 		}
 	    }
 	}
     }
 
+BAIL:
     if (a1_mask != mask)
 	cairo_surface_destroy (&a1_mask->base);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 cairo_status_t
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 1a7d666..9a1a844 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -452,8 +452,11 @@ _composite_trap_region (cairo_clip_t            *clip,
 				       extents->width, extents->height);
 
     /* Restore the original clip if we modified it temporarily. */
-    if (num_rects >1)
-	_cairo_surface_set_clip (dst, clip);
+    if (num_rects > 1) {
+	cairo_status_t status2 = _cairo_surface_set_clip (dst, clip);
+	if (status == CAIRO_STATUS_SUCCESS)
+	    status = status2;
+    }
 
     if (clip_surface)
       _cairo_pattern_fini (&mask.base);
@@ -979,17 +982,21 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
 
     _cairo_pattern_init_for_surface (&pattern.surface, &image->base);
 
-    _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
-			      &pattern.base,
-			      NULL,
-			      snapshot,
-			      0, 0,
-			      0, 0,
-			      0, 0,
-			      image->width,
-			      image->height);
+    status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
+			               &pattern.base,
+				       NULL,
+				       snapshot,
+				       0, 0,
+				       0, 0,
+				       0, 0,
+				       image->width,
+				       image->height);
 
     _cairo_pattern_fini (&pattern.base);
+    if (status) {
+	cairo_surface_destroy (snapshot);
+	return (cairo_surface_t *) &_cairo_surface_nil;
+    }
 
     _cairo_surface_release_source_image (surface,
 					 image, &image_extra);
@@ -1158,13 +1165,14 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t		op,
 	traps = offset_traps;
     }
 
-    _cairo_surface_composite_trapezoids (op, pattern,
-					 &state.image->base,
-					 antialias,
-					 src_x, src_y,
-					 dst_x - state.image_rect.x,
-					 dst_y - state.image_rect.y,
-					 width, height, traps, num_traps);
+    status = _cairo_surface_composite_trapezoids (op, pattern,
+					          &state.image->base,
+						  antialias,
+						  src_x, src_y,
+						  dst_x - state.image_rect.x,
+						  dst_y - state.image_rect.y,
+						  width, height,
+						  traps, num_traps);
     if (offset_traps)
 	free (offset_traps);
 
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 703017a..1c885d1 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -447,7 +447,8 @@ _cairo_svg_surface_store_page (cairo_svg_surface_t *surface)
     for (i = 0; i < page.clip_level; i++)
 	_cairo_output_stream_printf (page.xml_node, "</g>\n");
 
-    _cairo_array_append (&surface->page_set, &page);
+    if (_cairo_array_append (&surface->page_set, &page) != CAIRO_STATUS_SUCCESS)
+	return NULL;
 
     return _cairo_array_index (&surface->page_set, surface->page_set.num_elements - 1);
 }
@@ -776,7 +777,7 @@ _cairo_svg_surface_create_similar (void			*abstract_src,
 static cairo_status_t
 _cairo_svg_surface_finish (void *abstract_surface)
 {
-    cairo_status_t status;
+    cairo_status_t status, status2;
     cairo_svg_surface_t *surface = abstract_surface;
     cairo_svg_document_t *document = surface->document;
     cairo_svg_page_t *page;
@@ -787,11 +788,15 @@ _cairo_svg_surface_finish (void *abstract_surface)
     else
 	status = CAIRO_STATUS_SUCCESS;
 
-    _cairo_output_stream_destroy (surface->xml_node);
+    status2 = _cairo_output_stream_destroy (surface->xml_node);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
 
     for (i = 0; i < surface->page_set.num_elements; i++) {
 	page = _cairo_array_index (&surface->page_set, i);
-	_cairo_output_stream_destroy (page->xml_node);
+	status2 = _cairo_output_stream_destroy (page->xml_node);
+	if (status == CAIRO_STATUS_SUCCESS)
+	    status = status2;
     }
     _cairo_array_fini (&surface->page_set);
 
@@ -941,7 +946,9 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t     *outp
 	return status;
 
     p2u = pattern->base.matrix;
-    cairo_matrix_invert (&p2u);
+    status = cairo_matrix_invert (&p2u);
+    if (status)
+	return status;
 
     if (pattern_id != invalid_pattern_id) {
 	_cairo_output_stream_printf (output,
@@ -1075,15 +1082,18 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t	*output,
     cairo_svg_document_t *document = surface->document;
     cairo_meta_surface_t *meta_surface;
     cairo_matrix_t p2u;
+    cairo_status_t status;
     int id;
 
+    p2u = pattern->base.matrix;
+    status = cairo_matrix_invert (&p2u);
+    if (status)
+	return status;
+
     meta_surface = (cairo_meta_surface_t *) pattern->surface;
 
     id = _cairo_svg_surface_emit_meta_surface (document, meta_surface);
 
-    p2u = pattern->base.matrix;
-    cairo_matrix_invert (&p2u);
-
     if (pattern_id != invalid_pattern_id) {
 	_cairo_output_stream_printf (output,
 				     "<pattern id=\"pattern%d\" "
@@ -1375,6 +1385,12 @@ _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t    *surface,
     cairo_svg_document_t *document = surface->document;
     double x0, y0, x1, y1;
     cairo_matrix_t p2u;
+    cairo_status_t status;
+
+    p2u = pattern->base.base.matrix;
+    status = cairo_matrix_invert (&p2u);
+    if (status)
+	return status;
 
     x0 = _cairo_fixed_to_double (pattern->gradient.p1.x);
     y0 = _cairo_fixed_to_double (pattern->gradient.p1.y);
@@ -1389,8 +1405,6 @@ _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t    *surface,
 				 x0, y0, x1, y1);
 
     _cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base),
-    p2u = pattern->base.base.matrix;
-    cairo_matrix_invert (&p2u);
     _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", ">\n", &p2u);
 
     _cairo_svg_surface_emit_pattern_stops (document->xml_node_defs ,&pattern->base, 0.0, FALSE, FALSE);
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index a183b28..eef0d73 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -558,6 +558,7 @@ cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
                                      const char         *name)
 {
     cairo_int_status_t status;
+    cairo_status_t status2;
     cairo_output_stream_t *encrypted_output;
 
     font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
@@ -597,10 +598,10 @@ cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
                                  "dup /FontName get exch definefont pop\n"
                                  "mark currentfile closefile\n");
 
-    if (status == CAIRO_STATUS_SUCCESS)
-	status = _cairo_output_stream_get_status (encrypted_output);
   fail:
-    _cairo_output_stream_destroy (encrypted_output);
+    status2 = _cairo_output_stream_destroy (encrypted_output);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
 
     return status;
 }
diff --git a/src/cairo.c b/src/cairo.c
index 9a96dda..b8a0419 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -189,6 +189,7 @@ cairo_t *
 cairo_create (cairo_surface_t *target)
 {
     cairo_t *cr;
+    cairo_status_t status;
 
     cr = malloc (sizeof (cairo_t));
     if (cr == NULL)
@@ -201,14 +202,18 @@ cairo_create (cairo_surface_t *target)
     _cairo_user_data_array_init (&cr->user_data);
 
     cr->gstate = cr->gstate_tail;
-    _cairo_gstate_init (cr->gstate, target);
+    status = _cairo_gstate_init (cr->gstate, target);
 
     _cairo_path_fixed_init (cr->path);
 
     if (target == NULL) {
-	_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
+	/* override status with user error */
+	status = CAIRO_STATUS_NULL_POINTER;
     }
 
+    if (status)
+	_cairo_set_error (cr, status);
+
     return cr;
 }
 slim_hidden_def (cairo_create);
@@ -483,9 +488,11 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
 
     parent_surface = _cairo_gstate_get_target (cr->gstate);
     /* Get the extents that we'll use in creating our new group surface */
-    _cairo_surface_get_extents (parent_surface, &extents);
+    status = _cairo_surface_get_extents (parent_surface, &extents);
+    if (status)
+	goto bail;
     status = _cairo_clip_intersect_to_rectangle (_cairo_gstate_get_clip (cr->gstate), &extents);
-    if (status != CAIRO_STATUS_SUCCESS)
+    if (status)
 	goto bail;
 
     group_surface = cairo_surface_create_similar (_cairo_gstate_get_target (cr->gstate),
@@ -563,7 +570,7 @@ cairo_pop_group (cairo_t *cr)
     /* We need to save group_surface before we restore; we don't need
      * to reference parent_target and original_target, since the
      * gstate will still hold refs to them once we restore. */
-    cairo_surface_reference (group_surface);
+    group_surface = cairo_surface_reference (group_surface);
 
     cairo_restore (cr);
 
@@ -1623,17 +1630,20 @@ void
 cairo_rel_move_to (cairo_t *cr, double dx, double dy)
 {
     cairo_fixed_t dx_fixed, dy_fixed;
+    cairo_status_t status;
 
     if (cr->status)
 	return;
 
-    _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
-    dx_fixed = _cairo_fixed_from_double (dx);
-    dy_fixed = _cairo_fixed_from_double (dy);
+    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
+    if (status == CAIRO_STATUS_SUCCESS) {
+	dx_fixed = _cairo_fixed_from_double (dx);
+	dy_fixed = _cairo_fixed_from_double (dy);
 
-    cr->status = _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+	status = _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
+    }
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1658,17 +1668,20 @@ void
 cairo_rel_line_to (cairo_t *cr, double dx, double dy)
 {
     cairo_fixed_t dx_fixed, dy_fixed;
+    cairo_status_t status;
 
     if (cr->status)
 	return;
 
-    _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
-    dx_fixed = _cairo_fixed_from_double (dx);
-    dy_fixed = _cairo_fixed_from_double (dy);
+    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
+    if (status == CAIRO_STATUS_SUCCESS) {
+	dx_fixed = _cairo_fixed_from_double (dx);
+	dy_fixed = _cairo_fixed_from_double (dy);
 
-    cr->status = _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+	status = _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
+    }
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def(cairo_rel_line_to);
 
@@ -1707,13 +1720,20 @@ cairo_rel_curve_to (cairo_t *cr,
     cairo_fixed_t dx1_fixed, dy1_fixed;
     cairo_fixed_t dx2_fixed, dy2_fixed;
     cairo_fixed_t dx3_fixed, dy3_fixed;
+    cairo_status_t status;
 
     if (cr->status)
 	return;
 
-    _cairo_gstate_user_to_device_distance (cr->gstate, &dx1, &dy1);
-    _cairo_gstate_user_to_device_distance (cr->gstate, &dx2, &dy2);
-    _cairo_gstate_user_to_device_distance (cr->gstate, &dx3, &dy3);
+    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx1, &dy1);
+    if (status)
+	goto BAIL;
+    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx2, &dy2);
+    if (status)
+	goto BAIL;
+    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx3, &dy3);
+    if (status)
+	goto BAIL;
 
     dx1_fixed = _cairo_fixed_from_double (dx1);
     dy1_fixed = _cairo_fixed_from_double (dy1);
@@ -1724,12 +1744,14 @@ cairo_rel_curve_to (cairo_t *cr,
     dx3_fixed = _cairo_fixed_from_double (dx3);
     dy3_fixed = _cairo_fixed_from_double (dy3);
 
-    cr->status = _cairo_path_fixed_rel_curve_to (cr->path,
-						 dx1_fixed, dy1_fixed,
-						 dx2_fixed, dy2_fixed,
-						 dx3_fixed, dy3_fixed);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_path_fixed_rel_curve_to (cr->path,
+					     dx1_fixed, dy1_fixed,
+					     dx2_fixed, dy2_fixed,
+					     dx3_fixed, dy3_fixed);
+    if (status) {
+BAIL:
+	_cairo_set_error (cr, status);
+    }
 }
 
 /**
diff --git a/test/buffer-diff.c b/test/buffer-diff.c
index d111b23..abb7e33 100644
--- a/test/buffer-diff.c
+++ b/test/buffer-diff.c
@@ -339,6 +339,7 @@ image_diff_core (const char *filename_a,
 
     compare_surfaces (surface_a, surface_b, surface_diff, result);
 
+    status = CAIRO_STATUS_SUCCESS;
     if (result->pixels_changed) {
 	FILE *png_file;
 
@@ -347,7 +348,7 @@ image_diff_core (const char *filename_a,
 	else
 	    png_file = stdout;
 
-	cairo_surface_write_to_png_stream (surface_diff, stdio_write_func, png_file);
+	status = cairo_surface_write_to_png_stream (surface_diff, stdio_write_func, png_file);
 
 	if (png_file != stdout)
 	    fclose (png_file);
@@ -360,7 +361,7 @@ image_diff_core (const char *filename_a,
     cairo_surface_destroy (surface_b);
     cairo_surface_destroy (surface_diff);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 cairo_status_t
-- 
1.4.4.2



More information about the cairo mailing list