[cairo-commit] 3 commits - src/cairo-analysis-surface.c src/cairo-array.c src/cairo-atomic.c src/cairo-atomic-private.h src/cairo-atsui-font.c src/cairo-base85-stream.c src/cairo-bentley-ottmann.c src/cairo.c src/cairo-cache.c src/cairo-cff-subset.c src/cairo-clip.c src/cairo-deflate-stream.c src/cairo-directfb-surface.c src/cairo-font-face.c src/cairo-font-options.c src/cairo-ft-font.c src/cairo-glitz-surface.c src/cairo-gstate.c src/cairo-hash.c src/cairo-hull.c src/cairo-image-surface.c src/cairoint.h src/cairo-lzw.c src/cairo-matrix.c src/cairo-meta-surface.c src/cairo-os2-surface.c src/cairo-output-stream.c src/cairo-paginated-surface.c src/cairo-path.c src/cairo-path-fixed.c src/cairo-path-stroke.c src/cairo-pattern.c src/cairo-pdf-surface.c src/cairo-pen.c src/cairo-png.c src/cairo-polygon.c src/cairo-ps-surface.c src/cairo-quartz-surface.c src/cairo-region.c src/cairo-scaled-font.c src/cairo-scaled-font-subsets.c src/cairo-skiplist.c src/cairo-spline.c src/cairo-stroke-style.c src/cairo-surface.c src/cairo-surface-fallback.c src/cairo-svg-surface.c src/cairo-traps.c src/cairo-truetype-subset.c src/cairo-type1-fallback.c src/cairo-type1-subset.c src/cairo-unicode.c src/cairo-win32-font.c src/cairo-win32-surface.c src/cairo-xcb-surface.c src/cairo-xlib-display.c src/cairo-xlib-surface.c src/test-fallback-surface.c src/test-meta-surface.c src/test-paginated-surface.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Oct 4 06:07:10 PDT 2007


 src/cairo-analysis-surface.c    |    4 -
 src/cairo-array.c               |    9 --
 src/cairo-atomic-private.h      |    8 ++
 src/cairo-atomic.c              |   15 ++++
 src/cairo-atsui-font.c          |   18 ++---
 src/cairo-base85-stream.c       |    2 
 src/cairo-bentley-ottmann.c     |   22 ++-----
 src/cairo-cache.c               |    4 -
 src/cairo-cff-subset.c          |  122 +++++++++++++++-------------------------
 src/cairo-clip.c                |   18 ++---
 src/cairo-deflate-stream.c      |    2 
 src/cairo-directfb-surface.c    |   49 +++++++---------
 src/cairo-font-face.c           |    6 -
 src/cairo-font-options.c        |    4 -
 src/cairo-ft-font.c             |  111 ++++++++++++++----------------------
 src/cairo-glitz-surface.c       |   89 ++++++++++++-----------------
 src/cairo-gstate.c              |   37 ++++--------
 src/cairo-hash.c                |   10 +--
 src/cairo-hull.c                |    2 
 src/cairo-image-surface.c       |   47 ++++++---------
 src/cairo-lzw.c                 |    6 -
 src/cairo-matrix.c              |    4 -
 src/cairo-meta-surface.c        |   48 +++++----------
 src/cairo-os2-surface.c         |   24 +++----
 src/cairo-output-stream.c       |   18 ++---
 src/cairo-paginated-surface.c   |    8 --
 src/cairo-path-fixed.c          |   14 ++--
 src/cairo-path-stroke.c         |    6 -
 src/cairo-path.c                |   16 ++---
 src/cairo-pattern.c             |   80 +++++++++++---------------
 src/cairo-pdf-surface.c         |   62 ++++++++------------
 src/cairo-pen.c                 |   19 ++----
 src/cairo-png.c                 |   24 +++----
 src/cairo-polygon.c             |    6 -
 src/cairo-ps-surface.c          |   63 ++++++++------------
 src/cairo-quartz-surface.c      |   15 +---
 src/cairo-region.c              |   22 ++-----
 src/cairo-scaled-font-subsets.c |   20 ++----
 src/cairo-scaled-font.c         |   29 ++++-----
 src/cairo-skiplist.c            |    2 
 src/cairo-spline.c              |    6 -
 src/cairo-stroke-style.c        |    6 -
 src/cairo-surface-fallback.c    |   10 +--
 src/cairo-surface.c             |   95 ++++++++++++++++---------------
 src/cairo-svg-surface.c         |   24 ++-----
 src/cairo-traps.c               |    9 --
 src/cairo-truetype-subset.c     |   43 +++++---------
 src/cairo-type1-fallback.c      |   27 +++-----
 src/cairo-type1-subset.c        |   30 ++++-----
 src/cairo-unicode.c             |   20 ++----
 src/cairo-win32-font.c          |   40 ++++++-------
 src/cairo-win32-surface.c       |   23 +++----
 src/cairo-xcb-surface.c         |   50 ++++++----------
 src/cairo-xlib-display.c        |    2 
 src/cairo-xlib-surface.c        |   88 +++++++++++++---------------
 src/cairo.c                     |   26 ++++----
 src/cairoint.h                  |   10 ++-
 src/test-fallback-surface.c     |    2 
 src/test-meta-surface.c         |    6 -
 src/test-paginated-surface.c    |    6 -
 60 files changed, 701 insertions(+), 887 deletions(-)

New commits:
diff-tree bed8239f03773ad1584c8ba48ceb0b34bbe69453 (from d90d4bb6b99e0a912650234e28d097ea76c1cecc)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 4 13:15:46 2007 +0100

    [cairo-error] Clean up all the warnings and missing _cairo_error() calls.
    
    Every time we assign or return a hard-coded error status wrap that value
    with a call to _cairo_error(). So the idiom becomes:
        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
    or
        return _cairo_error (CAIRO_STATUS_INVALID_DASH);
    
    This ensures that a breakpoint placed on _cairo_error() will trigger
    immediately cairo detects the error.

diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 067543f..97b245e 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -76,7 +76,7 @@ _cairo_analysis_surface_analyze_meta_sur
     analysis = _cairo_analysis_surface_create (surface->target,
 					       surface->width, surface->height);
     if (analysis == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = _cairo_meta_surface_replay_analyze_meta_pattern (meta_surface, analysis);
     if (status == CAIRO_STATUS_SUCCESS)
@@ -592,7 +592,7 @@ _cairo_analysis_surface_create (cairo_su
 
     return &surface->base;
 FAIL:
-    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
     return NULL;
 }
 
diff --git a/src/cairo-array.c b/src/cairo-array.c
index 58c699e..0313caa 100644
--- a/src/cairo-array.c
+++ b/src/cairo-array.c
@@ -132,10 +132,8 @@ _cairo_array_grow_by (cairo_array_t *arr
 
     if (array->elements == NULL) {
 	array->elements = malloc (sizeof (char *));
-	if (array->elements == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (array->elements == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	*array->elements = NULL;
     }
@@ -146,8 +144,7 @@ _cairo_array_grow_by (cairo_array_t *arr
 
     if (new_elements == NULL) {
 	array->size = old_size;
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     *array->elements = new_elements;
diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
index ab567c6..b677185 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -213,7 +213,7 @@ _cairo_atsui_font_set_metrics (cairo_ats
         }
     }
 
-    return CAIRO_STATUS_NULL_POINTER;
+    return _cairo_error (CAIRO_STATUS_NULL_POINTER);
 }
 
 static cairo_status_t
@@ -233,7 +233,7 @@ _cairo_atsui_font_create_scaled (cairo_f
 
     font = malloc(sizeof(cairo_atsui_font_t));
     if (font == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = _cairo_scaled_font_init (&font->base,
 				      font_face, font_matrix, ctm, options,
@@ -263,7 +263,7 @@ _cairo_atsui_font_create_scaled (cairo_f
 				sizeof(ATSUAttributeTag), theFontStyleTags,
 				theFontStyleSizes, theFontStyleValues);
 	if (err != noErr) {
-	    status = CAIRO_STATUS_NO_MEMORY;
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto FAIL;
 	}
     }
@@ -436,7 +436,7 @@ _cairo_atsui_font_init_glyph_metrics (ca
 				     1, &theGlyph, 0, false,
 				     false, &metricsH);
     if (err != noErr)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     /* Scale down to font units.*/
     _cairo_matrix_compute_scale_factors (&scaled_font->base.scale,
@@ -550,7 +550,7 @@ _cairo_atsui_scaled_font_init_glyph_path
     
     scaled_path.path = _cairo_path_fixed_create ();
     if (!scaled_path.path)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (theGlyph == kATSDeletedGlyphcode) {
 	_cairo_scaled_glyph_set_path (scaled_glyph, &scaled_font->base, 
@@ -703,7 +703,7 @@ _cairo_atsui_scaled_font_init_glyph_surf
 
     if (!drawingContext) {
 	cairo_surface_destroy ((cairo_surface_t *)surface);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
     
     atsFont = FMGetATSFontRefFromFont (scaled_font->fontID);
@@ -810,10 +810,8 @@ _cairo_atsui_font_text_to_glyphs (void		
     *num_glyphs = glyphCount - 1;
     *glyphs =
 	(cairo_glyph_t *) _cairo_malloc_ab(*num_glyphs, sizeof (cairo_glyph_t));
-    if (*glyphs == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (*glyphs == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     _cairo_matrix_compute_scale_factors (&font->base.ctm, &xscale, &yscale, 1);
     device_to_user_scale = 
diff --git a/src/cairo-base85-stream.c b/src/cairo-base85-stream.c
index bfde0cf..97ef263 100644
--- a/src/cairo-base85-stream.c
+++ b/src/cairo-base85-stream.c
@@ -115,7 +115,7 @@ _cairo_base85_stream_create (cairo_outpu
 
     stream = malloc (sizeof (cairo_base85_stream_t));
     if (stream == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
     }
 
diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c
index 679b532..b8a5f81 100644
--- a/src/cairo-bentley-ottmann.c
+++ b/src/cairo-bentley-ottmann.c
@@ -701,7 +701,7 @@ _cairo_bo_event_queue_insert (cairo_bo_e
     /* Don't insert if there's already an equivalent intersection event in the queue. */
     if (_cairo_skip_list_insert (&queue->intersection_queue, event,
 		      event->type == CAIRO_BO_EVENT_TYPE_INTERSECTION) == NULL)
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
     return status;
 }
 
@@ -755,10 +755,8 @@ _cairo_bo_event_queue_init (cairo_bo_eve
      * event type a union so it doesn't always contain the skip
      * elt? */
     events = _cairo_malloc_ab (num_events, sizeof (cairo_bo_event_t) + sizeof(cairo_bo_event_t*));
-    if (events == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (events == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     sorted_event_ptrs = (cairo_bo_event_t **) (events + num_events);
     event_queue->startstop_events = events;
@@ -861,7 +859,7 @@ _cairo_bo_sweep_line_insert (cairo_bo_sw
     sweep_line_elt = _cairo_skip_list_insert (&sweep_line->active_edges, &edge,
 				       1 /* unique inserts*/);
     if (sweep_line_elt == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     next_elt = sweep_line_elt->elt.next[0];
     if (next_elt)
@@ -1148,10 +1146,8 @@ _cairo_bo_edge_start_or_continue_trap (c
 
     if (edge->next) {
 	trap = edge->deferred_trap = _cairo_freelist_alloc (&bo_traps->freelist);
-	if (!edge->deferred_trap) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (!edge->deferred_trap)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	trap->right = edge->next;
 	trap->top = top;
@@ -1441,10 +1437,8 @@ _cairo_bentley_ottmann_tessellate_polygo
 	edges = stack_edges;
     } else {
 	edges = _cairo_malloc_ab (polygon->num_edges, sizeof (cairo_bo_edge_t));
-	if (edges == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (edges == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     /* Figure out the bounding box of the input coordinates and
diff --git a/src/cairo-cache.c b/src/cairo-cache.c
index a7c27c1..9bb4de5 100644
--- a/src/cairo-cache.c
+++ b/src/cairo-cache.c
@@ -54,7 +54,7 @@ _cairo_cache_init (cairo_cache_t		*cache
 {
     cache->hash_table = _cairo_hash_table_create (keys_equal);
     if (cache->hash_table == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     cache->entry_destroy = entry_destroy;
 
@@ -132,7 +132,7 @@ _cairo_cache_create (cairo_cache_keys_eq
 
     cache = malloc (sizeof (cairo_cache_t));
     if (cache == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index aac1378..7bc7cb9 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -389,10 +389,8 @@ cff_index_append_copy (cairo_array_t *in
     element.length = length;
     element.is_copy = TRUE;
     element.data = malloc (element.length);
-    if (element.data == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (element.data == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     memcpy (element.data, object, element.length);
 
@@ -444,7 +442,7 @@ cff_dict_create_operator (int           
 
     op = malloc (sizeof (cff_dict_operator_t));
     if (op == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
         return NULL;
     }
 
@@ -452,7 +450,7 @@ cff_dict_create_operator (int           
     op->operand = malloc (operand_length);
     if (op->operand == NULL) {
         free (op);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
         return NULL;
     }
     memcpy (op->operand, operand, operand_length);
@@ -487,7 +485,7 @@ cff_dict_read (cairo_hash_table_t *dict,
                                            _cairo_array_index (&operands, 0),
                                            _cairo_array_num_elements (&operands));
             if (op == NULL) {
-                status = CAIRO_STATUS_NO_MEMORY;
+                status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
                 goto fail;
             }
             status = _cairo_hash_table_insert (dict, &op->base);
@@ -551,10 +549,8 @@ cff_dict_set_operands (cairo_hash_table_
     {
         free (op->operand);
         op->operand = malloc (size);
-	if (op->operand == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (op->operand == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
         memcpy (op->operand, operand, size);
         op->operand_length = size;
@@ -562,10 +558,8 @@ cff_dict_set_operands (cairo_hash_table_
     else
     {
         op = cff_dict_create_operator (operator, operand, size);
-        if (op == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+        if (op == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	status = _cairo_hash_table_insert (dict, &op->base);
 	if (status)
@@ -731,10 +725,8 @@ cairo_cff_font_read_fdselect (cairo_cff_
     int type, num_ranges, first, last, fd, i, j;
 
     font->fdselect = calloc (font->num_glyphs, sizeof (int));
-    if (font->fdselect == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (font->fdselect == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     type = *p++;
     if (type == 0)
@@ -782,26 +774,26 @@ cairo_cff_font_read_cid_fontdict (cairo_
 
     font->fd_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
     if (font->fd_dict == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto fail;
     }
 
     font->fd_private_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
     if (font->fd_private_dict == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto fail;
     }
 
     font->fd_local_sub_index = calloc (sizeof (cairo_array_t), font->num_fontdicts);
     if (font->fd_local_sub_index == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto fail;
     }
 
     for (i = 0; i < font->num_fontdicts; i++) {
         cff_dict_init (&font->fd_dict[i]);
         if (font->fd_dict[i] == NULL) {
-            status = CAIRO_STATUS_NO_MEMORY;
+            status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
             goto fail;
         }
         element = _cairo_array_index (&index, i);
@@ -818,7 +810,7 @@ cairo_cff_font_read_cid_fontdict (cairo_
         decode_integer (operand, &offset);
         cff_dict_init (&font->fd_private_dict[i]);
         if (font->fd_private_dict[i] == NULL) {
-            status = CAIRO_STATUS_NO_MEMORY;
+            status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
             goto fail;
         }
         cff_index_init (&font->fd_local_sub_index[i]);
@@ -843,8 +835,7 @@ cairo_cff_font_read_cid_fontdict (cairo_
 fail:
     cff_index_fini (&index);
 
-    _cairo_error (status);
-    return status;
+    return _cairo_error (status);
 }
 
 static cairo_int_status_t
@@ -1078,28 +1069,20 @@ cairo_cff_font_subset_fontdict (cairo_cf
 
     font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
                                      sizeof (int));
-    if (font->fdselect_subset == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-        return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (font->fdselect_subset == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int));
-    if (font->fd_subset_map == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-        return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (font->fd_subset_map == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int));
-    if (font->private_dict_offset == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-        return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (font->private_dict_offset == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     reverse_map = calloc (font->num_fontdicts, sizeof (int));
-    if (reverse_map == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-        return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (reverse_map == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     for (i = 0; i < font->num_fontdicts; i++)
         reverse_map[i] = -1;
@@ -1127,24 +1110,18 @@ cairo_cff_font_create_cid_fontdict (cair
 
     font->num_fontdicts = 1;
     font->fd_dict = malloc (sizeof (cairo_hash_table_t *));
-    if (font->fd_dict == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-        return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (font->fd_dict == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     cff_dict_init (&font->fd_dict[0]);
 
     font->fd_subset_map = malloc (sizeof (int));
-    if (font->fd_subset_map == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-        return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (font->fd_subset_map == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     font->private_dict_offset = malloc (sizeof (int));
-    if (font->private_dict_offset == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-        return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (font->private_dict_offset == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     font->fd_subset_map[0] = 0;
     font->num_subset_fontdicts = 1;
@@ -1698,10 +1675,8 @@ _cairo_cff_font_create (cairo_scaled_fon
         return status;
 
     name = malloc (size);
-    if (name == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-        return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (name == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
                                            TT_TAG_name, 0,
@@ -1711,7 +1686,7 @@ _cairo_cff_font_create (cairo_scaled_fon
 
     font = malloc (sizeof (cairo_cff_font_t));
     if (font == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail1;
     }
 
@@ -1725,7 +1700,7 @@ _cairo_cff_font_create (cairo_scaled_fon
 
     font->subset_font_name = strdup (subset_name);
     if (font->subset_font_name == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail3;
     }
     font->x_min = (int16_t) be16_to_cpu (head.x_min);
@@ -1761,7 +1736,7 @@ _cairo_cff_font_create (cairo_scaled_fon
     if (font->font_name == NULL) {
         font->font_name = malloc (30);
         if (font->font_name == NULL) {
-            status = CAIRO_STATUS_NO_MEMORY;
+            status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
             goto fail4;
         }
         snprintf(font->font_name, 30, "CairoFont-%u-%u",
@@ -1778,7 +1753,7 @@ _cairo_cff_font_create (cairo_scaled_fon
 
     font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
     if (font->widths == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto fail5;
     }
     cairo_cff_font_create_set_widths (font);
@@ -1786,7 +1761,7 @@ _cairo_cff_font_create (cairo_scaled_fon
     font->data_length = data_length;
     font->data = malloc (data_length);
     if (font->data == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto fail6;
     }
     status = font->backend->load_truetype_table ( font->scaled_font_subset->scaled_font,
@@ -1831,8 +1806,7 @@ fail2:
     free (font);
 fail1:
     free (name);
-    _cairo_error (status);
-    return status;
+    return _cairo_error (status);
 }
 
 static void
@@ -1946,8 +1920,7 @@ _cairo_cff_subset_init (cairo_cff_subset
  fail1:
     cairo_cff_font_destroy (font);
 
-    _cairo_error (status);
-    return status;
+    return _cairo_error (status);
 }
 
 void
@@ -1967,10 +1940,8 @@ _cairo_cff_font_fallback_create (cairo_s
     cairo_cff_font_t *font;
 
     font = malloc (sizeof (cairo_cff_font_t));
-    if (font == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-        return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (font == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     font->backend = NULL;
     font->scaled_font_subset = scaled_font_subset;
@@ -1982,13 +1953,13 @@ _cairo_cff_font_fallback_create (cairo_s
 
     font->subset_font_name = strdup (subset_name);
     if (font->subset_font_name == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail2;
     }
 
     font->font_name = strdup (subset_name);
     if (font->subset_font_name == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail3;
     }
 
@@ -2001,7 +1972,7 @@ _cairo_cff_font_fallback_create (cairo_s
 
     font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
     if (font->widths == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto fail4;
     }
 
@@ -2037,8 +2008,7 @@ fail2:
     _cairo_array_fini (&font->output);
 fail1:
     free (font);
-    _cairo_error (status);
-    return status;
+    return _cairo_error (status);
 }
 
 static cairo_int_status_t
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 4f42414..43b25ca 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -86,7 +86,7 @@ _cairo_clip_init_copy (cairo_clip_t *cli
         {
 	    _cairo_region_fini (&clip->region);
 	    cairo_surface_destroy (clip->surface);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
         clip->has_region = TRUE;
     } else {
@@ -276,10 +276,8 @@ _cairo_clip_intersect_path (cairo_clip_t
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     clip_path = malloc (sizeof (cairo_clip_path_t));
-    if (clip_path == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (clip_path == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = _cairo_path_fixed_init_copy (&clip_path->path, path);
     if (status) {
@@ -404,7 +402,7 @@ _cairo_clip_intersect_mask (cairo_clip_t
 						   CAIRO_COLOR_WHITE,
 						   NULL);
     if (surface->status)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     /* Render the new clipping path into the new mask surface. */
 
@@ -593,7 +591,7 @@ BAIL:
     if (clip->surface)
 	cairo_surface_destroy (clip->surface);
 
-    return CAIRO_STATUS_NO_MEMORY;
+    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 }
 
 const cairo_rectangle_list_t _cairo_rectangles_nil =
@@ -644,7 +642,7 @@ _cairo_clip_copy_rectangle_list (cairo_c
 	    rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
 	    if (rectangles == NULL) {
 		_cairo_region_boxes_fini (&clip->region, boxes);
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
+		_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 		return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
 	    }
 
@@ -669,7 +667,7 @@ _cairo_clip_copy_rectangle_list (cairo_c
 
 	rectangles = malloc(sizeof (cairo_rectangle_t));
 	if (rectangles == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
 	}
 
@@ -684,7 +682,7 @@ _cairo_clip_copy_rectangle_list (cairo_c
     list = malloc (sizeof (cairo_rectangle_list_t));
     if (list == NULL) {
         free (rectangles);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
         return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
     }
     
diff --git a/src/cairo-deflate-stream.c b/src/cairo-deflate-stream.c
index 618c6be..73746fe 100644
--- a/src/cairo-deflate-stream.c
+++ b/src/cairo-deflate-stream.c
@@ -119,7 +119,7 @@ _cairo_deflate_stream_create (cairo_outp
 
     stream = malloc (sizeof (cairo_deflate_stream_t));
     if (stream == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
     }
 
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index 50f926c..b79f8e2 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -390,7 +390,7 @@ _directfb_acquire_surface (cairo_directf
       if( buffer != surface->dfbsurface) 
         buffer->Release(buffer);
     }
-    return CAIRO_STATUS_NO_MEMORY;
+    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 }
 
 
@@ -415,7 +415,7 @@ _cairo_directfb_surface_create_similar (
     format = _cairo_format_from_content (content);             
     surface = calloc (1, sizeof(cairo_directfb_surface_t));
     if (!surface) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
         return NULL;
     }
    
@@ -576,14 +576,14 @@ _cairo_directfb_surface_clone_similar (v
                             _cairo_content_from_format (image_src->format),
                             image_src->width, image_src->height);
         if (!clone)
-            return CAIRO_STATUS_NO_MEMORY;
+            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
             
         ret = clone->dfbsurface->Lock (clone->dfbsurface, 
                                    DSLF_WRITE, (void *)&dst, &pitch);
         if (ret) {
             DirectFBError ("IDirectFBSurface::Lock()", ret);
             cairo_surface_destroy ((cairo_surface_t *)clone);
-            return CAIRO_STATUS_NO_MEMORY;
+            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
         }
 
 	dst += pitch * src_y;
@@ -687,7 +687,7 @@ _directfb_prepare_composite (cairo_direc
             dst->color = _cairo_directfb_surface_create_similar (dst,
                                                 CAIRO_CONTENT_COLOR_ALPHA, 1, 1);
             if (!dst->color)
-                return CAIRO_STATUS_NO_MEMORY;
+                return _cairo_error (CAIRO_STATUS_NO_MEMORY);
         }
         
         src = (cairo_directfb_surface_t *)dst->color;
@@ -758,7 +758,7 @@ _cairo_directfb_surface_composite (cairo
                                    unsigned int      height)
 {
     cairo_directfb_surface_t   *dst = abstract_dst;
-    cairo_directfb_surface_t   *src;
+    cairo_directfb_surface_t   *src = NULL; /* hide compiler warning */
     cairo_surface_attributes_t  src_attr;
     cairo_matrix_t             *m;
     cairo_status_t              ret;
@@ -1109,9 +1109,11 @@ _cairo_directfb_surface_set_clip_region 
     if (region) {
         cairo_box_int_t *boxes;
         int n_boxes, i;
+	cairo_status_t status;
 
-        if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
-            return CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_region_get_boxes (region, &n_boxes, &boxes);
+	if (status)
+	    return status;
 
         if (surface->n_clips != n_boxes) {
             if( surface->clips )
@@ -1121,8 +1123,7 @@ _cairo_directfb_surface_set_clip_region 
             if (!surface->clips) {
                 _cairo_region_boxes_fini (region, boxes);
                 surface->n_clips = 0;
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
-                return CAIRO_STATUS_NO_MEMORY;
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
             }
         
             surface->n_clips = n_boxes;
@@ -1184,7 +1185,7 @@ _cairo_directfb_surface_mark_dirty_recta
     if( !surface->dirty_region ) 
             surface->dirty_region = malloc(sizeof(DFBRegion));
     if (!dirty_region)
-            return CAIRO_STATUS_NO_MEMORY;
+            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 #endif 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1215,14 +1216,14 @@ _directfb_allocate_font_cache (IDirectFB
 
     cache = calloc (1, sizeof(cairo_directfb_font_cache_t));
     if (!cache) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
     cache->dfbsurface = _directfb_buffer_surface_create( dfb, DSPF_A8, width, height);
     if (!cache->dfbsurface) {
         free (cache);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
         return NULL;
     }
 
@@ -1319,10 +1320,8 @@ _directfb_acquire_font_cache (cairo_dire
             
             /* Remember glyph location */ 
             rect = malloc (sizeof(DFBRectangle));
-            if (!rect) {
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
-                return CAIRO_STATUS_NO_MEMORY;
-	    }
+            if (!rect)
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
             *rect = rects[n];
             
             scaled_glyph->surface_private = rect;
@@ -1359,10 +1358,8 @@ _directfb_acquire_font_cache (cairo_dire
                         "Reallocating font cache (%dx%d).\n", w, h);
             
             new_cache = _directfb_allocate_font_cache (surface->dfb, w, h);
-            if (!new_cache) {
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
-                return CAIRO_STATUS_NO_MEMORY;
-	    }
+            if (!new_cache)
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
             
             new_cache->dfbsurface->Blit (new_cache->dfbsurface,
                                      cache->dfbsurface, NULL, 0, 0);
@@ -1376,10 +1373,8 @@ _directfb_acquire_font_cache (cairo_dire
                     "Allocating font cache (%dx%d).\n", w, h);
         
         cache = _directfb_allocate_font_cache (surface->dfb, w, h);
-	if (!cache) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (!cache)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
             
         scaled_font->surface_backend = &cairo_directfb_surface_backend;
         scaled_font->surface_private = cache;
@@ -1391,7 +1386,7 @@ _directfb_acquire_font_cache (cairo_dire
     
         if (cache->dfbsurface->Lock (cache->dfbsurface, 
                                  DSLF_WRITE, (void *)&data, &pitch))
-            return CAIRO_STATUS_NO_MEMORY;
+            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     
         for (i = 0; i < num_chars; i++) {
             cairo_image_surface_t *img  = chars[i]->surface;
@@ -1642,7 +1637,7 @@ cairo_directfb_surface_create (IDirectFB
         
     surface = calloc (1, sizeof(cairo_directfb_surface_t));
     if (!surface) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
         
diff --git a/src/cairo-font-face.c b/src/cairo-font-face.c
index b3bcc84..0285b52 100644
--- a/src/cairo-font-face.c
+++ b/src/cairo-font-face.c
@@ -231,7 +231,7 @@ cairo_font_face_set_user_data (cairo_fon
 			       cairo_destroy_func_t	    destroy)
 {
     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return _cairo_user_data_array_set_data (&font_face->user_data,
 					    key, user_data, destroy);
@@ -321,7 +321,7 @@ _cairo_toy_font_face_init (cairo_toy_fon
 
     family_copy = strdup (family);
     if (family_copy == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     _cairo_toy_font_face_init_key (font_face, family_copy,
 				      slant, weight);
@@ -396,7 +396,7 @@ _cairo_toy_font_face_create (const char 
     /* Otherwise create it and insert into hash table. */
     font_face = malloc (sizeof (cairo_toy_font_face_t));
     if (font_face == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto UNWIND_HASH_TABLE_LOCK;
     }
 
diff --git a/src/cairo-font-options.c b/src/cairo-font-options.c
index b3a5660..c5d5c12 100644
--- a/src/cairo-font-options.c
+++ b/src/cairo-font-options.c
@@ -90,7 +90,7 @@ cairo_font_options_create (void)
 
     options = malloc (sizeof (cairo_font_options_t));
     if (!options) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_font_options_t *)&_cairo_font_options_nil;
     }
 
@@ -123,7 +123,7 @@ cairo_font_options_copy (const cairo_fon
 
     options = malloc (sizeof (cairo_font_options_t));
     if (!options) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_font_options_t *)&_cairo_font_options_nil;
     }
 
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 753810a..7768a77 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -177,7 +177,7 @@ _cairo_ft_unscaled_font_map_create (void
 
     font_map = malloc (sizeof (cairo_ft_unscaled_font_map_t));
     if (font_map == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	goto FAIL;
     }
 
@@ -257,7 +257,7 @@ _cairo_ft_unscaled_font_map_lock (void)
 
 	if (cairo_ft_unscaled_font_map == NULL) {
 	    CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	    return NULL;
 	}
     }
@@ -330,10 +330,8 @@ _cairo_ft_unscaled_font_init (cairo_ft_u
 	unscaled->face = NULL;
 
 	filename_copy = strdup (filename);
-	if (filename_copy == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (filename_copy == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	_cairo_ft_unscaled_font_init_key (unscaled, filename_copy, id);
     }
@@ -426,7 +424,7 @@ _cairo_ft_unscaled_font_create_for_patte
     /* Otherwise create it and insert into hash table. */
     unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
     if (unscaled == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	goto UNWIND_FONT_MAP_LOCK;
     }
 
@@ -461,7 +459,7 @@ _cairo_ft_unscaled_font_create_from_face
 
     unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
     if (unscaled == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -560,7 +558,7 @@ _cairo_ft_unscaled_font_lock_face (cairo
     {
 	unscaled->lock_count--;
 	CAIRO_MUTEX_UNLOCK (unscaled->mutex);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -666,10 +664,8 @@ _cairo_ft_unscaled_font_set_scale (cairo
 				  sf.x_scale * 64.0,
 				  sf.y_scale * 64.0,
 				  0, 0);
-	if (error) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (error)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     } else {
 	double min_distance = DBL_MAX;
 	int i;
@@ -698,10 +694,8 @@ _cairo_ft_unscaled_font_set_scale (cairo
 	    error = FT_Set_Pixel_Sizes (unscaled->face,
 					unscaled->face->available_sizes[best_i].width,
 					unscaled->face->available_sizes[best_i].height);
-	if (error) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (error)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     return CAIRO_STATUS_SUCCESS;
@@ -755,10 +749,8 @@ _get_bitmap_surface (FT_Bitmap		     *bi
 	    assert (stride == bitmap->pitch);
 	} else {
 	    data = _cairo_malloc_ab (height, stride);
-	    if (!data) {
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
-		return CAIRO_STATUS_NO_MEMORY;
-	    }
+	    if (!data)
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	    if (stride == bitmap->pitch) {
 		memcpy (data, bitmap->buffer, stride * height);
@@ -805,10 +797,9 @@ _get_bitmap_surface (FT_Bitmap		     *bi
 		data = bitmap->buffer;
 	    } else {
 		data = _cairo_malloc_ab (height, stride);
-		if (!data) {
-		    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-		    return CAIRO_STATUS_NO_MEMORY;
-		}
+		if (!data)
+		    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
 		memcpy (data, bitmap->buffer, stride * height);
 	    }
 	    format = CAIRO_FORMAT_A8;
@@ -850,8 +841,7 @@ _get_bitmap_surface (FT_Bitmap		     *bi
 	    if (data_rgba == NULL) {
 		if (own_buffer)
 		    free (bitmap->buffer);
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
-		return CAIRO_STATUS_NO_MEMORY;
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    }
 
 	    os = 1;
@@ -919,8 +909,7 @@ _get_bitmap_surface (FT_Bitmap		     *bi
     default:
 	if (own_buffer)
 	    free (bitmap->buffer);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     *surface = (cairo_image_surface_t *)
@@ -929,7 +918,7 @@ _get_bitmap_surface (FT_Bitmap		     *bi
 					     width, height, stride);
     if ((*surface)->base.status) {
 	free (data);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     if (subpixel)
@@ -1002,7 +991,7 @@ _render_glyph_outline (FT_Face          
 	(*surface) = (cairo_image_surface_t *)
 	    cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
 	if ((*surface)->base.status)
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return (*surface)->base.status;
     } else  {
 
 	matrix.xx = matrix.yy = 0x10000L;
@@ -1049,16 +1038,14 @@ _render_glyph_outline (FT_Face          
 	bitmap.rows = height * vmul;
 	bitmap.buffer = calloc (stride, bitmap.rows);
 	if (bitmap.buffer == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 
 	FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
 
 	if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {
 	    free (bitmap.buffer);
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 
 	status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
@@ -1099,10 +1086,8 @@ _render_glyph_bitmap (FT_Face		      fac
     error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_NORMAL);
     /* XXX ignoring all other errors for now.  They are not fatal, typically
      * just a glyph-not-found. */
-    if (error == FT_Err_Out_Of_Memory) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (error == FT_Err_Out_Of_Memory)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
     if (status)
@@ -1199,7 +1184,7 @@ _transform_glyph_bitmap (cairo_matrix_t 
     width = (width + 3) & ~3;
     image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
     if (image->status)
-	return CAIRO_STATUS_NO_MEMORY;
+	return image->status;
 
     /* Initialize it to empty
      */
@@ -1486,7 +1471,7 @@ _cairo_ft_scaled_font_create (cairo_ft_u
     scaled_font = malloc (sizeof(cairo_ft_scaled_font_t));
     if (scaled_font == NULL) {
 	_cairo_ft_unscaled_font_unlock_face (unscaled);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -1596,10 +1581,8 @@ _cairo_ft_scaled_font_create_toy (cairo_
     unsigned char *family = (unsigned char*) toy_face->family;
 
     pattern = FcPatternCreate ();
-    if (!pattern) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (!pattern)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     switch (toy_face->weight)
     {
@@ -1668,10 +1651,8 @@ _cairo_ft_scaled_font_create_toy (cairo_
     if (new_font) {
 	*font = new_font;
 	return CAIRO_STATUS_SUCCESS;
-    } else {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    } else
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 }
 
 static void
@@ -1804,7 +1785,7 @@ _decompose_glyph_outline (FT_Face		  fac
 
     path = _cairo_path_fixed_create ();
     if (!path)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     glyph = face->glyph;
 
@@ -1812,8 +1793,7 @@ _decompose_glyph_outline (FT_Face		  fac
     FT_Outline_Transform (&glyph->outline, &invert_y);
     if (FT_Outline_Decompose (&glyph->outline, &outline_funcs, path)) {
 	_cairo_path_fixed_destroy (path);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     status = _cairo_path_fixed_close_path (path);
@@ -1868,7 +1848,7 @@ _cairo_ft_scaled_glyph_init (void			*abs
 
     face = _cairo_ft_unscaled_font_lock_face (unscaled);
     if (!face)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
 				                &scaled_font->base.scale);
@@ -1897,7 +1877,7 @@ _cairo_ft_scaled_glyph_init (void			*abs
     /* XXX ignoring all other errors for now.  They are not fatal, typically
      * just a glyph-not-found. */
     if (error == FT_Err_Out_Of_Memory) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto FAIL;
     }
 
@@ -2036,7 +2016,7 @@ _cairo_ft_scaled_glyph_init (void			*abs
     }
 
     if (info & CAIRO_SCALED_GLYPH_INFO_PATH) {
-	cairo_path_fixed_t *path;
+	cairo_path_fixed_t *path = NULL; /* hide compiler warning */
 
 	/*
 	 * A kludge -- the above code will trash the outline,
@@ -2049,9 +2029,8 @@ _cairo_ft_scaled_glyph_init (void			*abs
 	    /* XXX ignoring all other errors for now.  They are not fatal, typically
 	     * just a glyph-not-found. */
 	    if (error == FT_Err_Out_Of_Memory) {
-		_cairo_ft_unscaled_font_unlock_face (unscaled);
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
-		return CAIRO_STATUS_NO_MEMORY;
+		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+		goto FAIL;
 	    }
 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
 	    /*
@@ -2118,7 +2097,7 @@ _cairo_ft_load_truetype_table (void	    
 #if HAVE_FT_LOAD_SFNT_TABLE
     face = _cairo_ft_unscaled_font_lock_face (unscaled);
     if (!face)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (FT_IS_SFNT (face) &&
 	FT_Load_Sfnt_Table (face, tag, offset, buffer, length) == 0)
@@ -2260,12 +2239,10 @@ _cairo_ft_font_face_scaled_font_create (
 						 &font_face->base,
 						 font_matrix, ctm,
 						 options, ft_options);
-    if (*scaled_font) {
+    if (*scaled_font)
 	return CAIRO_STATUS_SUCCESS;
-    } else {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    else
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 }
 
 static const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
@@ -2301,7 +2278,7 @@ _cairo_ft_font_face_create (cairo_ft_uns
     /* No match found, create a new one */
     font_face = malloc (sizeof (cairo_ft_font_face_t));
     if (!font_face) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -2451,7 +2428,7 @@ cairo_ft_font_face_create_for_pattern (F
 
     unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern);
     if (unscaled == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_font_face_t *)&_cairo_font_face_nil;
     }
 
@@ -2501,7 +2478,7 @@ cairo_ft_font_face_create_for_ft_face (F
 
     unscaled = _cairo_ft_unscaled_font_create_from_face (face);
     if (unscaled == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_font_face_t *)&_cairo_font_face_nil;
     }
 
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index 4d781cf..83a5109 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -89,7 +89,7 @@ _cairo_glitz_surface_create_similar (voi
 	glitz_find_standard_format (drawable,
 				    _glitz_format_from_content (content));
     if (!gformat) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -99,7 +99,7 @@ _cairo_glitz_surface_create_similar (voi
 				    0, NULL);
 
     if (surface == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -166,7 +166,7 @@ _cairo_glitz_get_boxes_from_region (cair
 
     gboxes = _cairo_malloc_ab (n, sizeof(glitz_box_t));
     if (gboxes == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
         goto done;
     }
 
@@ -271,16 +271,13 @@ _cairo_glitz_surface_get_image (cairo_gl
     pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
 
     pixels = _cairo_malloc_ab (height, pf.bytes_per_line);
-    if (!pixels) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (!pixels)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     buffer = glitz_buffer_create_for_data (pixels);
     if (!buffer) {
 	free (pixels);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     /* clear out the glitz clip; the clip affects glitz_get_pixels */
@@ -304,7 +301,7 @@ _cairo_glitz_surface_get_image (cairo_gl
         box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
         if (box == NULL && n != 0) {
             free (pixels);
-            return CAIRO_STATUS_NO_MEMORY;
+            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
         }
 
 	glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
@@ -350,7 +347,7 @@ _cairo_glitz_surface_get_image (cairo_gl
 
 FAIL:
     free (pixels);
-    return CAIRO_STATUS_NO_MEMORY;
+    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 }
 
 static void
@@ -433,7 +430,7 @@ _cairo_glitz_surface_set_image (void		  
 
     buffer = glitz_buffer_create_for_data (data);
     if (!buffer)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     glitz_set_pixels (surface->surface,
 		      x_dst, y_dst,
@@ -539,7 +536,7 @@ _cairo_glitz_surface_clone_similar (void
 						 image_src->width,
 						 image_src->height);
 	if (clone->base.status)
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return clone->base.status;
 
 	image_extent.x = 0;
 	image_extent.y = 0;
@@ -769,32 +766,28 @@ _cairo_glitz_pattern_acquire_surface (ca
             int size1, size2;
             if (n_params >= INT32_MAX / sizeof (glitz_fixed16_16_t) ||
                 gradient->n_stops >= INT32_MAX / sizeof (unsigned int))
-                return CAIRO_STATUS_NO_MEMORY;
+                return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
             size1 = n_params * sizeof (glitz_fixed16_16_t);
             size2 = gradient->n_stops * sizeof (unsigned int);
 
             if (size1 >= INT32_MAX - size2)
-                return CAIRO_STATUS_NO_MEMORY;
+                return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
             data = malloc (size1 + size2);
         }
 
-	if (!data) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (!data)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	params = (glitz_fixed16_16_t *) data;
 	pixels = (unsigned int *)
 	    (data + sizeof (glitz_fixed16_16_t) * n_params);
 
 	buffer = glitz_buffer_create_for_data (pixels);
-	if (!buffer)
-	{
+	if (!buffer) {
 	    free (data);
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 
 	src = (cairo_glitz_surface_t *)
@@ -805,7 +798,7 @@ _cairo_glitz_pattern_acquire_surface (ca
 	{
 	    glitz_buffer_destroy (buffer);
 	    free (data);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return src->base.status;
 	}
 
 	for (i = 0; i < gradient->n_stops; i++)
@@ -1166,7 +1159,7 @@ _cairo_glitz_surface_fill_rectangles (vo
 						 (cairo_color_t *) color,
 						 NULL);
 	if (src->base.status)
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return src->base.status;
 
 	glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT);
 
@@ -1285,7 +1278,7 @@ _cairo_glitz_surface_composite_trapezoid
 	    if (src_pattern == &tmp_src_pattern.base)
 		_cairo_pattern_fini (&tmp_src_pattern.base);
 
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return mask->base.status;
 	}
 
 	color.red = color.green = color.blue = color.alpha = 0xffff;
@@ -1312,8 +1305,7 @@ _cairo_glitz_surface_composite_trapezoid
 							  &attributes);
 		    if (src_pattern == &tmp_src_pattern.base)
 			_cairo_pattern_fini (&tmp_src_pattern.base);
-		    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-		    return CAIRO_STATUS_NO_MEMORY;
+		    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		}
 
 		if (buffer)
@@ -1326,8 +1318,7 @@ _cairo_glitz_surface_composite_trapezoid
 							  &attributes);
 		    if (src_pattern == &tmp_src_pattern.base)
 			_cairo_pattern_fini (&tmp_src_pattern.base);
-		    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-		    return CAIRO_STATUS_NO_MEMORY;
+		    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		}
 	    }
 
@@ -1363,8 +1354,7 @@ _cairo_glitz_surface_composite_trapezoid
 	    _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
 	    if (src_pattern == &tmp_src_pattern.base)
 		_cairo_pattern_fini (&tmp_src_pattern.base);
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 
 	/* using negative stride */
@@ -1379,7 +1369,7 @@ _cairo_glitz_surface_composite_trapezoid
 	{
 	    cairo_surface_destroy (&src->base);
 	    free (data);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return image->base.status;
 	}
 
 	pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y,
@@ -1394,7 +1384,7 @@ _cairo_glitz_surface_composite_trapezoid
 	    _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes);
 	    free (data);
 	    cairo_surface_destroy (&image->base);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return mask->base.status;
 	}
 
 	_cairo_glitz_surface_set_image (mask, image, 0, 0, width, height, 0, 0);
@@ -1449,24 +1439,25 @@ _cairo_glitz_surface_set_clip_region (vo
     {
 	glitz_box_t *box;
 	int	    n;
+	cairo_status_t status;
 
 	if (!surface->has_clip) {
             _cairo_region_init (&surface->clip);
             surface->has_clip = TRUE;
         }
 
-	if (_cairo_region_copy (&surface->clip, region) != CAIRO_STATUS_SUCCESS)
-        {
+	status = _cairo_region_copy (&surface->clip, region);
+	if (status) {
             _cairo_region_fini (&surface->clip);
 	    surface->has_clip = FALSE;
-            return CAIRO_STATUS_NO_MEMORY;
+            return status;
         }
 
         box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
         if (box == NULL && n != 0) {
             _cairo_region_fini (&surface->clip);
 	    surface->has_clip = FALSE;
-            return CAIRO_STATUS_NO_MEMORY;
+            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
         }
 
 	glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
@@ -1577,7 +1568,7 @@ _cairo_glitz_area_create (cairo_glitz_ro
 
     area = malloc (sizeof (cairo_glitz_area_t));
     if (!area) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -1801,7 +1792,7 @@ _cairo_glitz_root_area_init (cairo_glitz
 
     root->area = _cairo_glitz_area_create (root, 0, 0, 0, width, height);
     if (!root->area)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1913,10 +1904,8 @@ _cairo_glitz_surface_font_init (cairo_gl
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     font_private = malloc (sizeof (cairo_glitz_surface_font_private_t));
-    if (!font_private) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (!font_private)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     font_private->surface = glitz_surface_create (drawable, surface_format,
 						  GLYPH_CACHE_TEXTURE_SIZE,
@@ -2001,10 +1990,8 @@ _cairo_glitz_surface_add_glyph (cairo_gl
     if (glyph_private == NULL)
     {
 	glyph_private = malloc (sizeof (cairo_glitz_surface_glyph_private_t));
-	if (!glyph_private) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (!glyph_private)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	glyph_private->area   = NULL;
 	glyph_private->locked = FALSE;
@@ -2048,7 +2035,7 @@ _cairo_glitz_surface_add_glyph (cairo_gl
     if (!buffer)
     {
 	_cairo_glitz_area_move_out (glyph_private->area);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     cairo_format_get_masks (glyph_surface->format, &bpp, &am, &rm, &gm, &bm);
@@ -2169,7 +2156,7 @@ _cairo_glitz_surface_old_show_glyphs (ca
 
 	data = malloc (size1 + size2);
 	if (!data) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	    goto FAIL1;
 	}
 
@@ -2459,7 +2446,7 @@ cairo_glitz_surface_create (glitz_surfac
 
     crsurface = malloc (sizeof (cairo_glitz_surface_t));
     if (crsurface == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 4097a65..b1fc6b3 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -94,7 +94,7 @@ _cairo_gstate_init (cairo_gstate_t  *gst
     gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK,
 						  CAIRO_CONTENT_COLOR);
     if (gstate->source->status)
-	return CAIRO_STATUS_NO_MEMORY;
+	return gstate->source->status;
 
     return target ? target->status : CAIRO_STATUS_NULL_POINTER;
 }
@@ -208,7 +208,7 @@ _cairo_gstate_clone (cairo_gstate_t *oth
 
     gstate = malloc (sizeof (cairo_gstate_t));
     if (gstate == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -235,10 +235,8 @@ _cairo_gstate_save (cairo_gstate_t **gst
     cairo_gstate_t *top;
 
     top = _cairo_gstate_clone (*gstate);
-
-    if (top == NULL) {
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (top == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     top->next = *gstate;
     *gstate = top;
@@ -258,10 +256,8 @@ _cairo_gstate_restore (cairo_gstate_t **
     cairo_gstate_t *top;
 
     top = *gstate;
-
-    if (top->next == NULL) {
-	return CAIRO_STATUS_INVALID_RESTORE;
-    }
+    if (top->next == NULL)
+	return _cairo_error (CAIRO_STATUS_INVALID_RESTORE);
 
     *gstate = top->next;
 
@@ -535,8 +531,7 @@ _cairo_gstate_set_dash (cairo_gstate_t *
     gstate->stroke_style.dash = _cairo_malloc_ab (gstate->stroke_style.num_dashes, sizeof (double));
     if (gstate->stroke_style.dash == NULL) {
 	gstate->stroke_style.num_dashes = 0;
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     memcpy (gstate->stroke_style.dash, dash, gstate->stroke_style.num_dashes * sizeof (double));
@@ -544,12 +539,12 @@ _cairo_gstate_set_dash (cairo_gstate_t *
     dash_total = 0.0;
     for (i = 0; i < gstate->stroke_style.num_dashes; i++) {
 	if (gstate->stroke_style.dash[i] < 0)
-	    return CAIRO_STATUS_INVALID_DASH;
+	    return _cairo_error (CAIRO_STATUS_INVALID_DASH);
 	dash_total += gstate->stroke_style.dash[i];
     }
 
     if (dash_total == 0.0)
-	return CAIRO_STATUS_INVALID_DASH;
+	return _cairo_error (CAIRO_STATUS_INVALID_DASH);
 
     /* A single dash value indicate symmetric repeating, so the total
      * is twice as long. */
@@ -626,7 +621,7 @@ _cairo_gstate_scale (cairo_gstate_t *gst
     cairo_matrix_t tmp;
 
     if (sx == 0 || sy == 0)
-	return CAIRO_STATUS_INVALID_MATRIX;
+	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
 
     _cairo_gstate_unset_scaled_font (gstate);
 
@@ -1576,10 +1571,8 @@ _cairo_gstate_show_glyphs (cairo_gstate_
 	transformed_glyphs = stack_transformed_glyphs;
     } else {
 	transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
-	if (transformed_glyphs == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (transformed_glyphs == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     _cairo_gstate_transform_glyphs_to_backend (gstate, glyphs, num_glyphs,
@@ -1623,10 +1616,8 @@ _cairo_gstate_glyph_path (cairo_gstate_t
       transformed_glyphs = stack_transformed_glyphs;
     else
       transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
-    if (transformed_glyphs == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (transformed_glyphs == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     _cairo_gstate_transform_glyphs_to_backend (gstate, glyphs, num_glyphs,
                                                transformed_glyphs);
diff --git a/src/cairo-hash.c b/src/cairo-hash.c
index 7051860..c419e9e 100644
--- a/src/cairo-hash.c
+++ b/src/cairo-hash.c
@@ -150,7 +150,7 @@ _cairo_hash_table_create (cairo_hash_key
 
     hash_table = malloc (sizeof (cairo_hash_table_t));
     if (hash_table == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -161,8 +161,8 @@ _cairo_hash_table_create (cairo_hash_key
     hash_table->entries = calloc (hash_table->arrangement->size,
 				  sizeof(cairo_hash_entry_t *));
     if (hash_table->entries == NULL) {
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	free (hash_table);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -331,10 +331,8 @@ _cairo_hash_table_resize  (cairo_hash_ta
 
     new_size = tmp.arrangement->size;
     tmp.entries = calloc (new_size, sizeof (cairo_hash_entry_t*));
-    if (tmp.entries == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (tmp.entries == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     for (i = 0; i < hash_table->arrangement->size; ++i) {
 	if (ENTRY_IS_LIVE (hash_table->entries[i])) {
diff --git a/src/cairo-hull.c b/src/cairo-hull.c
index f5d05e4..9eed671 100644
--- a/src/cairo-hull.c
+++ b/src/cairo-hull.c
@@ -64,7 +64,7 @@ _cairo_hull_create (cairo_pen_vertex_t *
 
     hull = _cairo_malloc_ab (num_vertices, sizeof (cairo_hull_t));
     if (hull == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 091a957..3331e55 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -214,7 +214,7 @@ _cairo_image_surface_create_for_pixman_i
 
     surface = malloc (sizeof (cairo_image_surface_t));
     if (surface == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -433,7 +433,7 @@ _cairo_image_surface_create_with_pixman_
 					     (uint32_t *) data, stride);
 
     if (pixman_image == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -475,7 +475,7 @@ cairo_image_surface_create (cairo_format
     pixman_format_code_t pixman_format;
 
     if (! CAIRO_FORMAT_VALID (format)) {
-	_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
+	_cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT);
 	return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_format;
     }
 
@@ -494,7 +494,7 @@ _cairo_image_surface_create_with_content
 					  int			height)
 {
     if (! CAIRO_CONTENT_VALID (content)) {
-	_cairo_error (CAIRO_STATUS_INVALID_CONTENT);
+	_cairo_error_throw (CAIRO_STATUS_INVALID_CONTENT);
 	return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_content;
     }
 
@@ -545,7 +545,7 @@ cairo_image_surface_create_for_data (uns
      * attempting to create such surfaces will failure but we will interpret
      * such failure as CAIRO_STATUS_NO_MEMORY.  */
     if (! CAIRO_FORMAT_VALID (format) || stride % sizeof (uint32_t) != 0) {
-	_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
+	_cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT);
 	return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_format;
     }
 
@@ -564,7 +564,7 @@ _cairo_image_surface_create_for_data_wit
 						   int			 stride)
 {
     if (! CAIRO_CONTENT_VALID (content)) {
-	_cairo_error (CAIRO_STATUS_INVALID_CONTENT);
+	_cairo_error_throw (CAIRO_STATUS_INVALID_CONTENT);
 	return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_content;
     }
 
@@ -591,7 +591,7 @@ cairo_image_surface_get_data (cairo_surf
     cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
 
     if (!_cairo_surface_is_image (surface)) {
-	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return NULL;
     }
 
@@ -614,7 +614,7 @@ cairo_image_surface_get_format (cairo_su
     cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
 
     if (!_cairo_surface_is_image (surface)) {
-	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return 0;
     }
 
@@ -637,7 +637,7 @@ cairo_image_surface_get_width (cairo_sur
     cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
 
     if (!_cairo_surface_is_image (surface)) {
-	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return 0;
     }
 
@@ -659,7 +659,7 @@ cairo_image_surface_get_height (cairo_su
     cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
 
     if (!_cairo_surface_is_image (surface)) {
-	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return 0;
     }
 
@@ -687,7 +687,7 @@ cairo_image_surface_get_stride (cairo_su
     cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface;
 
     if (!_cairo_surface_is_image (surface)) {
-	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return 0;
     }
 
@@ -839,7 +839,7 @@ _cairo_image_surface_set_matrix (cairo_i
     _cairo_matrix_to_pixman_matrix (matrix, &pixman_transform);
 
     if (!pixman_image_set_transform (surface->pixman_image, &pixman_transform))
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1062,10 +1062,8 @@ _cairo_image_surface_fill_rectangles (vo
 
     if (num_rects > ARRAY_LENGTH(stack_rects)) {
 	pixman_rects = _cairo_malloc_ab (num_rects, sizeof(pixman_rectangle16_t));
-	if (pixman_rects == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (pixman_rects == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }		 
 
     for (i = 0; i < num_rects; i++) {
@@ -1081,8 +1079,7 @@ _cairo_image_surface_fill_rectangles (vo
 				       &pixman_color,
 				       num_rects,
 				       pixman_rects)) {
-	status = CAIRO_STATUS_NO_MEMORY;
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     if (pixman_rects != stack_rects)
@@ -1128,10 +1125,8 @@ _cairo_image_surface_composite_trapezoid
     /* Convert traps to pixman traps */
     if (num_traps > ARRAY_LENGTH(stack_traps)) {
 	pixman_traps = _cairo_malloc_ab (num_traps, sizeof(pixman_trapezoid_t));
-	if (pixman_traps == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (pixman_traps == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     for (i = 0; i < num_traps; i++) {
@@ -1206,16 +1201,14 @@ _cairo_image_surface_composite_trapezoid
     /* The image must be initially transparent */
     mask_data = calloc (mask_stride, height);
     if (mask_data == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP_SOURCE;
     }
 
     mask = pixman_image_create_bits (format, width, height,
 				     mask_data, mask_stride);
     if (mask == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP_IMAGE_DATA;
     }
 
@@ -1263,7 +1256,7 @@ _cairo_image_surface_set_clip_region (vo
     cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
 
     if (!pixman_image_set_clip_region (surface->pixman_image, &region->rgn))
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     surface->has_clip = region != NULL;
 
diff --git a/src/cairo-lzw.c b/src/cairo-lzw.c
index 73d82a3..6158eaf 100644
--- a/src/cairo-lzw.c
+++ b/src/cairo-lzw.c
@@ -75,8 +75,7 @@ _lzw_buf_init (lzw_buf_t *buf, int size)
     buf->data = malloc (size);
     if (buf->data == NULL) {
 	buf->data_size = 0;
-	buf->status = CAIRO_STATUS_NO_MEMORY;
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	buf->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return;
     }
 }
@@ -102,8 +101,7 @@ _lzw_buf_grow (lzw_buf_t *buf)
     if (new_data == NULL) {
 	free (buf->data);
 	buf->data_size = 0;
-	buf->status = CAIRO_STATUS_NO_MEMORY;
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	buf->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return buf->status;
     }
 
diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index 17b11ef..cf31c5d 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -473,11 +473,11 @@ cairo_matrix_invert (cairo_matrix_t *mat
     _cairo_matrix_compute_determinant (matrix, &det);
 
     if (det == 0)
-	return CAIRO_STATUS_INVALID_MATRIX;
+	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
 
     /* this weird construct is for detecting NaNs */
     if (! (det * det > 0.))
-	return CAIRO_STATUS_INVALID_MATRIX;
+	return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
 
     _cairo_matrix_compute_adjoint (matrix);
     _cairo_matrix_scalar_multiply (matrix, 1 / det);
diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index ac43be9..d353d2e 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -85,7 +85,7 @@ _cairo_meta_surface_create (cairo_conten
 
     meta = malloc (sizeof (cairo_meta_surface_t));
     if (meta == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -252,10 +252,8 @@ _cairo_meta_surface_paint (void			*abstr
     cairo_command_paint_t *command;
 
     command = malloc (sizeof (cairo_command_paint_t));
-    if (command == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (command == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     command->header.type = CAIRO_COMMAND_PAINT;
     command->header.region = CAIRO_META_REGION_ALL;
@@ -295,10 +293,8 @@ _cairo_meta_surface_mask (void			*abstra
     cairo_command_mask_t *command;
 
     command = malloc (sizeof (cairo_command_mask_t));
-    if (command == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (command == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     command->header.type = CAIRO_COMMAND_MASK;
     command->header.region = CAIRO_META_REGION_ALL;
@@ -343,10 +339,8 @@ _cairo_meta_surface_stroke (void			*abst
     cairo_command_stroke_t *command;
 
     command = malloc (sizeof (cairo_command_stroke_t));
-    if (command == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (command == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     command->header.type = CAIRO_COMMAND_STROKE;
     command->header.region = CAIRO_META_REGION_ALL;
@@ -400,10 +394,8 @@ _cairo_meta_surface_fill (void			*abstra
     cairo_command_fill_t *command;
 
     command = malloc (sizeof (cairo_command_fill_t));
-    if (command == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (command == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     command->header.type = CAIRO_COMMAND_FILL;
     command->header.region = CAIRO_META_REGION_ALL;
@@ -449,10 +441,8 @@ _cairo_meta_surface_show_glyphs (void			
     cairo_command_show_glyphs_t *command;
 
     command = malloc (sizeof (cairo_command_show_glyphs_t));
-    if (command == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (command == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     command->header.type = CAIRO_COMMAND_SHOW_GLYPHS;
     command->header.region = CAIRO_META_REGION_ALL;
@@ -464,7 +454,7 @@ _cairo_meta_surface_show_glyphs (void			
 
     command->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
     if (command->glyphs == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP_SOURCE;
     }
     memcpy (command->glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
@@ -486,8 +476,7 @@ _cairo_meta_surface_show_glyphs (void			
     _cairo_pattern_fini (&command->source.base);
   CLEANUP_COMMAND:
     free (command);
-    _cairo_error (status);
-    return status;
+    return _cairo_error (status);
 }
 
 /**
@@ -511,7 +500,7 @@ _cairo_meta_surface_snapshot (void *abst
 
     meta = malloc (sizeof (cairo_meta_surface_t));
     if (meta == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -542,10 +531,8 @@ _cairo_meta_surface_intersect_clip_path 
     cairo_status_t status;
 
     command = malloc (sizeof (cairo_command_intersect_clip_path_t));
-    if (command == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (command == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     command->header.type = CAIRO_COMMAND_INTERSECT_CLIP_PATH;
     command->header.region = CAIRO_META_REGION_ALL;
@@ -811,8 +798,7 @@ _cairo_meta_surface_replay_internal (cai
 	    if (has_device_transform) {
 		dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
 		if (dev_glyphs == NULL) {
-		    status = CAIRO_STATUS_NO_MEMORY;
-		    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+		    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		    break;
 		}
 		for (i = 0; i < num_glyphs; i++) {
diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c
index b448887..0d888ed 100644
--- a/src/cairo-os2-surface.c
+++ b/src/cairo-os2-surface.c
@@ -473,7 +473,7 @@ _cairo_os2_surface_acquire_source_image 
         (local_os2_surface->base.backend != &cairo_os2_surface_backend))
     {
         /* Invalid parameter (wrong surface)! */
-        return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+        return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
     }
 
     DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT);
@@ -529,7 +529,7 @@ _cairo_os2_surface_acquire_dest_image (v
         (local_os2_surface->base.backend != &cairo_os2_surface_backend))
     {
         /* Invalid parameter (wrong surface)! */
-        return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+        return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
     }
 
     DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT);
@@ -637,7 +637,7 @@ _cairo_os2_surface_get_extents (void    
         (local_os2_surface->base.backend != &cairo_os2_surface_backend))
     {
         /* Invalid parameter (wrong surface)! */
-        return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+        return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
     }
 
     rectangle->x = 0;
@@ -773,14 +773,14 @@ cairo_os2_surface_set_size (cairo_surfac
         (local_os2_surface->base.backend != &cairo_os2_surface_backend))
     {
         /* Invalid parameter (wrong surface)! */
-        return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+        return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
     }
 
     if ((new_width <= 0) ||
         (new_height <= 0))
     {
         /* Invalid size! */
-        return CAIRO_STATUS_NO_MEMORY;
+        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     /* Allocate memory for new stuffs */
@@ -789,7 +789,7 @@ cairo_os2_surface_set_size (cairo_surfac
         /* Not enough memory for the pixels!
          * Everything remains the same!
          */
-        return CAIRO_STATUS_NO_MEMORY;
+        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     /* This is possibly not needed, malloc'd space is usually
@@ -812,7 +812,7 @@ cairo_os2_surface_set_size (cairo_surfac
          * Everything remains the same!
          */
         free (pchNewPixels);
-        return CAIRO_STATUS_NO_MEMORY;
+        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     /* Okay, new memory allocated, so it's time to swap old buffers
@@ -824,7 +824,7 @@ cairo_os2_surface_set_size (cairo_surfac
          */
         cairo_surface_destroy ((cairo_surface_t *) pNewImageSurface);
         free (pchNewPixels);
-        return CAIRO_STATUS_NO_MEMORY;
+        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     /* We have to make sure that we won't destroy a surface which
@@ -840,7 +840,7 @@ cairo_os2_surface_set_size (cairo_surfac
             /* Either timeout or something wrong... Exit. */
             cairo_surface_destroy ((cairo_surface_t *) pNewImageSurface);
             free (pchNewPixels);
-            return CAIRO_STATUS_NO_MEMORY;
+            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
         }
         /* Okay, grab mutex and check counter again! */
         if (DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT)
@@ -851,7 +851,7 @@ cairo_os2_surface_set_size (cairo_surfac
              */
             cairo_surface_destroy ((cairo_surface_t *) pNewImageSurface);
             free (pchNewPixels);
-            return CAIRO_STATUS_NO_MEMORY;
+            return _cairo_error (CAIRO_STATUS_NO_MEMORY);
         }
     }
 
@@ -949,7 +949,7 @@ _cairo_os2_surface_finish (void *abstrac
         (local_os2_surface->base.backend != &cairo_os2_surface_backend))
     {
         /* Invalid parameter (wrong surface)! */
-        return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+        return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
     }
 
     DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT);
@@ -1042,7 +1042,7 @@ _cairo_os2_surface_mark_dirty_rectangle 
         (local_os2_surface->base.backend != &cairo_os2_surface_backend))
     {
         /* Invalid parameter (wrong surface)! */
-        return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+        return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
     }
 
     /* Get mutex, we'll work with the pixel array! */
diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c
index a0add6d..791c0f2 100644
--- a/src/cairo-output-stream.c
+++ b/src/cairo-output-stream.c
@@ -120,7 +120,7 @@ _cairo_output_stream_create (cairo_write
 
     stream = malloc (sizeof (cairo_output_stream_with_closure_t));
     if (stream == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
     }
 
@@ -164,7 +164,7 @@ _cairo_output_stream_destroy (cairo_outp
     cairo_status_t status;
 
     if (stream == NULL)
-	return CAIRO_STATUS_NULL_POINTER;
+	return _cairo_error (CAIRO_STATUS_NULL_POINTER);
 
     status = _cairo_output_stream_fini (stream);
     free (stream);
@@ -434,7 +434,7 @@ stdio_write (cairo_output_stream_t *base
     stdio_stream_t *stream = (stdio_stream_t *) base;
 
     if (fwrite (data, 1, length, stream->file) != length)
-	return CAIRO_STATUS_WRITE_ERROR;
+	return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -447,7 +447,7 @@ stdio_flush (cairo_output_stream_t *base
     fflush (stream->file);
 
     if (ferror (stream->file))
-	return CAIRO_STATUS_WRITE_ERROR;
+	return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
     else
 	return CAIRO_STATUS_SUCCESS;
 }
@@ -471,13 +471,13 @@ _cairo_output_stream_create_for_file (FI
     stdio_stream_t *stream;
 
     if (file == NULL) {
-	_cairo_error (CAIRO_STATUS_WRITE_ERROR);
+	_cairo_error_throw (CAIRO_STATUS_WRITE_ERROR);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
     }
 
     stream = malloc (sizeof *stream);
     if (stream == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
     }
 
@@ -495,14 +495,14 @@ _cairo_output_stream_create_for_filename
 
     file = fopen (filename, "wb");
     if (file == NULL) {
-	_cairo_error (CAIRO_STATUS_WRITE_ERROR);
+	_cairo_error_throw (CAIRO_STATUS_WRITE_ERROR);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
     }
 
     stream = malloc (sizeof *stream);
     if (stream == NULL) {
 	fclose (file);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
     }
 
@@ -544,7 +544,7 @@ _cairo_memory_stream_create (void)
 
     stream = malloc (sizeof *stream);
     if (stream == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
     }
 
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 76eb661..d7f02f3 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -76,10 +76,8 @@ _cairo_paginated_surface_create (cairo_s
     cairo_paginated_surface_t *surface;
 
     surface = malloc (sizeof (cairo_paginated_surface_t));
-    if (surface == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+    if (surface == NULL)
 	goto FAIL;
-    }
 
     _cairo_surface_init (&surface->base, &cairo_paginated_surface_backend,
 			 content);
@@ -108,7 +106,7 @@ _cairo_paginated_surface_create (cairo_s
   FAIL_CLEANUP_SURFACE:
     free (surface);
   FAIL:
-    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
     return (cairo_surface_t*) &_cairo_surface_nil;
 }
 
@@ -289,7 +287,7 @@ _paint_page (cairo_paginated_surface_t *
     analysis = _cairo_analysis_surface_create (surface->target,
 					       surface->width, surface->height);
     if (analysis == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE);
     status = _cairo_meta_surface_replay_and_create_regions (surface->meta, analysis);
diff --git a/src/cairo-path-fixed.c b/src/cairo-path-fixed.c
index 56b1df2..1ed674e 100644
--- a/src/cairo-path-fixed.c
+++ b/src/cairo-path-fixed.c
@@ -108,7 +108,7 @@ _cairo_path_fixed_init_copy (cairo_path_
 	buf = _cairo_path_buf_create ();
 	if (buf == NULL) {
 	    _cairo_path_fixed_fini (path);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 	memcpy (buf, other_buf, sizeof (cairo_path_buf_t));
 	_cairo_path_fixed_add_buf (path, buf);
@@ -124,7 +124,7 @@ _cairo_path_fixed_create (void)
 
     path = malloc (sizeof (cairo_path_fixed_t));
     if (!path) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -206,7 +206,7 @@ _cairo_path_fixed_rel_move_to (cairo_pat
     cairo_fixed_t x, y;
 
     if (! path->has_current_point)
-	return CAIRO_STATUS_NO_CURRENT_POINT;
+	return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
 
     x = path->current_point.x + dx;
     y = path->current_point.y + dy;
@@ -252,7 +252,7 @@ _cairo_path_fixed_rel_line_to (cairo_pat
     cairo_fixed_t x, y;
 
     if (! path->has_current_point)
-	return CAIRO_STATUS_NO_CURRENT_POINT;
+	return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
 
     x = path->current_point.x + dx;
     y = path->current_point.y + dy;
@@ -302,7 +302,7 @@ _cairo_path_fixed_rel_curve_to (cairo_pa
     cairo_fixed_t x2, y2;
 
     if (! path->has_current_point)
-	return CAIRO_STATUS_NO_CURRENT_POINT;
+	return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
 
     x0 = path->current_point.x + dx0;
     y0 = path->current_point.y + dy0;
@@ -346,7 +346,7 @@ _cairo_path_fixed_get_current_point (cai
 				     cairo_fixed_t	*y)
 {
     if (! path->has_current_point)
-	return CAIRO_STATUS_NO_CURRENT_POINT;
+	return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
 
     *x = path->current_point.x;
     *y = path->current_point.y;
@@ -367,7 +367,7 @@ _cairo_path_fixed_add (cairo_path_fixed_
 
 	buf = _cairo_path_buf_create ();
 	if (buf == NULL)
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	_cairo_path_fixed_add_buf (path, buf);
     }
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index 0a295ba..ce523b0 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -1066,10 +1066,8 @@ _cairo_rectilinear_stroker_add_segment (
 	    new_size = 4;
 	new_segments = _cairo_realloc_ab (stroker->segments,
 	       	                          new_size, sizeof (cairo_line_t));
-	if (new_segments == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (new_segments == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	stroker->segments_size = new_size;
 	stroker->segments = new_segments;
diff --git a/src/cairo-path.c b/src/cairo-path.c
index b1ef44e..90b726d 100644
--- a/src/cairo-path.c
+++ b/src/cairo-path.c
@@ -353,7 +353,7 @@ _cairo_path_create_in_error (cairo_statu
 
     path = malloc (sizeof (cairo_path_t));
     if (path == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_path_t*) &_cairo_path_nil;
     }
 
@@ -373,7 +373,7 @@ _cairo_path_create_internal (cairo_path_
 
     path = malloc (sizeof (cairo_path_t));
     if (path == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_path_t*) &_cairo_path_nil;
     }
 
@@ -390,7 +390,7 @@ _cairo_path_create_internal (cairo_path_
 	       	                       sizeof (cairo_path_data_t));
 	if (path->data == NULL) {
 	    free (path);
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	    return (cairo_path_t*) &_cairo_path_nil;
 	}
 
@@ -496,19 +496,19 @@ _cairo_path_append_to_context (const cai
 	switch (p->header.type) {
 	case CAIRO_PATH_MOVE_TO:
 	    if (p->header.length < 2)
-		return CAIRO_STATUS_INVALID_PATH_DATA;
+		return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
 	    cairo_move_to (cr,
 			   p[1].point.x, p[1].point.y);
 	    break;
 	case CAIRO_PATH_LINE_TO:
 	    if (p->header.length < 2)
-		return CAIRO_STATUS_INVALID_PATH_DATA;
+		return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
 	    cairo_line_to (cr,
 			   p[1].point.x, p[1].point.y);
 	    break;
 	case CAIRO_PATH_CURVE_TO:
 	    if (p->header.length < 4)
-		return CAIRO_STATUS_INVALID_PATH_DATA;
+		return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
 	    cairo_curve_to (cr,
 			    p[1].point.x, p[1].point.y,
 			    p[2].point.x, p[2].point.y,
@@ -516,11 +516,11 @@ _cairo_path_append_to_context (const cai
 	    break;
 	case CAIRO_PATH_CLOSE_PATH:
 	    if (p->header.length < 1)
-		return CAIRO_STATUS_INVALID_PATH_DATA;
+		return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
 	    cairo_close_path (cr);
 	    break;
 	default:
-	    return CAIRO_STATUS_INVALID_PATH_DATA;
+	    return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA);
 	}
 
 	status = cairo_status (cr);
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index a7e804e..6eea9a6 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -77,7 +77,7 @@ const cairo_solid_pattern_t cairo_patter
  * breakpoint in _cairo_error() to generate a stack trace for when the
  * user causes cairo to detect an error.
  **/
-static void
+static cairo_status_t
 _cairo_pattern_set_error (cairo_pattern_t *pattern,
 			  cairo_status_t status)
 {
@@ -85,7 +85,7 @@ _cairo_pattern_set_error (cairo_pattern_
      * error, which is the most significant. */
     _cairo_status_set_error (&pattern->status, status);
 
-    _cairo_error (status);
+    return _cairo_error (status);
 }
 
 static void
@@ -137,8 +137,7 @@ _cairo_gradient_pattern_init_copy (cairo
 	if (pattern->stops == NULL) {
 	    pattern->stops_size = 0;
 	    pattern->n_stops = 0;
-	    _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
 	}
 
 	memcpy (pattern->stops, other->stops,
@@ -152,10 +151,8 @@ cairo_status_t
 _cairo_pattern_init_copy (cairo_pattern_t	*pattern,
 			  const cairo_pattern_t *other)
 {
-    if (other->status) {
-	_cairo_pattern_set_error (pattern, other->status);
-	return other->status;
-    }
+    if (other->status)
+	return _cairo_pattern_set_error (pattern, other->status);
 
     switch (other->type) {
     case CAIRO_PATTERN_TYPE_SOLID: {
@@ -345,7 +342,7 @@ _cairo_pattern_create_in_error (cairo_st
     pattern = _cairo_pattern_create_solid (_cairo_stock_color (CAIRO_STOCK_BLACK),
 					   CAIRO_CONTENT_COLOR);
     if (pattern->status == CAIRO_STATUS_SUCCESS)
-	_cairo_pattern_set_error (pattern, status);
+	status = _cairo_pattern_set_error (pattern, status);
 
     return pattern;
 }
@@ -385,7 +382,7 @@ cairo_pattern_create_rgb (double red, do
     pattern = _cairo_pattern_create_solid (&color,
 					   CAIRO_CONTENT_COLOR);
     if (pattern->status)
-	_cairo_error (pattern->status);
+	_cairo_error_throw (pattern->status);
 
     return pattern;
 }
@@ -429,7 +426,7 @@ cairo_pattern_create_rgba (double red, d
     pattern = _cairo_pattern_create_solid (&color,
 					   CAIRO_CONTENT_COLOR_ALPHA);
     if (pattern->status)
-	_cairo_error (pattern->status);
+	_cairo_error_throw (pattern->status);
 
     return pattern;
 }
@@ -463,7 +460,7 @@ cairo_pattern_create_for_surface (cairo_
 
     pattern = malloc (sizeof (cairo_surface_pattern_t));
     if (pattern == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_pattern_t *)&_cairo_pattern_nil.base;
     }
 
@@ -506,7 +503,7 @@ cairo_pattern_create_linear (double x0, 
 
     pattern = malloc (sizeof (cairo_linear_pattern_t));
     if (pattern == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_pattern_t *) &_cairo_pattern_nil.base;
     }
 
@@ -551,7 +548,7 @@ cairo_pattern_create_radial (double cx0,
 
     pattern = malloc (sizeof (cairo_radial_pattern_t));
     if (pattern == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_pattern_t *) &_cairo_pattern_nil.base;
     }
 
@@ -734,7 +731,7 @@ cairo_pattern_set_user_data (cairo_patte
 			     cairo_destroy_func_t	  destroy)
 {
     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count))
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return _cairo_user_data_array_set_data (&pattern->user_data,
 					    key, user_data, destroy);
@@ -769,10 +766,8 @@ _cairo_pattern_gradient_grow (cairo_grad
 				       sizeof (cairo_gradient_stop_t));
     }
 
-    if (new_stops == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (new_stops == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     pattern->stops = new_stops;
     pattern->stops_size = new_size;
@@ -795,7 +790,7 @@ _cairo_pattern_add_color_stop (cairo_gra
     if (pattern->n_stops >= pattern->stops_size) {
         cairo_status_t status = _cairo_pattern_gradient_grow (pattern);
 	if (status) {
-	    _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
+	    status = _cairo_pattern_set_error (&pattern->base, status);
 	    return;
 	}
     }
@@ -984,7 +979,7 @@ cairo_pattern_set_matrix (cairo_pattern_
     inverse = *matrix;
     status = cairo_matrix_invert (&inverse);
     if (status)
-	_cairo_pattern_set_error (pattern, status);
+	status = _cairo_pattern_set_error (pattern, status);
 }
 slim_hidden_def (cairo_pattern_set_matrix);
 
@@ -1160,10 +1155,8 @@ _cairo_pattern_acquire_surface_for_gradi
 
     if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
 	pixman_stops = _cairo_malloc_ab (pattern->n_stops, sizeof(pixman_gradient_stop_t));
-	if (pixman_stops == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (pixman_stops == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     for (i = 0; i < pattern->n_stops; i++) {
@@ -1212,7 +1205,7 @@ _cairo_pattern_acquire_surface_for_gradi
 	free (pixman_stops);
 
     if (pixman_image == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (_cairo_surface_is_image (dst))
     {
@@ -1222,7 +1215,7 @@ _cairo_pattern_acquire_surface_for_gradi
 	if (image->base.status)
 	{
 	    pixman_image_unref (pixman_image);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return image->base.status;
 	}
 
 	attr->x_offset = attr->y_offset = 0;
@@ -1264,7 +1257,7 @@ _cairo_pattern_acquire_surface_for_gradi
 	cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
     if (image->base.status) {
 	pixman_image_unref (pixman_image);
-	return CAIRO_STATUS_NO_MEMORY;
+	return image->base.status;
     }
 
     pixman_image_set_filter (pixman_image, PIXMAN_FILTER_BILINEAR, NULL, 0);
@@ -1273,7 +1266,7 @@ _cairo_pattern_acquire_surface_for_gradi
     if (!pixman_image_set_transform (pixman_image, &pixman_transform)) {
 	cairo_surface_destroy (&image->base);
 	pixman_image_unref (pixman_image);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     switch (pattern->base.extend) {
@@ -2030,7 +2023,7 @@ cairo_pattern_get_rgba (cairo_pattern_t 
     double r0, g0, b0, a0;
 
     if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
-	return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
 
     _cairo_color_get_rgba (&solid->color, &r0, &g0, &b0, &a0);
 
@@ -2068,7 +2061,7 @@ cairo_pattern_get_surface (cairo_pattern
     cairo_surface_pattern_t *spat = (cairo_surface_pattern_t*) pattern;
 
     if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
-	return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
 
     if (surface)
 	*surface = spat->surface;
@@ -2107,10 +2100,10 @@ cairo_pattern_get_color_stop_rgba (cairo
 
     if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
 	pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
-	return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
 
     if (index < 0 || (unsigned int) index >= gradient->n_stops)
-	return CAIRO_STATUS_INVALID_INDEX;
+	return _cairo_error (CAIRO_STATUS_INVALID_INDEX);
 
     if (offset)
 	*offset = _cairo_fixed_to_double(gradient->stops[index].x);
@@ -2148,7 +2141,7 @@ cairo_pattern_get_color_stop_count (cair
 
     if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
 	pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
-	return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
 
     if (count)
 	*count = gradient->n_stops;
@@ -2180,7 +2173,7 @@ cairo_pattern_get_linear_points (cairo_p
     cairo_linear_pattern_t *linear = (cairo_linear_pattern_t*) pattern;
 
     if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR)
-	return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
 
     if (x0)
 	*x0 = _cairo_fixed_to_double (linear->p1.x);
@@ -2221,7 +2214,7 @@ cairo_pattern_get_radial_circles (cairo_
     cairo_radial_pattern_t *radial = (cairo_radial_pattern_t*) pattern;
 
     if (pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
-	return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
 
     if (x0)
 	*x0 = _cairo_fixed_to_double (radial->c1.x);
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 043d8f4..3a5b637 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -305,7 +305,7 @@ _cairo_pdf_surface_create_for_stream_int
 
     surface = malloc (sizeof (cairo_pdf_surface_t));
     if (surface == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -331,7 +331,7 @@ _cairo_pdf_surface_create_for_stream_int
 
     surface->font_subsets = _cairo_scaled_font_subsets_create_composite ();
     if (! surface->font_subsets) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	goto fail;
     }
 
@@ -403,10 +403,8 @@ cairo_pdf_surface_create_for_stream (cai
 
     output = _cairo_output_stream_create (write_func, NULL, closure);
     status = _cairo_output_stream_get_status (output);
-    if (status) {
-	_cairo_error (status);
+    if (status)
 	return (cairo_surface_t*) &_cairo_surface_nil;
-    }
 
     return _cairo_pdf_surface_create_for_stream_internal (output,
 							  width_in_points,
@@ -442,12 +440,10 @@ cairo_pdf_surface_create (const char		*f
 
     output = _cairo_output_stream_create_for_filename (filename);
     status = _cairo_output_stream_get_status (output);
-    if (status) {
-	_cairo_error (status);
+    if (status)
 	return (status == CAIRO_STATUS_WRITE_ERROR) ?
 		(cairo_surface_t*) &_cairo_surface_nil_write_error :
 		(cairo_surface_t*) &_cairo_surface_nil;
-    }
 
     return _cairo_pdf_surface_create_for_stream_internal (output,
 							  width_in_points,
@@ -471,12 +467,12 @@ _extract_pdf_surface (cairo_surface_t		 
     cairo_surface_t *target;
 
     if (! _cairo_surface_is_paginated (surface))
-	return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     target = _cairo_paginated_surface_get_target (surface);
 
     if (! _cairo_surface_is_pdf (target))
-	return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     *pdf_surface = (cairo_pdf_surface_t *) target;
 
@@ -505,12 +501,12 @@ cairo_pdf_surface_set_size (cairo_surfac
 			    double		 width_in_points,
 			    double		 height_in_points)
 {
-    cairo_pdf_surface_t *pdf_surface;
+    cairo_pdf_surface_t *pdf_surface = NULL; /* hide compiler warning */
     cairo_status_t status;
 
     status = _extract_pdf_surface (surface, &pdf_surface);
     if (status) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	status = _cairo_surface_set_error (surface, status);
 	return;
     }
 
@@ -521,7 +517,7 @@ cairo_pdf_surface_set_size (cairo_surfac
 						width_in_points,
 						height_in_points);
     if (status)
-	_cairo_surface_set_error (surface, status);
+	status = _cairo_surface_set_error (surface, status);
 }
 
 static void
@@ -1182,7 +1178,7 @@ compress_dup (const void *data, unsigned
     *compressed_size = data_size + (data_size >> 12) + (data_size >> 14) + 11;
     compressed = malloc (*compressed_size);
     if (compressed == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -1221,8 +1217,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf
     alpha_size = image->height * image->width;
     alpha = malloc (alpha_size);
     if (alpha == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP;
     }
 
@@ -1258,7 +1253,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf
 
     alpha_compressed = compress_dup (alpha, alpha_size, &alpha_compressed_size);
     if (alpha_compressed == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP_ALPHA;
     }
 
@@ -1315,8 +1310,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf
     rgb_size = image->height * image->width * 3;
     rgb = malloc (rgb_size);
     if (rgb == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP;
     }
 
@@ -1356,7 +1350,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf
 
     compressed = compress_dup (rgb, rgb_size, &compressed_size);
     if (compressed == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP_RGB;
     }
 
@@ -1888,10 +1882,8 @@ _cairo_pdf_surface_emit_pattern_stops (c
     alpha_function->id = 0;
 
     allstops = _cairo_malloc_ab ((pattern->n_stops + 2), sizeof (cairo_pdf_color_stop_t));
-    if (allstops == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (allstops == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     stops = &allstops[1];
     n_stops = pattern->n_stops;
@@ -2303,7 +2295,7 @@ _cairo_pdf_surface_emit_pattern (cairo_p
     }
 
     ASSERT_NOT_REACHED;
-    return CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+    return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
 }
 
 static cairo_status_t
@@ -2498,7 +2490,8 @@ _cairo_pdf_surface_add_clip (cairo_pdf_s
     } else {
 	elem.clip_path = _cairo_path_fixed_create ();
 	if (elem.clip_path == NULL)
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
 	status = _cairo_path_fixed_init_copy (elem.clip_path, path);
 	if (status)
 	    return status;
@@ -2694,7 +2687,7 @@ _cairo_pdf_surface_emit_cff_font (cairo_
 
     compressed = compress_dup (subset->data, subset->data_length, &compressed_length);
     if (compressed == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     stream = _cairo_pdf_surface_new_object (surface);
     _cairo_output_stream_printf (surface->output,
@@ -2858,7 +2851,7 @@ _cairo_pdf_surface_emit_type1_font (cair
     length = subset->header_length + subset->data_length;
     compressed = compress_dup (subset->data, length, &compressed_length);
     if (compressed == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     stream = _cairo_pdf_surface_new_object (surface);
     _cairo_output_stream_printf (surface->output,
@@ -3015,7 +3008,7 @@ _cairo_pdf_surface_emit_truetype_font_su
 			       &compressed_length);
     if (compressed == NULL) {
 	_cairo_truetype_subset_fini (&subset);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     stream = _cairo_pdf_surface_new_object (surface);
@@ -3280,7 +3273,7 @@ _cairo_pdf_surface_emit_glyph (cairo_pdf
                                                        width);
 
     if (status)
-	_cairo_surface_set_error (&surface->base, status);
+	status = _cairo_surface_set_error (&surface->base, status);
 }
 
 static cairo_status_t
@@ -3297,16 +3290,13 @@ _cairo_pdf_surface_emit_type3_font_subse
     cairo_box_t bbox = {{0,0},{0,0}};
 
     glyphs = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (cairo_pdf_resource_t));
-    if (glyphs == NULL) {
-	_cairo_surface_set_error (&surface->base, CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (glyphs == NULL)
+	return _cairo_surface_set_error (&surface->base, CAIRO_STATUS_NO_MEMORY);
 
     widths = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (double));
     if (widths == NULL) {
         free (glyphs);
-	_cairo_surface_set_error (&surface->base, CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_surface_set_error (&surface->base, CAIRO_STATUS_NO_MEMORY);
     }
 
     for (i = 0; i < font_subset->num_glyphs; i++) {
diff --git a/src/cairo-pen.c b/src/cairo-pen.c
index 471849b..0f0dee8 100644
--- a/src/cairo-pen.c
+++ b/src/cairo-pen.c
@@ -80,10 +80,8 @@ _cairo_pen_init (cairo_pen_t	*pen,
 
     pen->vertices = _cairo_malloc_ab (pen->num_vertices,
 	                              sizeof (cairo_pen_vertex_t));
-    if (pen->vertices == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (pen->vertices == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     /*
      * Compute pen coordinates.  To generate the right ellipse, compute points around
@@ -123,10 +121,9 @@ _cairo_pen_init_copy (cairo_pen_t *pen, 
     if (pen->num_vertices) {
 	pen->vertices = _cairo_malloc_ab (pen->num_vertices,
 	       	                          sizeof (cairo_pen_vertex_t));
-	if (pen->vertices == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (pen->vertices == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
 	memcpy (pen->vertices, other->vertices, pen->num_vertices * sizeof (cairo_pen_vertex_t));
     }
 
@@ -144,10 +141,8 @@ _cairo_pen_add_points (cairo_pen_t *pen,
     num_vertices = pen->num_vertices + num_points;
     vertices = _cairo_realloc_ab (pen->vertices,
 	                          num_vertices, sizeof (cairo_pen_vertex_t));
-    if (vertices == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (vertices == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     pen->vertices = vertices;
     pen->num_vertices = num_vertices;
diff --git a/src/cairo-png.c b/src/cairo-png.c
index 8ad4c9a..2715067 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -129,14 +129,14 @@ write_png (cairo_surface_t	*surface,
 						  &image_extra);
 
     if (status == CAIRO_STATUS_NO_MEMORY)
-        return CAIRO_STATUS_NO_MEMORY;
+        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     else if (status != CAIRO_STATUS_SUCCESS)
-	return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     if (image->height && image->width) {
 	rows = _cairo_malloc_ab (image->height, sizeof (png_byte*));
 	if (rows == NULL) {
-	    status = CAIRO_STATUS_NO_MEMORY;
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto BAIL1;
 	}
 
@@ -148,13 +148,13 @@ write_png (cairo_surface_t	*surface,
 	                           png_simple_error_callback,
 	                           png_simple_warning_callback);
     if (png == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto BAIL2;
     }
 
     info = png_create_info_struct (png);
     if (info == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto BAIL3;
     }
 
@@ -181,7 +181,7 @@ write_png (cairo_surface_t	*surface,
 	png_color_type = PNG_COLOR_TYPE_GRAY;
 	break;
     default:
-	status = CAIRO_STATUS_INVALID_FORMAT;
+	status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
 	goto BAIL3;
     }
 
@@ -270,12 +270,12 @@ cairo_surface_write_to_png (cairo_surfac
 
     fp = fopen (filename, "wb");
     if (fp == NULL)
-	return CAIRO_STATUS_WRITE_ERROR;
+	return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
 
     status = write_png (surface, stdio_write_func, fp);
 
     if (fclose (fp) && status == CAIRO_STATUS_SUCCESS)
-	status = CAIRO_STATUS_WRITE_ERROR;
+	status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
 
     return status;
 }
@@ -477,7 +477,7 @@ read_png (png_rw_ptr	read_func,
 	png_destroy_read_struct (&png, &info, NULL);
 
     if (surface->status)
-	_cairo_error (surface->status);
+	_cairo_error_throw (surface->status);
 
     return surface;
 }
@@ -526,13 +526,13 @@ cairo_image_surface_create_from_png (con
     if (fp == NULL) {
 	switch (errno) {
 	case ENOMEM:
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	    return (cairo_surface_t*) &_cairo_surface_nil;
 	case ENOENT:
-	    _cairo_error (CAIRO_STATUS_FILE_NOT_FOUND);
+	    _cairo_error_throw (CAIRO_STATUS_FILE_NOT_FOUND);
 	    return (cairo_surface_t*) &_cairo_surface_nil_file_not_found;
 	default:
-	    _cairo_error (CAIRO_STATUS_READ_ERROR);
+	    _cairo_error_throw (CAIRO_STATUS_READ_ERROR);
 	    return (cairo_surface_t*) &_cairo_surface_nil_read_error;
 	}
     }
diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c
index 3aa0c4c..125d54d 100644
--- a/src/cairo-polygon.c
+++ b/src/cairo-polygon.c
@@ -101,10 +101,8 @@ _cairo_polygon_grow (cairo_polygon_t *po
 	       	                       new_size, sizeof (cairo_edge_t));
     }
 
-    if (new_edges == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (new_edges == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     polygon->edges = new_edges;
     polygon->edges_size = new_size;
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 77d3820..23a478c 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -150,7 +150,7 @@ _word_wrap_stream_create (cairo_output_s
 
     stream = malloc (sizeof (word_wrap_stream_t));
     if (stream == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
     }
 
@@ -653,7 +653,7 @@ _cairo_ps_surface_emit_glyph (cairo_ps_s
 				 "\t\t}\n");
 
     if (status)
-	_cairo_surface_set_error (&surface->base, status);
+	status = _cairo_surface_set_error (&surface->base, status);
 
     return status;
 }
@@ -807,7 +807,7 @@ _cairo_ps_surface_create_for_stream_inte
 
     surface = malloc (sizeof (cairo_ps_surface_t));
     if (surface == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP;
     }
 
@@ -857,7 +857,7 @@ _cairo_ps_surface_create_for_stream_inte
  CLEANUP_SURFACE:
     free (surface);
  CLEANUP:
-    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
     return (cairo_surface_t*) &_cairo_surface_nil;
 }
 
@@ -895,12 +895,10 @@ cairo_ps_surface_create (const char		*fi
 
     stream = _cairo_output_stream_create_for_filename (filename);
     status = _cairo_output_stream_get_status (stream);
-    if (status) {
-	_cairo_error (status);
+    if (status)
 	return (status == CAIRO_STATUS_WRITE_ERROR) ?
 		(cairo_surface_t*) &_cairo_surface_nil_write_error :
 		(cairo_surface_t*) &_cairo_surface_nil;
-    }
 
     return _cairo_ps_surface_create_for_stream_internal (stream,
 							 width_in_points,
@@ -943,10 +941,8 @@ cairo_ps_surface_create_for_stream (cair
 
     stream = _cairo_output_stream_create (write_func, NULL, closure);
     status = _cairo_output_stream_get_status (stream);
-    if (status) {
-	_cairo_error (status);
+    if (status)
 	return (cairo_surface_t*) &_cairo_surface_nil;
-    }
 
     return _cairo_ps_surface_create_for_stream_internal (stream,
 							 width_in_points,
@@ -970,12 +966,12 @@ _extract_ps_surface (cairo_surface_t	 *s
     cairo_surface_t *target;
 
     if (! _cairo_surface_is_paginated (surface))
-	return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     target = _cairo_paginated_surface_get_target (surface);
 
     if (! _cairo_surface_is_ps (target))
-	return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     *ps_surface = (cairo_ps_surface_t *) target;
 
@@ -1007,7 +1003,7 @@ cairo_ps_surface_set_eps (cairo_surface_
 
     status = _extract_ps_surface (surface, &ps_surface);
     if (status) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	status = _cairo_surface_set_error (surface, status);
 	return;
     }
 
@@ -1032,7 +1028,7 @@ cairo_ps_surface_get_eps (cairo_surface_
 
     status = _extract_ps_surface (surface, &ps_surface);
     if (status) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	status = _cairo_surface_set_error (surface, status);
 	return FALSE;
     }
 
@@ -1066,7 +1062,7 @@ cairo_ps_surface_set_size (cairo_surface
 
     status = _extract_ps_surface (surface, &ps_surface);
     if (status) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	status = _cairo_surface_set_error (surface, status);
 	return;
     }
 
@@ -1076,7 +1072,7 @@ cairo_ps_surface_set_size (cairo_surface
 						width_in_points,
 						height_in_points);
     if (status)
-	_cairo_surface_set_error (surface, status);
+	status = _cairo_surface_set_error (surface, status);
 }
 
 /**
@@ -1177,32 +1173,32 @@ cairo_ps_surface_dsc_comment (cairo_surf
 
     status = _extract_ps_surface (surface, &ps_surface);
     if (status) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	status = _cairo_surface_set_error (surface, status);
 	return;
     }
 
     /* A couple of sanity checks on the comment value. */
     if (comment == NULL) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_NULL_POINTER);
+	status = _cairo_surface_set_error (surface, CAIRO_STATUS_NULL_POINTER);
 	return;
     }
 
     if (comment[0] != '%' || strlen (comment) > 255) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_DSC_COMMENT);
+	status = _cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_DSC_COMMENT);
 	return;
     }
 
     /* Then, copy the comment and store it in the appropriate array. */
     comment_copy = strdup (comment);
     if (comment_copy == NULL) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_surface_set_error (surface, CAIRO_STATUS_NO_MEMORY);
 	return;
     }
 
     status = _cairo_array_append (ps_surface->dsc_comment_target, &comment_copy);
     if (status) {
 	free (comment_copy);
-	_cairo_surface_set_error (surface, status);
+	status = _cairo_surface_set_error (surface, status);
 	return;
     }
 }
@@ -1231,7 +1227,7 @@ cairo_ps_surface_dsc_begin_setup (cairo_
 
     status = _extract_ps_surface (surface, &ps_surface);
     if (status) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	status = _cairo_surface_set_error (surface, status);
 	return;
     }
 
@@ -1266,7 +1262,7 @@ cairo_ps_surface_dsc_begin_page_setup (c
 
     status = _extract_ps_surface (surface, &ps_surface);
     if (status) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	status = _cairo_surface_set_error (surface, status);
 	return;
     }
 
@@ -1568,7 +1564,7 @@ _string_array_stream_create (cairo_outpu
 
     stream = malloc (sizeof (string_array_stream_t));
     if (stream == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
     }
 
@@ -1610,7 +1606,7 @@ _cairo_ps_surface_emit_image (cairo_ps_s
 					     image->width,
 					     image->height);
 	if (opaque->status) {
-	    status = CAIRO_STATUS_NO_MEMORY;
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto bail0;
 	}
 
@@ -1650,8 +1646,7 @@ _cairo_ps_surface_emit_image (cairo_ps_s
     rgb_size = 3 * opaque_image->width * opaque_image->height;
     rgb = malloc (rgb_size);
     if (rgb == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto bail1;
     }
 
@@ -1670,7 +1665,7 @@ _cairo_ps_surface_emit_image (cairo_ps_s
     compressed_size = rgb_size;
     compressed = _cairo_lzw_compress (rgb, &compressed_size);
     if (compressed == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto bail2;
     }
 
@@ -2122,10 +2117,8 @@ _cairo_ps_surface_stroke (void			*abstra
 	 */
 	if (num_dashes % 2) {
 	    dash = _cairo_malloc_abc (num_dashes, 2, sizeof (double));
-	    if (dash == NULL) {
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
-		return CAIRO_STATUS_NO_MEMORY;
-	    }
+	    if (dash == NULL)
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	    memcpy (dash, style->dash, num_dashes * sizeof (double));
 	    memcpy (dash + num_dashes, style->dash, num_dashes * sizeof (double));
@@ -2306,10 +2299,8 @@ _cairo_ps_surface_show_glyphs (void		   
 
     _cairo_ps_surface_emit_pattern (surface, source);
     glyph_ids = _cairo_malloc_ab (num_glyphs_unsigned, sizeof (cairo_ps_glyph_id_t));
-    if (glyph_ids == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (glyph_ids == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     for (i = 0; i < num_glyphs_unsigned; i++) {
         status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets,
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 8a90f30..88fe4b0 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -1256,10 +1256,8 @@ _cairo_quartz_surface_stroke (void *abst
 	unsigned int k;
 	if (style->num_dashes > STATIC_DASH)
 	    fdash = _cairo_malloc_ab (style->num_dashes, sizeof (float));
-	if (fdash == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (fdash == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	for (k = 0; k < style->num_dashes; k++)
 	    fdash[k] = (float) style->dash[k];
@@ -1399,16 +1397,13 @@ _cairo_quartz_surface_show_glyphs (void 
 
     if (num_glyphs > STATIC_BUF_SIZE) {
 	cg_glyphs = (CGGlyph*) _cairo_malloc_ab (num_glyphs, sizeof(CGGlyph));
-	if (cg_glyphs == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (cg_glyphs == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	cg_advances = (CGSize*) _cairo_malloc_ab (num_glyphs, sizeof(CGSize));
 	if (cg_glyphs == NULL) {
 	    free (cg_advances);
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
     }
 
diff --git a/src/cairo-region.c b/src/cairo-region.c
index ea4ccc3..b4b9117 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -66,10 +66,8 @@ _cairo_region_init_boxes (cairo_region_t
 
     if (count > ARRAY_LENGTH(stack_pboxes)) {
 	pboxes = _cairo_malloc_ab (count, sizeof(pixman_box16_t));
-	if (pboxes == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (pboxes == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     for (i = 0; i < count; i++) {
@@ -80,7 +78,7 @@ _cairo_region_init_boxes (cairo_region_t
     }
 
     if (!pixman_region_init_rects (&region->rgn, pboxes, count))
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (pboxes != stack_pboxes)
 	free (pboxes);
@@ -98,7 +96,7 @@ cairo_int_status_t
 _cairo_region_copy (cairo_region_t *dst, cairo_region_t *src)
 {
     if (!pixman_region_copy (&dst->rgn, &src->rgn))
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -126,10 +124,8 @@ _cairo_region_get_boxes (cairo_region_t 
     }
 
     cboxes = _cairo_malloc_ab (nboxes, sizeof(cairo_box_int_t));
-    if (cboxes == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (cboxes == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     for (i = 0; i < nboxes; i++) {
 	cboxes[i].p1.x = pboxes[i].x1;
@@ -172,7 +168,7 @@ cairo_int_status_t
 _cairo_region_subtract (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
 {
     if (!pixman_region_subtract (&dst->rgn, &a->rgn, &b->rgn))
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -181,7 +177,7 @@ cairo_int_status_t
 _cairo_region_intersect (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
 {
     if (!pixman_region_intersect (&dst->rgn, &a->rgn, &b->rgn))
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -194,7 +190,7 @@ _cairo_region_union_rect (cairo_region_t
     if (!pixman_region_union_rect (&dst->rgn, &src->rgn,
 				   rect->x, rect->y,
 				   rect->width, rect->height))
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return CAIRO_STATUS_SUCCESS;
 }
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index a5d9c49..efc7999 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -125,7 +125,7 @@ _cairo_sub_font_glyph_create (unsigned l
 
     sub_font_glyph = malloc (sizeof (cairo_sub_font_glyph_t));
     if (sub_font_glyph == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -217,7 +217,7 @@ _cairo_sub_font_create (cairo_scaled_fon
 
     sub_font = malloc (sizeof (cairo_sub_font_t));
     if (sub_font == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -289,7 +289,7 @@ _cairo_sub_font_lookup_glyph (cairo_sub_
         return CAIRO_STATUS_SUCCESS;
     }
 
-    return CAIRO_STATUS_NULL_POINTER;
+    return _cairo_error (CAIRO_STATUS_NULL_POINTER);
 }
 
 static cairo_status_t
@@ -328,7 +328,7 @@ _cairo_sub_font_map_glyph (cairo_sub_fon
 						       sub_font->num_glyphs_in_current_subset++,
                                                        scaled_glyph->metrics.x_advance);
 	if (sub_font_glyph == NULL)
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
         if (sub_font->is_scaled)
         {
@@ -416,7 +416,7 @@ _cairo_scaled_font_subsets_create_intern
 
     subsets = malloc (sizeof (cairo_scaled_font_subsets_t)); 
     if (subsets == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
@@ -563,7 +563,7 @@ _cairo_scaled_font_subsets_map_glyph (ca
                                                subset_glyph->is_composite);
             if (sub_font == NULL) {
 		cairo_scaled_font_destroy (unscaled_font);
-                return CAIRO_STATUS_NO_MEMORY;
+                return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    }
 
             status = _cairo_hash_table_insert (subsets->unscaled_sub_fonts,
@@ -595,7 +595,7 @@ _cairo_scaled_font_subsets_map_glyph (ca
                                                subset_glyph->is_composite);
             if (sub_font == NULL) {
 		cairo_scaled_font_destroy (scaled_font);
-                return CAIRO_STATUS_NO_MEMORY;
+                return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    }
 
             status = _cairo_hash_table_insert (subsets->scaled_sub_fonts,
@@ -629,10 +629,8 @@ _cairo_scaled_font_subsets_foreach_inter
 	return CAIRO_STATUS_SUCCESS;
 
     collection.glyphs = _cairo_malloc_ab (collection.glyphs_size, sizeof(unsigned long));
-    if (collection.glyphs == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (collection.glyphs == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     collection.font_subset_callback = font_subset_callback;
     collection.font_subset_callback_closure = closure;
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 08d426f..47f06e7 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -223,7 +223,7 @@ _cairo_scaled_font_set_error (cairo_scal
      * error, which is the most significant. */
     _cairo_status_set_error (&scaled_font->status, status);
 
-    _cairo_error (status);
+    _cairo_error_throw (status);
 }
 
 /**
@@ -323,7 +323,7 @@ _cairo_scaled_font_map_lock (void)
     cairo_scaled_font_map = NULL;
  CLEANUP_MUTEX_LOCK:
     CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex);
-    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
     return NULL;
 }
 
@@ -481,7 +481,7 @@ _cairo_scaled_font_init (cairo_scaled_fo
 					       _cairo_scaled_glyph_destroy,
 					       MAX_GLYPHS_CACHED_PER_FONT);
     if (scaled_font->glyphs == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     CAIRO_REFERENCE_COUNT_INIT (&scaled_font->ref_count, 1);
 
@@ -827,7 +827,7 @@ cairo_scaled_font_set_user_data (cairo_s
 				 cairo_destroy_func_t	      destroy)
 {
     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&scaled_font->ref_count))
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return _cairo_user_data_array_set_data (&scaled_font->user_data,
 					    key, user_data, destroy);
@@ -1035,8 +1035,7 @@ _cairo_scaled_font_text_to_glyphs (cairo
     *glyphs = (cairo_glyph_t *) _cairo_malloc_ab ((*num_glyphs), sizeof (cairo_glyph_t));
 
     if (*glyphs == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto DONE;
     }
 
@@ -1443,7 +1442,7 @@ _cairo_scaled_font_glyph_path (cairo_sca
 
 	    glyph_path = _cairo_path_fixed_create ();
 	    if (glyph_path == NULL)
-		return CAIRO_STATUS_NO_MEMORY;
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	    status = _trace_mask_to_path (scaled_glyph->surface, glyph_path);
 	    if (status) {
@@ -1626,8 +1625,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled
 	 */
 	scaled_glyph = malloc (sizeof (cairo_scaled_glyph_t));
 	if (scaled_glyph == NULL) {
-	    status = CAIRO_STATUS_NO_MEMORY;
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto CLEANUP;
 	}
 
diff --git a/src/cairo-skiplist.c b/src/cairo-skiplist.c
index fe80263..ebeb52c 100644
--- a/src/cairo-skiplist.c
+++ b/src/cairo-skiplist.c
@@ -356,7 +356,7 @@ _cairo_skip_list_insert (cairo_skip_list
 
     data_and_elt = alloc_node_for_level (list, level);
     if (data_and_elt == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
diff --git a/src/cairo-spline.c b/src/cairo-spline.c
index f22f646..898ce7c 100644
--- a/src/cairo-spline.c
+++ b/src/cairo-spline.c
@@ -117,10 +117,8 @@ _cairo_spline_grow (cairo_spline_t *spli
 	       	                        new_size, sizeof (cairo_point_t));
     }
 
-    if (new_points == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (new_points == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     spline->points = new_points;
     spline->points_size = new_size;
diff --git a/src/cairo-stroke-style.c b/src/cairo-stroke-style.c
index ea6b412..a7c17b2 100644
--- a/src/cairo-stroke-style.c
+++ b/src/cairo-stroke-style.c
@@ -63,10 +63,8 @@ _cairo_stroke_style_init_copy (cairo_str
 	style->dash = NULL;
     } else {
 	style->dash = _cairo_malloc_ab (style->num_dashes, sizeof (double));
-	if (style->dash == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (style->dash == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	memcpy (style->dash, other->dash,
 		style->num_dashes * sizeof (double));
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 37aee51..e9a77ad 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -125,7 +125,7 @@ _create_composite_mask_pattern (cairo_su
 					 extents->width,
 					 extents->height);
     if (mask->status)
-	return CAIRO_STATUS_NO_MEMORY;
+	return mask->status;
 
     status = (*draw_func) (draw_closure, CAIRO_OPERATOR_ADD,
 			   NULL, mask,
@@ -211,7 +211,7 @@ _clip_and_composite_combine (cairo_clip_
 						 extents->width,
 						 extents->height);
     if (intermediate->status)
-	return CAIRO_STATUS_NO_MEMORY;
+	return intermediate->status;
 
     /* Initialize the intermediate surface from the destination surface
      */
@@ -1171,8 +1171,7 @@ _cairo_surface_fallback_fill_rectangles 
     if (state.image_rect.x != 0 || state.image_rect.y != 0) {
 	offset_rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int_t));
 	if (offset_rects == NULL) {
-	    status = CAIRO_STATUS_NO_MEMORY;
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto DONE;
 	}
 
@@ -1228,8 +1227,7 @@ _cairo_surface_fallback_composite_trapez
     if (state.image_rect.x != 0 || state.image_rect.y != 0) {
 	offset_traps = _cairo_malloc_ab (num_traps, sizeof (cairo_trapezoid_t));
 	if (!offset_traps) {
-	    status = CAIRO_STATUS_NO_MEMORY;
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto DONE;
 	}
 
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 8697689..3c95198 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -104,8 +104,10 @@ _cairo_surface_copy_pattern_for_destinat
  * The purpose of this function is to allow the user to set a
  * breakpoint in _cairo_error() to generate a stack trace for when the
  * user causes cairo to detect an error.
+ *
+ * Return value: the error status.
  **/
-void
+cairo_status_t
 _cairo_surface_set_error (cairo_surface_t *surface,
 			  cairo_status_t status)
 {
@@ -113,7 +115,7 @@ _cairo_surface_set_error (cairo_surface_
      * error, which is the most significant. */
     _cairo_status_set_error (&surface->status, status);
 
-    _cairo_error (status);
+    return _cairo_error (status);
 }
 
 /**
@@ -287,7 +289,7 @@ cairo_surface_create_similar (cairo_surf
 	return (cairo_surface_t*) &_cairo_surface_nil;
 
     if (! CAIRO_CONTENT_VALID (content)) {
-	_cairo_error (CAIRO_STATUS_INVALID_CONTENT);
+	_cairo_error_throw (CAIRO_STATUS_INVALID_CONTENT);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -313,7 +315,7 @@ _cairo_surface_create_similar_solid (cai
     surface = _cairo_surface_create_similar_scratch (other, content,
 						     width, height);
     if (surface->status) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -321,7 +323,7 @@ _cairo_surface_create_similar_solid (cai
 	source = _cairo_pattern_create_solid (color, content);
 	if (source->status) {
 	    cairo_surface_destroy (surface);
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	    return (cairo_surface_t*) &_cairo_surface_nil;
 	}
     } else
@@ -337,7 +339,7 @@ _cairo_surface_create_similar_solid (cai
 
     if (status) {
 	cairo_surface_destroy (surface);
-	_cairo_error (status);
+	_cairo_error_throw (status);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -492,7 +494,7 @@ cairo_surface_finish (cairo_surface_t *s
 	return;
 
     if (surface->finished) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
+	status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
 	return;
     }
 
@@ -504,14 +506,14 @@ cairo_surface_finish (cairo_surface_t *s
     if (!surface->status && surface->backend->flush) {
 	status = surface->backend->flush (surface);
 	if (status) {
-	    _cairo_surface_set_error (surface, status);
+	    status = _cairo_surface_set_error (surface, status);
 	    return;
 	}
     }
 
     status = surface->backend->finish (surface);
     if (status)
-	_cairo_surface_set_error (surface, status);
+	status = _cairo_surface_set_error (surface, status);
 
     surface->finished = TRUE;
 }
@@ -560,7 +562,7 @@ cairo_surface_set_user_data (cairo_surfa
 			     cairo_destroy_func_t	 destroy)
 {
     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return _cairo_user_data_array_set_data (&surface->user_data,
 					    key, user_data, destroy);
@@ -640,21 +642,20 @@ slim_hidden_def (cairo_surface_get_font_
 void
 cairo_surface_flush (cairo_surface_t *surface)
 {
+    cairo_status_t status;
+
     if (surface->status)
 	return;
 
     if (surface->finished) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
+	status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
 	return;
     }
 
     if (surface->backend->flush) {
-	cairo_status_t status;
-
 	status = surface->backend->flush (surface);
-
 	if (status)
-	    _cairo_surface_set_error (surface, status);
+	    status = _cairo_surface_set_error (surface, status);
     }
 }
 
@@ -697,13 +698,15 @@ cairo_surface_mark_dirty_rectangle (cair
 				    int              width,
 				    int              height)
 {
+    cairo_status_t status;
+
     assert (! surface->is_snapshot);
 
     if (surface->status)
 	return;
 
     if (surface->finished) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
+	status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
 	return;
     }
 
@@ -715,8 +718,6 @@ cairo_surface_mark_dirty_rectangle (cair
     surface->current_clip_serial = -1;
 
     if (surface->backend->mark_dirty_rectangle) {
-	cairo_status_t status;
-
 	/* XXX: FRAGILE: We're ignoring the scaling component of
 	 * device_transform here. I don't know what the right thing to
 	 * do would actually be if there were some scaling here, but
@@ -728,7 +729,7 @@ cairo_surface_mark_dirty_rectangle (cair
 							 width, height);
 
 	if (status)
-	    _cairo_surface_set_error (surface, status);
+	    status = _cairo_surface_set_error (surface, status);
     }
 }
 slim_hidden_def (cairo_surface_mark_dirty_rectangle);
@@ -758,13 +759,15 @@ _cairo_surface_set_device_scale (cairo_s
 				 double		  sx,
 				 double		  sy)
 {
+    cairo_status_t status;
+
     assert (! surface->is_snapshot);
 
     if (surface->status)
 	return;
 
     if (surface->finished) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
+	status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
 	return;
     }
 
@@ -798,13 +801,15 @@ cairo_surface_set_device_offset (cairo_s
 				 double           x_offset,
 				 double           y_offset)
 {
+    cairo_status_t status;
+
     assert (! surface->is_snapshot);
 
     if (surface->status)
 	return;
 
     if (surface->finished) {
-	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
+	status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
 	return;
     }
 
@@ -1036,7 +1041,7 @@ _cairo_surface_clone_similar (cairo_surf
     void *image_extra;
 
     if (surface->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     if (surface->backend->clone_similar) {
 	status = surface->backend->clone_similar (surface, src, src_x, src_y,
@@ -1164,7 +1169,7 @@ _cairo_surface_composite (cairo_operator
 	return dst->status;
 
     if (dst->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     if (dst->backend->composite) {
 	status = dst->backend->composite (op,
@@ -1217,7 +1222,7 @@ _cairo_surface_fill_rectangle (cairo_sur
 	return surface->status;
 
     if (surface->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     rect.x = x;
     rect.y = y;
@@ -1267,8 +1272,7 @@ _cairo_surface_fill_region (cairo_surfac
 	rects = _cairo_malloc_ab (num_boxes, sizeof (cairo_rectangle_int_t));
 	if (!rects) {
 	    _cairo_region_boxes_fini (region, boxes);
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
         }
     }
 
@@ -1321,7 +1325,7 @@ _cairo_surface_fill_rectangles (cairo_su
 	return surface->status;
 
     if (surface->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     if (num_rects == 0)
 	return CAIRO_STATUS_SUCCESS;
@@ -1571,7 +1575,7 @@ _cairo_surface_composite_trapezoids (cai
 	return dst->status;
 
     if (dst->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     if (dst->backend->composite_trapezoids) {
 	status = dst->backend->composite_trapezoids (op,
@@ -1613,7 +1617,7 @@ cairo_surface_copy_page (cairo_surface_t
 	return surface->status;
 
     if (surface->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     /* It's fine if some backends don't implement copy_page */
     if (surface->backend->copy_page == NULL)
@@ -1642,7 +1646,7 @@ cairo_surface_show_page (cairo_surface_t
 	return surface->status;
 
     if (surface->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     /* It's fine if some backends don't implement show_page */
     if (surface->backend->show_page == NULL)
@@ -1708,7 +1712,7 @@ _cairo_surface_reset_clip (cairo_surface
 	return surface->status;
 
     if (surface->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     surface->current_clip_serial = 0;
 
@@ -1752,7 +1756,7 @@ _cairo_surface_set_clip_region (cairo_su
 	return surface->status;
 
     if (surface->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     assert (surface->backend->set_clip_region != NULL);
 
@@ -1777,7 +1781,7 @@ _cairo_surface_intersect_clip_path (cair
 	return surface->status;
 
     if (surface->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     assert (surface->backend->intersect_clip_path != NULL);
 
@@ -1830,7 +1834,7 @@ _cairo_surface_set_clip_path (cairo_surf
 	return surface->status;
 
     if (surface->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     assert (surface->backend->intersect_clip_path != NULL);
 
@@ -1857,13 +1861,13 @@ _cairo_surface_set_clip (cairo_surface_t
     unsigned int serial = 0;
 
     if (!surface)
-	return CAIRO_STATUS_NULL_POINTER;
+	return _cairo_error (CAIRO_STATUS_NULL_POINTER);
 
     if (surface->status)
 	return surface->status;
 
     if (surface->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     if (clip) {
 	serial = clip->serial;
@@ -1923,7 +1927,7 @@ _cairo_surface_get_extents (cairo_surfac
 	return surface->status;
 
     if (surface->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     return surface->backend->get_extents (surface, rectangle);
 }
@@ -2036,7 +2040,7 @@ _cairo_surface_old_show_glyphs (cairo_sc
 	return dst->status;
 
     if (dst->finished)
-	return CAIRO_STATUS_SURFACE_FINISHED;
+	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     if (dst->backend->old_show_glyphs) {
 	status = dst->backend->old_show_glyphs (scaled_font,
@@ -2095,7 +2099,7 @@ _cairo_surface_composite_fixup_unbounded
     if (_cairo_region_subtract (&clear_region, &clear_region, &drawn_region)
 	!= CAIRO_STATUS_SUCCESS)
     {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto CLEANUP_REGIONS;
     }
 
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index b4e9270..cc909f5 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -178,10 +178,8 @@ cairo_svg_surface_create_for_stream (cai
 
     stream = _cairo_output_stream_create (write_func, NULL, closure);
     status = _cairo_output_stream_get_status (stream);
-    if (status) {
-	_cairo_error (status);
+    if (status)
 	return (cairo_surface_t *) &_cairo_surface_nil;
-    }
 
     return _cairo_svg_surface_create_for_stream_internal (stream, width, height, CAIRO_SVG_VERSION_1_1);
 }
@@ -215,12 +213,10 @@ cairo_svg_surface_create (const char	*fi
 
     stream = _cairo_output_stream_create_for_filename (filename);
     status = _cairo_output_stream_get_status (stream);
-    if (status) {
-	_cairo_error (status);
+    if (status)
 	return (status == CAIRO_STATUS_WRITE_ERROR) ?
 		(cairo_surface_t *) &_cairo_surface_nil_write_error :
 		(cairo_surface_t *) &_cairo_surface_nil;
-    }
 
     return _cairo_svg_surface_create_for_stream_internal (stream, width, height, CAIRO_SVG_VERSION_1_1);
 }
@@ -242,12 +238,12 @@ _extract_svg_surface (cairo_surface_t		 
     cairo_surface_t *target;
 
     if (! _cairo_surface_is_paginated (surface))
-	return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     target = _cairo_paginated_surface_get_target (surface);
 
     if (! _cairo_surface_is_svg (target))
-	return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     *svg_surface = (cairo_svg_surface_t *) target;
 
@@ -273,13 +269,12 @@ void
 cairo_svg_surface_restrict_to_version (cairo_surface_t 		*abstract_surface,
 				       cairo_svg_version_t  	 version)
 {
-    cairo_svg_surface_t *surface;
+    cairo_svg_surface_t *surface = NULL; /* hide compiler warning */
     cairo_status_t status;
 
     status = _extract_svg_surface (abstract_surface, &surface);
     if (status) {
-	_cairo_surface_set_error (abstract_surface,
-				  CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	status = _cairo_surface_set_error (abstract_surface, status);
 	return;
     }
 
@@ -339,7 +334,7 @@ _cairo_svg_surface_create_for_document (
 
     surface = malloc (sizeof (cairo_svg_surface_t));
     if (surface == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -389,7 +384,7 @@ _cairo_svg_surface_create_for_stream_int
 
     document = _cairo_svg_document_create (stream, width, height, version);
     if (document == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t *) &_cairo_surface_nil;
     }
 
@@ -2119,14 +2114,13 @@ _cairo_svg_document_create (cairo_output
 
     document = malloc (sizeof (cairo_svg_document_t));
     if (document == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
     /* The use of defs for font glyphs imposes no per-subset limit. */
     document->font_subsets = _cairo_scaled_font_subsets_create_scaled ();
     if (document->font_subsets == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	free (document);
 	return NULL;
     }
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 32743b4..1893fc2 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -270,8 +270,7 @@ _cairo_traps_grow (cairo_traps_t *traps)
     }
 
     if (new_traps == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	traps->status = CAIRO_STATUS_NO_MEMORY;
+	traps->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return traps->status;
     }
 
@@ -615,10 +614,8 @@ _cairo_traps_extract_region (cairo_traps
     if (traps->num_traps > ARRAY_LENGTH(stack_boxes)) {
 	boxes = _cairo_malloc_ab (traps->num_traps, sizeof(cairo_box_int_t));
 
-	if (boxes == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (boxes == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     box_count = 0;
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 5afab3a..0064bbb 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -144,7 +144,7 @@ _cairo_truetype_font_create (cairo_scale
 
     name = malloc(size);
     if (name == NULL)
-        return CAIRO_STATUS_NO_MEMORY;
+        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
 					   TT_TAG_name, 0, (unsigned char *) name,
@@ -154,7 +154,7 @@ _cairo_truetype_font_create (cairo_scale
 
     font = malloc (sizeof (cairo_truetype_font_t));
     if (font == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail0;
     }
 
@@ -171,13 +171,13 @@ _cairo_truetype_font_create (cairo_scale
 
     font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t));
     if (font->glyphs == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail1;
     }
 
     font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int));
     if (font->parent_to_subset == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail2;
     }
 
@@ -221,7 +221,7 @@ _cairo_truetype_font_create (cairo_scale
     if (font->base.base_font == NULL) {
         font->base.base_font = malloc (30);
         if (font->base.base_font == NULL) {
-	    status = CAIRO_STATUS_NO_MEMORY;
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
             goto fail3;
 	}
 
@@ -239,7 +239,7 @@ _cairo_truetype_font_create (cairo_scale
 
     font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
     if (font->base.widths == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail4;
     }
 
@@ -248,7 +248,7 @@ _cairo_truetype_font_create (cairo_scale
     if (status)
 	goto fail5;
 
-    font->status = CAIRO_STATUS_SUCCESS;
+    font->status = _cairo_error (CAIRO_STATUS_SUCCESS);
 
     *font_return = font;
 
@@ -270,8 +270,7 @@ _cairo_truetype_font_create (cairo_scale
     if (name)
 	free (name);
 
-    _cairo_error (status);
-    return status;
+    return _cairo_error (status);
 }
 
 static void
@@ -511,8 +510,7 @@ cairo_truetype_font_write_glyf_table (ca
 
     u.bytes = malloc (size);
     if (u.bytes == NULL) {
-	font->status = CAIRO_STATUS_NO_MEMORY;
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	font->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return font->status;
     }
 
@@ -977,7 +975,7 @@ _cairo_truetype_subset_init (cairo_truet
 
     truetype_subset->base_font = strdup (font->base.base_font);
     if (truetype_subset->base_font == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail1;
     }
 
@@ -987,7 +985,7 @@ _cairo_truetype_subset_init (cairo_truet
     truetype_subset->widths = calloc (sizeof (double),
                                       font->scaled_font_subset->num_glyphs);
     if (truetype_subset->widths == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail2;
     }
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
@@ -1003,7 +1001,7 @@ _cairo_truetype_subset_init (cairo_truet
     if (length) {
 	truetype_subset->data = malloc (length);
 	if (truetype_subset->data == NULL) {
-	    status = CAIRO_STATUS_NO_MEMORY;
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto fail3;
 	}
 
@@ -1016,7 +1014,7 @@ _cairo_truetype_subset_init (cairo_truet
 	offsets_length = num_strings * sizeof (unsigned long);
 	truetype_subset->string_offsets = malloc (offsets_length);
 	if (truetype_subset->string_offsets == NULL) {
-	    status = CAIRO_STATUS_NO_MEMORY;
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto fail4;
 	}
 
@@ -1040,8 +1038,7 @@ _cairo_truetype_subset_init (cairo_truet
  fail1:
     cairo_truetype_font_destroy (font);
 
-    _cairo_error (status);
-    return status;
+    return _cairo_error (status);
 }
 
 void
@@ -1086,10 +1083,8 @@ _cairo_truetype_map_glyphs_to_unicode (c
 
     size = be16_to_cpu (map->length);
     map = malloc (size);
-    if (map == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (map == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (backend->load_truetype_table (font_subset->scaled_font,
                                       TT_TAG_cmap, table_offset,
@@ -1173,10 +1168,8 @@ _cairo_truetype_create_glyph_to_unicode_
     num_tables = be16_to_cpu (cmap->num_tables);
     size = 4 + num_tables*sizeof(tt_cmap_index_t);
     cmap = malloc (size);
-    if (cmap == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (cmap == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (backend->load_truetype_table (font_subset->scaled_font,
                                       TT_TAG_cmap, 0, (unsigned char *) cmap,
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index 564b4b0..7f91643 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -80,17 +80,14 @@ cairo_type1_font_create (cairo_scaled_fo
     cairo_font_options_t font_options;
 
     font = calloc (1, sizeof (cairo_type1_font_t));
-    if (font == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (font == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     font->widths = calloc (scaled_font_subset->num_glyphs,
                            sizeof (int));
     if (font->widths == NULL) {
 	free (font);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     font->scaled_font_subset = scaled_font_subset;
@@ -122,7 +119,7 @@ fail:
     free (font->widths);
     free (font);
 
-    return CAIRO_STATUS_NO_MEMORY;
+    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 }
 
 /* Charstring commands. If the high byte is 0 the command is encoded
@@ -592,7 +589,7 @@ cairo_type1_font_write_private_dict (cai
         NULL,
         font);
     if (encrypted_output == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail;
     }
 
@@ -732,13 +729,13 @@ _cairo_type1_fallback_init_internal (cai
 
     type1_subset->base_font = strdup (name);
     if (type1_subset->base_font == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto fail1;
     }
 
     type1_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
     if (type1_subset->widths == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto fail2;
     }
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
@@ -755,7 +752,7 @@ _cairo_type1_fallback_init_internal (cai
 	font->trailer_size;
     type1_subset->data = malloc (length);
     if (type1_subset->data == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail3;
     }
     memcpy (type1_subset->data,
@@ -784,8 +781,7 @@ _cairo_type1_fallback_init_internal (cai
     /* status is already set, ignore further errors */
     cairo_type1_font_destroy (font);
 
-    _cairo_error (status);
-    return status;
+    return _cairo_error (status);
 }
 
 cairo_status_t
@@ -833,7 +829,7 @@ _cairo_type2_charstrings_init (cairo_typ
 
     type2_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
     if (type2_subset->widths == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto fail1;
     }
 
@@ -877,8 +873,7 @@ fail2:
     _cairo_type2_charstrings_fini (type2_subset);
 fail1:
     cairo_type1_font_destroy (font);
-    _cairo_error (status);
-    return status;
+    return _cairo_error (status);
 }
 
 void
diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
index 793faf3..cbc4126 100644
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -120,7 +120,7 @@ _cairo_type1_font_subset_create (cairo_u
 
     face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
     if (!face)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (FT_Get_PS_Font_Info(face, &font_info) != 0) {
 	status = CAIRO_INT_STATUS_UNSUPPORTED;
@@ -129,7 +129,7 @@ _cairo_type1_font_subset_create (cairo_u
 
     font = calloc (sizeof (cairo_type1_font_subset_t), 1);
     if (font == NULL) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto fail1;
     }
 
@@ -143,7 +143,7 @@ _cairo_type1_font_subset_create (cairo_u
     font->base.descent = face->descender;
     font->base.base_font = strdup (face->family_name);
     if (font->base.base_font == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail2;
     }
 
@@ -156,7 +156,7 @@ _cairo_type1_font_subset_create (cairo_u
 
     font->glyphs = calloc (face->num_glyphs, sizeof font->glyphs[0]);
     if (font->glyphs == NULL) {
-        status = CAIRO_STATUS_NO_MEMORY;
+        status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail3;
     }
 
@@ -182,7 +182,7 @@ _cairo_type1_font_subset_create (cairo_u
     _cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);
 
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-	_cairo_error (status);
+	status = _cairo_error (status);
     return status;
 }
 
@@ -373,8 +373,8 @@ cairo_type1_font_subset_decrypt_eexec_se
 
     font->cleartext = malloc (font->eexec_segment_size);
     if (font->cleartext == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return font->status = CAIRO_STATUS_NO_MEMORY;
+	font->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return font->status;
     }
 
     out = font->cleartext;
@@ -445,7 +445,7 @@ cairo_type1_font_subset_get_glyph_names_
 			       FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
 	if (error != 0) {
 	    printf ("could not load glyph %d\n", i);
-	    return font->status = CAIRO_STATUS_NO_MEMORY;
+	    return font->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 
 	font->glyphs[i].width = font->face->glyph->metrics.horiAdvance;
@@ -453,12 +453,12 @@ cairo_type1_font_subset_get_glyph_names_
 	error = FT_Get_Glyph_Name(font->face, i, buffer, sizeof buffer);
 	if (error != 0) {
 	    printf ("could not get glyph name for glyph %d\n", i);
-	    return font->status = CAIRO_STATUS_NO_MEMORY;
+	    return font->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 
 	font->glyphs[i].name = strdup (buffer);
 	if (font->glyphs[i].name == NULL)
-	    return font->status = CAIRO_STATUS_NO_MEMORY;
+	    return font->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     return CAIRO_STATUS_SUCCESS;
@@ -720,7 +720,7 @@ cairo_type1_font_subset_look_for_seac(ca
 
     charstring = malloc (encrypted_charstring_length);
     if (charstring == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return;
     }
 
@@ -1054,12 +1054,12 @@ cairo_type1_font_subset_generate (void  
 
     font->face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);
     if (!font->face)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     font->type1_length = font->face->stream->size;
     font->type1_data = malloc (font->type1_length);
     if (font->type1_data == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	goto fail;
     }
 
@@ -1123,7 +1123,7 @@ _cairo_type1_subset_init (cairo_type1_su
 			  cairo_scaled_font_subset_t	*scaled_font_subset,
                           cairo_bool_t                   hex_encode)
 {
-    cairo_type1_font_subset_t *font;
+    cairo_type1_font_subset_t *font = NULL; /* hide compiler warning */
     cairo_status_t status;
     unsigned long parent_glyph, length;
     unsigned int i;
@@ -1197,7 +1197,7 @@ _cairo_type1_subset_init (cairo_type1_su
     cairo_type1_font_subset_destroy (font);
 
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-	_cairo_error (status);
+	status = _cairo_error (status);
     return status;
 }
 
diff --git a/src/cairo-unicode.c b/src/cairo-unicode.c
index 8ee6d24..2b224a3 100644
--- a/src/cairo-unicode.c
+++ b/src/cairo-unicode.c
@@ -231,20 +231,18 @@ _cairo_utf8_to_ucs4 (const unsigned char
     {
 	uint32_t wc = _utf8_get_char_extended (in, str + len - in);
 	if (wc & 0x80000000 || !UNICODE_VALID (wc))
-	    return CAIRO_STATUS_INVALID_STRING;
+	    return _cairo_error (CAIRO_STATUS_INVALID_STRING);
 
 	n_chars++;
 	if (n_chars == INT_MAX)
-	    return CAIRO_STATUS_INVALID_STRING;
+	    return _cairo_error (CAIRO_STATUS_INVALID_STRING);
 
 	in = UTF8_NEXT_CHAR (in);
     }
 
     str32 = _cairo_malloc_ab (n_chars + 1, sizeof (uint32_t));
-    if (!str32) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (!str32)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     in = str;
     for (i=0; i < n_chars; i++) {
@@ -296,7 +294,7 @@ _cairo_utf8_to_utf16 (const unsigned cha
     while ((len < 0 || str + len - in > 0) && *in) {
 	uint32_t wc = _utf8_get_char_extended (in, str + len - in);
 	if (wc & 0x80000000 || !UNICODE_VALID (wc))
-	    return CAIRO_STATUS_INVALID_STRING;
+	    return _cairo_error (CAIRO_STATUS_INVALID_STRING);
 
 	if (wc < 0x10000)
 	    n16 += 1;
@@ -304,16 +302,14 @@ _cairo_utf8_to_utf16 (const unsigned cha
 	    n16 += 2;
 
 	if (n16 == INT_MAX - 1 || n16 == INT_MAX)
-	    return CAIRO_STATUS_INVALID_STRING;
+	    return _cairo_error (CAIRO_STATUS_INVALID_STRING);
 
 	in = UTF8_NEXT_CHAR (in);
     }
 
     str16 = _cairo_malloc_ab (n16 + 1, sizeof (uint16_t));
-    if (!str16) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (!str16)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     in = str;
     for (i = 0; i < n16;) {
diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index a883490..9e6c340 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -455,7 +455,7 @@ _cairo_win32_scaled_font_select_unscaled
 
     hfont = _win32_scaled_font_get_unscaled_hfont ((cairo_win32_scaled_font_t *)scaled_font, hdc);
     if (!hfont)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     old_hfont = SelectObject (hdc, hfont);
     if (!old_hfont)
@@ -499,7 +499,7 @@ _cairo_win32_scaled_font_create_toy (cai
 
     if (face_name_len > LF_FACESIZE - 1) {
 	free (face_name);
-	return CAIRO_STATUS_INVALID_STRING;
+	return _cairo_error (CAIRO_STATUS_INVALID_STRING);
     }
 
     memcpy (logfont.lfFaceName, face_name, sizeof (uint16_t) * (face_name_len + 1));
@@ -544,12 +544,12 @@ _cairo_win32_scaled_font_create_toy (cai
     logfont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
 
     if (!logfont.lfFaceName)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     scaled_font = _win32_scaled_font_create (&logfont, NULL, &toy_face->base,
 					     font_matrix, ctm, options);
     if (!scaled_font)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     *scaled_font_out = scaled_font;
 
@@ -610,13 +610,13 @@ _cairo_win32_scaled_font_text_to_glyphs 
 
     buffer_size = MAX (n16 * 1.2, 16);		/* Initially guess number of chars plus a few */
     if (buffer_size > INT_MAX) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto FAIL1;
     }
 
     hdc = _get_global_font_dc ();
     if (!hdc) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto FAIL1;
     }
 
@@ -637,7 +637,7 @@ _cairo_win32_scaled_font_text_to_glyphs 
 	glyph_indices = _cairo_malloc_ab (buffer_size, sizeof (WCHAR));
 	dx = _cairo_malloc_ab (buffer_size, sizeof (int));
 	if (!glyph_indices || !dx) {
-	    status = CAIRO_STATUS_NO_MEMORY;
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto FAIL2;
 	}
 
@@ -660,7 +660,7 @@ _cairo_win32_scaled_font_text_to_glyphs 
 
 	buffer_size *= 1.5;
 	if (buffer_size > INT_MAX) {
-	    status = CAIRO_STATUS_NO_MEMORY;
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto FAIL2;
 	}
     }
@@ -668,7 +668,7 @@ _cairo_win32_scaled_font_text_to_glyphs 
     *num_glyphs = gcp_results.nGlyphs;
     *glyphs = _cairo_malloc_ab (gcp_results.nGlyphs, sizeof (cairo_glyph_t));
     if (!*glyphs) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto FAIL2;
     }
 
@@ -710,7 +710,7 @@ _cairo_win32_scaled_font_set_metrics (ca
 
     hdc = _get_global_font_dc ();
     if (!hdc)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (scaled_font->preserve_axes || scaled_font->base.options.hint_metrics == CAIRO_HINT_METRICS_OFF) {
 	/* For 90-degree rotations (including 0), we get the metrics
@@ -773,7 +773,7 @@ _cairo_win32_scaled_font_init_glyph_metr
 
     hdc = _get_global_font_dc ();
     if (!hdc)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (scaled_font->glyph_indexing)
         glyph_index_option = GGO_GLYPH_INDEX;
@@ -873,7 +873,7 @@ _cairo_win32_scaled_font_glyph_bbox (voi
         UINT glyph_index_option;
 
 	if (!hdc)
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);
 	if (status)
@@ -1215,7 +1215,7 @@ _cairo_win32_scaled_font_show_glyphs (vo
 
 	tmp_surface = (cairo_win32_surface_t *)cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, width, height);
 	if (tmp_surface->base.status)
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return tmp_surface->base.status;
 
 	r.left = 0;
 	r.top = 0;
@@ -1248,7 +1248,7 @@ _cairo_win32_scaled_font_show_glyphs (vo
 	    mask_surface = _compute_a8_mask (tmp_surface);
 	    cairo_surface_destroy (&tmp_surface->base);
 	    if (!mask_surface)
-		return CAIRO_STATUS_NO_MEMORY;
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 
 	/* For op == OVER, no-cleartype, a possible optimization here is to
@@ -1286,7 +1286,7 @@ _cairo_win32_scaled_font_load_truetype_t
     cairo_win32_scaled_font_t *scaled_font = abstract_font;
     hdc = _get_global_font_dc ();
     if (!hdc)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     tag = (tag&0x000000ff)<<24 | (tag&0x0000ff00)<<8 | (tag&0x00ff0000)>>8 | (tag&0xff000000)>>24;
     status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);
@@ -1345,11 +1345,11 @@ _cairo_win32_scaled_font_init_glyph_path
 
     hdc = _get_global_font_dc ();
     if (!hdc)
-        return CAIRO_STATUS_NO_MEMORY;
+        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     path = _cairo_path_fixed_create ();
     if (!path)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (scaled_font->base.options.hint_style == CAIRO_HINT_STYLE_NONE) {
         status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);
@@ -1379,7 +1379,7 @@ _cairo_win32_scaled_font_init_glyph_path
     ptr = buffer = malloc (bytesGlyph);
 
     if (!buffer) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP_FONT;
     }
 
@@ -1557,7 +1557,7 @@ _cairo_win32_font_face_scaled_font_creat
     if (*font)
 	return CAIRO_STATUS_SUCCESS;
     else
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 }
 
 static const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
@@ -1694,7 +1694,7 @@ cairo_win32_scaled_font_select_font (cai
 
     hfont = _win32_scaled_font_get_scaled_hfont ((cairo_win32_scaled_font_t *)scaled_font);
     if (!hfont)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     old_hfont = SelectObject (hdc, hfont);
     if (!old_hfont)
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 4b27a8d..7b94325 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -105,7 +105,7 @@ _cairo_win32_print_gdi_error (const char
      * is no CAIRO_STATUS_UNKNOWN_ERROR.
      */
 
-    return CAIRO_STATUS_NO_MEMORY;
+    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 }
 
 uint32_t
@@ -187,10 +187,8 @@ _create_dc_and_bitmap (cairo_win32_surfa
 
     if (num_palette > 2) {
 	bitmap_info = _cairo_malloc_ab_plus_c (num_palette, sizeof(RGBQUAD), sizeof(BITMAPINFOHEADER));
-	if (!bitmap_info) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (!bitmap_info)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     } else {
 	bitmap_info = (BITMAPINFO *)&bmi_stack;
     }
@@ -349,7 +347,7 @@ _cairo_win32_surface_create_for_dc (HDC 
     surface->image = cairo_image_surface_create_for_data (bits, format,
 							  width, height, rowstride);
     if (surface->image->status) {
-	status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto FAIL;
     }
 
@@ -517,7 +515,7 @@ _cairo_win32_surface_get_subimage (cairo
 	(cairo_win32_surface_t *) _cairo_win32_surface_create_similar_internal
 	(surface, content, width, height, TRUE);
     if (local->base.status)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = CAIRO_INT_STATUS_UNSUPPORTED;
 
@@ -1452,6 +1450,7 @@ _cairo_win32_surface_set_clip_region (vo
     } else {
 	cairo_rectangle_int_t extents;
 	cairo_box_int_t *boxes;
+	cairo_status_t status;
 	int num_boxes;
 	RGNDATA *data;
 	size_t data_size;
@@ -1462,15 +1461,15 @@ _cairo_win32_surface_set_clip_region (vo
 	/* Create a GDI region for the cairo region */
 
 	_cairo_region_get_extents (region, &extents);
-	if (_cairo_region_get_boxes (region, &num_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
-	    return CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
+	if (status)
+	    return status;
 
 	data_size = sizeof (RGNDATAHEADER) + num_boxes * sizeof (RECT);
 	data = malloc (data_size);
 	if (!data) {
 	    _cairo_region_boxes_fini (region, boxes);
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 	rects = (RECT *)data->Buffer;
 
@@ -1496,7 +1495,7 @@ _cairo_win32_surface_set_clip_region (vo
 	free (data);
 
 	if (!gdi_region)
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	/* Combine the new region with the original clip */
 
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index d5c27d6..451cc8f 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -398,7 +398,7 @@ _get_image_surface (cairo_xcb_surface_t 
 
     }
     if (!imagerep)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     bpp = _bits_per_pixel(surface->dpy, imagerep->depth);
     bytes_per_line = _bytes_per_line(surface->dpy, surface->width, bpp);
@@ -406,8 +406,7 @@ _get_image_surface (cairo_xcb_surface_t 
     data = _cairo_malloc_ab (surface->height, bytes_per_line);
     if (data == NULL) {
 	free (imagerep);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     memcpy (data, xcb_get_image_data (imagerep), bytes_per_line * surface->height);
@@ -480,7 +479,7 @@ _get_image_surface (cairo_xcb_surface_t 
 
  FAIL:
     free (data);
-    return CAIRO_STATUS_NO_MEMORY;
+    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 }
 
 static void
@@ -592,7 +591,8 @@ _draw_image_surface (cairo_xcb_surface_t
 	data_len = height * data_bpl;
 	data_line = data = malloc(data_len);
 	if (data == NULL)
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
 	image_line = image->data + src_y * bpl + (src_x * bpp / 8);
 	while (line++ < height) {
 	    memcpy(data_line, image_line, data_bpl);
@@ -721,7 +721,7 @@ _cairo_xcb_surface_clone_similar (void		
 	    _cairo_xcb_surface_create_similar (surface, content,
 					       image_src->width, image_src->height);
 	if (clone->base.status)
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return clone->base.status;
 
 	_draw_image_surface (clone, image_src, src_x, src_y,
 			     width, height, src_x, src_y);
@@ -1266,10 +1266,8 @@ _cairo_xcb_surface_fill_rectangles (void
 
     if (num_rects > ARRAY_LENGTH(static_xrects)) {
         xrects = _cairo_malloc_ab (num_rects, sizeof(xcb_rectangle_t));
-	if (xrects == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (xrects == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     for (i = 0; i < num_rects; i++) {
@@ -1468,7 +1466,7 @@ _cairo_xcb_surface_composite_trapezoids 
 						       dst_x, dst_y, width, height,
 						       render_format);
 	if (!mask_picture) {
-	    status = CAIRO_STATUS_NO_MEMORY;
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto BAIL;
 	}
 
@@ -1500,8 +1498,7 @@ _cairo_xcb_surface_composite_trapezoids 
         if (num_traps > ARRAY_LENGTH(xtraps_stack)) {
             xtraps = _cairo_malloc_ab (num_traps, sizeof(xcb_render_trapezoid_t));
             if (xtraps == NULL) {
-                status = CAIRO_STATUS_NO_MEMORY;
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
+                status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
                 goto BAIL;
             }
         }
@@ -1561,18 +1558,19 @@ _cairo_xcb_surface_set_clip_region (void
 		XCB_RENDER_CP_CLIP_MASK, none);
     } else {
 	cairo_box_int_t *boxes;
+	cairo_status_t status;
 	xcb_rectangle_t *rects = NULL;
 	int n_boxes, i;
 
-        if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
-            return CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_region_get_boxes (region, &n_boxes, &boxes);
+        if (status)
+            return status;
 
 	if (n_boxes > 0) {
 	    rects = _cairo_malloc_ab (n_boxes, sizeof(xcb_rectangle_t));
 	    if (rects == NULL) {
                 _cairo_region_boxes_fini (region, boxes);
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
-		return CAIRO_STATUS_NO_MEMORY;
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
             }
 	} else {
 	    rects = NULL;
@@ -1996,10 +1994,8 @@ _cairo_xcb_surface_font_init (xcb_connec
     cairo_xcb_surface_font_private_t	*font_private;
 
     font_private = malloc (sizeof (cairo_xcb_surface_font_private_t));
-    if (!font_private) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (!font_private)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     font_private->dpy = dpy;
     font_private->format = format;
@@ -2117,8 +2113,7 @@ _cairo_xcb_surface_add_glyph (xcb_connec
 
 	    new = malloc (c);
 	    if (!new) {
-		status = CAIRO_STATUS_NO_MEMORY;
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
+		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		goto BAIL;
 	    }
 	    n = new;
@@ -2144,8 +2139,7 @@ _cairo_xcb_surface_add_glyph (xcb_connec
 
 	    new = malloc (c);
 	    if (new == NULL) {
-		status = CAIRO_STATUS_NO_MEMORY;
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
+		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		goto BAIL;
 	    }
 	    n = new;
@@ -2385,10 +2379,8 @@ _cairo_xcb_surface_show_glyphs (void    
      * glyphs to workaround an X server bug, (present in at least Xorg
      * 7.1 without EXA). */
     output_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
-    if (output_glyphs == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (output_glyphs == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     /* After passing all those tests, we're now committed to rendering
      * these glyphs or to fail trying. We first upload any glyphs to
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index 6e8f2ba..83170f5 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -252,7 +252,7 @@ _cairo_xlib_display_get (Display *dpy)
 
     display = malloc (sizeof (cairo_xlib_display_t));
     if (display == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	goto UNLOCK;
     }
 
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 65e2d6a..e67a5f9 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -172,7 +172,7 @@ _cairo_xlib_surface_create_similar_with_
 						       width, height);
     if (surface->base.status != CAIRO_STATUS_SUCCESS) {
 	XFreePixmap (dpy, pix);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -252,7 +252,7 @@ _cairo_xlib_surface_create_similar (void
 						       width, height);
     if (surface->base.status != CAIRO_STATUS_SUCCESS) {
 	XFreePixmap (src->dpy, pix);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -558,7 +558,7 @@ _get_image_surface (cairo_xlib_surface_t
 	}
     }
     if (!ximage)
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     _swap_ximage_to_native (ximage);
 
@@ -615,7 +615,7 @@ _get_image_surface (cairo_xlib_surface_t
 
  FAIL:
     XDestroyImage (ximage);
-    return CAIRO_STATUS_NO_MEMORY;
+    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 }
 
 static void
@@ -694,7 +694,7 @@ _cairo_xlib_surface_ensure_gc (cairo_xli
 	    surface->gc = XCreateGC (surface->dpy, surface->drawable,
 				     GCGraphicsExposures, &gcv);
 	    if (!surface->gc)
-		return CAIRO_STATUS_NO_MEMORY;
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 
 	_cairo_xlib_surface_set_gc_clip_rects (surface);
@@ -863,7 +863,7 @@ _cairo_xlib_surface_clone_similar (void	
 	    _cairo_xlib_surface_create_similar_with_format (surface, image_src->format,
 						image_src->width, image_src->height);
 	if (clone->base.status)
-	    return CAIRO_STATUS_NO_MEMORY;
+	    return clone->base.status;
 
 	status = _draw_image_surface (clone, image_src, src_x, src_y,
 			              width, height, src_x, src_y);
@@ -1445,10 +1445,8 @@ _cairo_xlib_surface_fill_rectangles (voi
 
     if (num_rects > ARRAY_LENGTH(static_xrects)) {
         xrects = _cairo_malloc_ab (num_rects, sizeof(XRectangle));
-	if (xrects == NULL) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	if (xrects == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     for (i = 0; i < num_rects; i++) {
@@ -1536,7 +1534,7 @@ _create_trapezoid_mask (cairo_xlib_surfa
     offset_traps = _cairo_malloc_ab (num_traps, sizeof (XTrapezoid));
     if (!offset_traps) {
 	XRenderFreePicture (dst->dpy, mask_picture);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return None;
     }
 
@@ -1654,7 +1652,7 @@ _cairo_xlib_surface_composite_trapezoids
 						       dst_x, dst_y, width, height,
 						       pict_format);
 	if (!mask_picture) {
-	    status = CAIRO_STATUS_NO_MEMORY;
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto BAIL;
 	}
 
@@ -1686,8 +1684,7 @@ _cairo_xlib_surface_composite_trapezoids
         if (num_traps > ARRAY_LENGTH(xtraps_stack)) {
             xtraps = _cairo_malloc_ab (num_traps, sizeof(XTrapezoid));
             if (xtraps == NULL) {
-                status = CAIRO_STATUS_NO_MEMORY;
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
+                status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
                 goto BAIL;
             }
         }
@@ -1742,18 +1739,19 @@ _cairo_xlib_surface_set_clip_region (voi
 
     if (region != NULL) {
 	cairo_box_int_t *boxes;
+	cairo_status_t status;
 	XRectangle *rects = NULL;
 	int n_boxes, i;
 
-        if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
-            return CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_region_get_boxes (region, &n_boxes, &boxes);
+        if (status)
+            return status;
 
 	if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) {
 	    rects = _cairo_malloc_ab (n_boxes, sizeof(XRectangle));
 	    if (rects == NULL) {
                 _cairo_region_boxes_fini (region, boxes);
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
-		return CAIRO_STATUS_NO_MEMORY;
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
             }
 	} else {
 	    rects = surface->embedded_clip_rects;
@@ -1942,14 +1940,14 @@ _cairo_xlib_surface_create_internal (Dis
 
     screen_info = _cairo_xlib_screen_info_get (dpy, screen);
     if (screen_info == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
     surface = malloc (sizeof (cairo_xlib_surface_t));
     if (surface == NULL) {
 	_cairo_xlib_screen_info_destroy (screen_info);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -1957,7 +1955,7 @@ _cairo_xlib_surface_create_internal (Dis
 	    _cairo_xlib_surface_detach_display, surface, surface)) {
 	free (surface);
 	_cairo_xlib_screen_info_destroy (screen_info);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -2096,7 +2094,7 @@ cairo_xlib_surface_create (Display     *
     Screen *screen = _cairo_xlib_screen_from_visual (dpy, visual);
 
     if (screen == NULL) {
-	_cairo_error (CAIRO_STATUS_INVALID_VISUAL);
+	_cairo_error_throw (CAIRO_STATUS_INVALID_VISUAL);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
@@ -2185,10 +2183,11 @@ cairo_xlib_surface_set_size (cairo_surfa
 			     int              height)
 {
     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
+    cairo_status_t status;
 
     if (! _cairo_surface_is_xlib (abstract_surface)) {
-	_cairo_surface_set_error (abstract_surface,
-				  CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	status = _cairo_surface_set_error (abstract_surface,
+		                           CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return;
     }
 
@@ -2219,7 +2218,8 @@ cairo_xlib_surface_set_drawable (cairo_s
     cairo_status_t status;
 
     if (! _cairo_surface_is_xlib (abstract_surface)) {
-	_cairo_surface_set_error (abstract_surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	status = _cairo_surface_set_error (abstract_surface,
+		                           CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return;
     }
 
@@ -2234,7 +2234,7 @@ cairo_xlib_surface_set_drawable (cairo_s
 						  XRenderFreePicture,
 						  surface->dst_picture);
 	    if (status) {
-		_cairo_surface_set_error (&surface->base, status);
+		status = _cairo_surface_set_error (&surface->base, status);
 		return;
 	    }
 
@@ -2247,7 +2247,7 @@ cairo_xlib_surface_set_drawable (cairo_s
 						  XRenderFreePicture,
 						  surface->src_picture);
 	    if (status) {
-		_cairo_surface_set_error (&surface->base, status);
+		status = _cairo_surface_set_error (&surface->base, status);
 		return;
 	    }
 
@@ -2276,7 +2276,7 @@ cairo_xlib_surface_get_display (cairo_su
     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
 
     if (! _cairo_surface_is_xlib (abstract_surface)) {
-	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return NULL;
     }
 
@@ -2299,7 +2299,7 @@ cairo_xlib_surface_get_drawable (cairo_s
     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
 
     if (! _cairo_surface_is_xlib (abstract_surface)) {
-	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return 0;
     }
 
@@ -2322,7 +2322,7 @@ cairo_xlib_surface_get_screen (cairo_sur
     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
 
     if (! _cairo_surface_is_xlib (abstract_surface)) {
-	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return NULL;
     }
 
@@ -2345,7 +2345,7 @@ cairo_xlib_surface_get_visual (cairo_sur
     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
 
     if (! _cairo_surface_is_xlib (abstract_surface)) {
-	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return NULL;
     }
 
@@ -2368,7 +2368,7 @@ cairo_xlib_surface_get_depth (cairo_surf
     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
 
     if (! _cairo_surface_is_xlib (abstract_surface)) {
-	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return 0;
     }
 
@@ -2391,7 +2391,7 @@ cairo_xlib_surface_get_width (cairo_surf
     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
 
     if (! _cairo_surface_is_xlib (abstract_surface)) {
-	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return -1;
     }
 
@@ -2414,7 +2414,7 @@ cairo_xlib_surface_get_height (cairo_sur
     cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
 
     if (! _cairo_surface_is_xlib (abstract_surface)) {
-	_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return -1;
     }
 
@@ -2456,17 +2456,14 @@ _cairo_xlib_surface_font_init (Display		
     cairo_xlib_surface_font_private_t	*font_private;
 
     font_private = malloc (sizeof (cairo_xlib_surface_font_private_t));
-    if (!font_private) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
+    if (!font_private)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (!_cairo_xlib_add_close_display_hook (dpy,
 		_cairo_xlib_surface_remove_scaled_font,
 		scaled_font, scaled_font)) {
 	free (font_private);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
 
@@ -2624,7 +2621,7 @@ _cairo_xlib_surface_add_glyph (Display *
 
 	    new = malloc (c);
 	    if (!new) {
-		status = CAIRO_STATUS_NO_MEMORY;
+		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		goto BAIL;
 	    }
 	    n = new;
@@ -2650,8 +2647,7 @@ _cairo_xlib_surface_add_glyph (Display *
 
 	    new = malloc (c);
 	    if (new == NULL) {
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
-		status = CAIRO_STATUS_NO_MEMORY;
+		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		goto BAIL;
 	    }
 	    n = new;
@@ -2778,10 +2774,8 @@ _cairo_xlib_surface_emit_glyphs_chunk (c
       elts = stack_elts;
     } else {
       elts = _cairo_malloc_ab (num_elts, sizeof (XGlyphElt8));
-      if (elts == NULL) {
-	  _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	  return CAIRO_STATUS_NO_MEMORY;
-      }
+      if (elts == NULL)
+	  return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     /* Fill them in */
diff --git a/src/cairo.c b/src/cairo.c
index 5273cb0..ef628e7 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -118,7 +118,7 @@ _cairo_set_error (cairo_t *cr, cairo_sta
      * error, which is the most significant. */
     _cairo_status_set_error (&cr->status, status);
 
-    _cairo_error (status);
+    status = _cairo_error (status);
 }
 
 /**
@@ -199,7 +199,7 @@ cairo_create (cairo_surface_t *target)
 
     cr = malloc (sizeof (cairo_t));
     if (cr == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_t *) &_cairo_nil;
     }
 
@@ -327,7 +327,7 @@ cairo_set_user_data (cairo_t			 *cr,
 		     cairo_destroy_func_t	 destroy)
 {
     if (CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count))
-	return CAIRO_STATUS_NO_MEMORY;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return _cairo_user_data_array_set_data (&cr->user_data,
 					    key, user_data, destroy);
@@ -2419,7 +2419,7 @@ _cairo_rectangle_list_create_in_error (c
 
     list = malloc (sizeof (cairo_rectangle_list_t));
     if (list == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
     }
 
diff --git a/src/cairoint.h b/src/cairoint.h
index cb764d2..7382292 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1623,7 +1623,7 @@ extern const cairo_private cairo_surface
 extern const cairo_private cairo_surface_t _cairo_surface_nil_write_error;
 extern const cairo_private cairo_surface_t _cairo_surface_nil_file_not_found;
 
-cairo_private void
+cairo_private cairo_status_t
 _cairo_surface_set_error (cairo_surface_t	*surface,
 			  cairo_status_t	 status);
 
@@ -2302,6 +2302,12 @@ _cairo_utf8_to_utf16 (const unsigned cha
 cairo_private cairo_status_t
 _cairo_error (cairo_status_t status);
 
+/* hide compiler warnings when discarding the return value */
+#define _cairo_error_throw(status) do { \
+    cairo_status_t status__ = _cairo_error (status); \
+    (void) status__; \
+} while (0)
+
 /* Avoid unnecessary PLT entries.  */
 slim_hidden_proto (cairo_clip_preserve);
 slim_hidden_proto (cairo_close_path);
diff --git a/src/test-fallback-surface.c b/src/test-fallback-surface.c
index db25874..3db945d 100644
--- a/src/test-fallback-surface.c
+++ b/src/test-fallback-surface.c
@@ -81,7 +81,7 @@ _cairo_test_fallback_surface_create (cai
     surface = malloc (sizeof (test_fallback_surface_t));
     if (surface == NULL) {
 	cairo_surface_destroy (backing);
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
diff --git a/src/test-meta-surface.c b/src/test-meta-surface.c
index 82fde5f..773d011 100644
--- a/src/test-meta-surface.c
+++ b/src/test-meta-surface.c
@@ -76,10 +76,8 @@ _cairo_test_meta_surface_create (cairo_c
     test_meta_surface_t *surface;
 
     surface = malloc (sizeof (test_meta_surface_t));
-    if (surface == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+    if (surface == NULL)
 	goto FAIL;
-    }
 
     _cairo_surface_init (&surface->base, &test_meta_surface_backend,
 			 content);
@@ -102,7 +100,7 @@ _cairo_test_meta_surface_create (cairo_c
   FAIL_CLEANUP_SURFACE:
     free (surface);
   FAIL:
-    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
     return (cairo_surface_t*) &_cairo_surface_nil;
 }
 
diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c
index 1e08c2d..3e9bad8 100644
--- a/src/test-paginated-surface.c
+++ b/src/test-paginated-surface.c
@@ -75,14 +75,12 @@ _cairo_test_paginated_surface_create_for
 								width, height,
 								stride);
     status = cairo_surface_status (target);
-    if (status) {
-	_cairo_error (status);
+    if (status)
 	return (cairo_surface_t *) &_cairo_surface_nil;
-    }
 
     surface = malloc (sizeof (test_paginated_surface_t));
     if (surface == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t *) &_cairo_surface_nil;
     }
 
diff-tree d90d4bb6b99e0a912650234e28d097ea76c1cecc (from 71120727e190dfaf3ccbe63b3d91d90e36cff6f6)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 4 11:30:13 2007 +0100

    [cairo-error] Make _cairo_error() return the error status.
    
    As pointed out by Jeff Muizelaar, this allows for more concise code, as
        _cairo_error(CAIRO_STATUS_NO_MEMORY)
        return CAIRO_STATUS_NO_MEMORY
    can become
        return _cairo_error(CAIRO_STATUS_NO_MEMORY);

diff --git a/src/cairo.c b/src/cairo.c
index bea91e4..5273cb0 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -83,12 +83,16 @@ static const cairo_t _cairo_nil = {
  * The purpose of this function is to allow the user to set a
  * breakpoint in _cairo_error() to generate a stack trace for when the
  * user causes cairo to detect an error.
+ *
+ * Return value: the error status.
  **/
-void
+cairo_status_t
 _cairo_error (cairo_status_t status)
 {
     assert (status > CAIRO_STATUS_SUCCESS &&
 	    status <= CAIRO_STATUS_LAST_STATUS);
+
+    return status;
 }
 
 /**
diff --git a/src/cairoint.h b/src/cairoint.h
index be7079c..cb764d2 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2299,7 +2299,7 @@ _cairo_utf8_to_utf16 (const unsigned cha
 		      uint16_t		 **result,
 		      int		  *items_written);
 
-cairo_private void
+cairo_private cairo_status_t
 _cairo_error (cairo_status_t status);
 
 /* Avoid unnecessary PLT entries.  */
diff-tree 71120727e190dfaf3ccbe63b3d91d90e36cff6f6 (from f4356efb64a043e7a459fe77616f3b7c92b25c49)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Oct 4 11:13:33 2007 +0100

    [cairo-atomic] Use an atomic operation to set the status on a shared resource.
    
    Since the objects can be shared and may be in use simultaneously across
    multiple threads, setting the status needs to be atomic. We use a
    locked compare and exchange in order to avoid overwriting an existing
    error - that is we use an atomic operation that only sets the new status
    value if the current value is CAIRO_STATUS_SUCCESS.

diff --git a/src/cairo-atomic-private.h b/src/cairo-atomic-private.h
index 3577e0d..3bf4e27 100644
--- a/src/cairo-atomic-private.h
+++ b/src/cairo-atomic-private.h
@@ -54,6 +54,8 @@ typedef int cairo_atomic_int_t;
 # define _cairo_atomic_int_get(x) (*x)
 # define _cairo_atomic_int_set(x, value) ((*x) = value)
 
+# define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
+
 #else
 
 # include "cairo-compiler-private.h"
@@ -74,8 +76,14 @@ _cairo_atomic_int_get (int *x);
 cairo_private void
 _cairo_atomic_int_set (int *x, int value);
 
+cairo_private int
+_cairo_atomic_int_cmpxchg (int *x, int oldv, int newv);
+
 #endif
 
+#define _cairo_status_set_error(status, err) \
+    (void) _cairo_atomic_int_cmpxchg (status, CAIRO_STATUS_SUCCESS, err)
+
 CAIRO_END_DECLS
 
 #endif
diff --git a/src/cairo-atomic.c b/src/cairo-atomic.c
index 9941548..f9e4de7 100644
--- a/src/cairo-atomic.c
+++ b/src/cairo-atomic.c
@@ -76,4 +76,19 @@ _cairo_atomic_int_set (int *x, int value
     *x = value;
     CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
 }
+
+int
+_cairo_atomic_int_cmpxchg (int *x, int oldv, int newv)
+{
+    int ret;
+
+    CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
+    ret = *x;
+    if (ret == oldv)
+	*x = newv;
+    CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
+
+    return ret;
+}
+
 #endif
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index eac7e4b..a7e804e 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -66,11 +66,12 @@ const cairo_solid_pattern_t cairo_patter
  * @status: a status value indicating an error, (eg. not
  * CAIRO_STATUS_SUCCESS)
  *
- * Sets pattern->status to @status and calls _cairo_error;
+ * Atomically sets pattern->status to @status and calls _cairo_error;
  *
  * All assignments of an error status to pattern->status should happen
- * through _cairo_pattern_set_error() or else _cairo_error() should be
- * called immediately after the assignment.
+ * through _cairo_pattern_set_error(). Note that due to the nature of
+ * the atomic operation, it is not safe to call this function on the nil
+ * objects.
  *
  * The purpose of this function is to allow the user to set a
  * breakpoint in _cairo_error() to generate a stack trace for when the
@@ -81,10 +82,8 @@ _cairo_pattern_set_error (cairo_pattern_
 			  cairo_status_t status)
 {
     /* Don't overwrite an existing error. This preserves the first
-     * error, which is the most significant. It also avoids attempting
-     * to write to read-only data (eg. from a nil pattern). */
-    if (pattern->status == CAIRO_STATUS_SUCCESS)
-	pattern->status = status;
+     * error, which is the most significant. */
+    _cairo_status_set_error (&pattern->status, status);
 
     _cairo_error (status);
 }
@@ -345,8 +344,8 @@ _cairo_pattern_create_in_error (cairo_st
 
     pattern = _cairo_pattern_create_solid (_cairo_stock_color (CAIRO_STOCK_BLACK),
 					   CAIRO_CONTENT_COLOR);
-    /* no-op on a pattern already in error i.e the _cairo_pattern_nil */
-    _cairo_pattern_set_error (pattern, status);
+    if (pattern->status == CAIRO_STATUS_SUCCESS)
+	_cairo_pattern_set_error (pattern, status);
 
     return pattern;
 }
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 282a486..08d426f 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -204,11 +204,12 @@ const cairo_scaled_font_t _cairo_scaled_
  * @status: a status value indicating an error, (eg. not
  * CAIRO_STATUS_SUCCESS)
  *
- * Sets scaled_font->status to @status and calls _cairo_error;
+ * Atomically sets scaled_font->status to @status and calls _cairo_error;
  *
  * All assignments of an error status to scaled_font->status should happen
- * through _cairo_scaled_font_set_error() or else _cairo_error() should be
- * called immediately after the assignment.
+ * through _cairo_scaled_font_set_error(). Note that due to the nature of
+ * the atomic operation, it is not safe to call this function on the nil
+ * objects.
  *
  * The purpose of this function is to allow the user to set a
  * breakpoint in _cairo_error() to generate a stack trace for when the
@@ -219,10 +220,8 @@ _cairo_scaled_font_set_error (cairo_scal
 			      cairo_status_t status)
 {
     /* Don't overwrite an existing error. This preserves the first
-     * error, which is the most significant. It also avoids attempting
-     * to write to read-only data (eg. from a nil scaled_font). */
-    if (scaled_font->status == CAIRO_STATUS_SUCCESS)
-	scaled_font->status = status;
+     * error, which is the most significant. */
+    _cairo_status_set_error (&scaled_font->status, status);
 
     _cairo_error (status);
 }
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index b5fcc64..8697689 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -94,11 +94,12 @@ _cairo_surface_copy_pattern_for_destinat
  * @status: a status value indicating an error, (eg. not
  * CAIRO_STATUS_SUCCESS)
  *
- * Sets surface->status to @status and calls _cairo_error;
+ * Atomically sets surface->status to @status and calls _cairo_error;
  *
  * All assignments of an error status to surface->status should happen
- * through _cairo_surface_set_error() or else _cairo_error() should be
- * called immediately after the assignment.
+ * through _cairo_surface_set_error(). Note that due to the nature of
+ * the atomic operation, it is not safe to call this function on the
+ * nil objects.
  *
  * The purpose of this function is to allow the user to set a
  * breakpoint in _cairo_error() to generate a stack trace for when the
@@ -109,10 +110,8 @@ _cairo_surface_set_error (cairo_surface_
 			  cairo_status_t status)
 {
     /* Don't overwrite an existing error. This preserves the first
-     * error, which is the most significant. It also avoids attempting
-     * to write to read-only data (eg. from a nil surface). */
-    if (surface->status == CAIRO_STATUS_SUCCESS)
-	surface->status = status;
+     * error, which is the most significant. */
+    _cairo_status_set_error (&surface->status, status);
 
     _cairo_error (status);
 }
diff --git a/src/cairo.c b/src/cairo.c
index 4a1c73b..bea91e4 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -97,11 +97,11 @@ _cairo_error (cairo_status_t status)
  * @status: a status value indicating an error, (eg. not
  * CAIRO_STATUS_SUCCESS)
  *
- * Sets cr->status to @status and calls _cairo_error;
+ * Atomically sets cr->status to @status and calls _cairo_error;
  *
  * All assignments of an error status to cr->status should happen
- * through _cairo_set_error() or else _cairo_error() should be
- * called immediately after the assignment.
+ * through _cairo_set_error(). Note that due to the nature of the atomic
+ * operation, it is not safe to call this function on the nil objects.
  *
  * The purpose of this function is to allow the user to set a
  * breakpoint in _cairo_error() to generate a stack trace for when the
@@ -111,10 +111,8 @@ static void
 _cairo_set_error (cairo_t *cr, cairo_status_t status)
 {
     /* Don't overwrite an existing error. This preserves the first
-     * error, which is the most significant. It also avoids attempting
-     * to write to read-only data (eg. from a nil cairo_t). */
-    if (cr->status == CAIRO_STATUS_SUCCESS)
-	cr->status = status;
+     * error, which is the most significant. */
+    _cairo_status_set_error (&cr->status, status);
 
     _cairo_error (status);
 }


More information about the cairo-commit mailing list