diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index 2cf5c8d..5e8d0f9 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,3 +1,14 @@
+2013-10-22  David Malcolm  <dmalcolm@redhat.com>
+
+	* internal-api.c (gcc::jit::context::add_error_va): Record the
+	first error that occurs on a context.
+	(gcc::jit::context::get_first_error): New.
+	* internal-api.h (gcc::jit::context::get_first_error): New.
+	(gcc::jit::context::m_first_error_str): New.
+	* libgccjit.c (gcc_jit_context_get_first_error): New.
+	* libgccjit.h (gcc_jit_context_get_first_error): New.
+	* libgccjit.map (gcc_jit_context_get_first_error): New.
+
 2013-10-21  David Malcolm  <dmalcolm@redhat.com>
 
 	* internal-api.c (gcc::jit::context::compile): Correctly cleanup
diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c
index d90f001..639cd49 100644
--- a/gcc/jit/internal-api.c
+++ b/gcc/jit/internal-api.c
@@ -1478,9 +1478,25 @@ add_error_va (const char *fmt, va_list ap)
 
   error ("%s\n", buf);
 
+  if (!m_error_count)
+    {
+      strncpy (m_first_error_str, buf, sizeof(m_first_error_str));
+      m_first_error_str[sizeof(m_first_error_str) - 1] = '\0';
+    }
+
   m_error_count++;
 }
 
+const char *
+gcc::jit::context::
+get_first_error () const
+{
+  if (m_error_count)
+    return m_first_error_str;
+  else
+    return NULL;
+}
+
 gcc::jit::result::
 result(void *dso_handle)
   : m_dso_handle(dso_handle)
diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h
index 1a8499f..01f0bb3 100644
--- a/gcc/jit/internal-api.h
+++ b/gcc/jit/internal-api.h
@@ -158,6 +158,9 @@ public:
   add_error_va (const char *fmt, va_list ap)
       GNU_PRINTF(2, 0);
 
+  const char *
+  get_first_error () const;
+
   void
   set_tree_location (tree t, location *loc);
 
@@ -193,6 +196,8 @@ private:
   void *m_user_data;
 
   int m_error_count;
+  char m_first_error_str[1024];
+  int m_cb_result; /* Result from client-provided code factory.  */
 
   /* Allocated using xmalloc (by xstrdup).  */
   char *m_path_template;
@@ -205,7 +210,6 @@ private:
   char *m_path_s_file;
   char *m_path_so_file;
 
-  int m_cb_result; /* Result from client-provided code factory.  */
   vec<function *> m_functions;
   const char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
   int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index 40ac98d..3222144 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -726,6 +726,14 @@ gcc_jit_context_compile (gcc_jit_context *ctxt)
   return (gcc_jit_result *)ctxt->compile ();
 }
 
+const char *
+gcc_jit_context_get_first_error (gcc_jit_context *ctxt)
+{
+  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
+
+  return ctxt->get_first_error ();
+}
+
 void *
 gcc_jit_result_get_code (gcc_jit_result *result,
 			 const char *fnname)
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 12a715d..f058162 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -216,6 +216,15 @@ gcc_jit_context_set_bool_option (gcc_jit_context *ctxt,
 extern gcc_jit_result *
 gcc_jit_context_compile (gcc_jit_context *ctxt);
 
+/* To be called after a compile, this gives the first error message
+   that occurred on the context.
+
+   The returned string is valid for the rest of the lifetime of the
+   context.
+
+   If no errors occurred, this will be NULL.  */
+extern const char *
+gcc_jit_context_get_first_error (gcc_jit_context *ctxt);
 
 /* Locate a given function within the built machine code.
    This will need to be cast to a function pointer of the
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index e2503e4..aaa2112 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -4,6 +4,7 @@
     # Keep this list sorted alphabetically:
     gcc_jit_context_acquire;
     gcc_jit_context_compile;
+    gcc_jit_context_get_first_error;
     gcc_jit_context_get_type;
     gcc_jit_context_new_array_lookup;
     gcc_jit_context_new_binary_op;
diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit
index 7190e09..0476507 100644
--- a/gcc/testsuite/ChangeLog.jit
+++ b/gcc/testsuite/ChangeLog.jit
@@ -1,3 +1,32 @@
+2013-10-22  David Malcolm  <dmalcolm@redhat.com>
+
+	* jit.dg/harness.h (verify_code): Add context param so that
+	test cases of failure can query errors on it.
+	(CHECK_STRING_VALUE): New.
+	(check_string_value): New.
+	(test_jit): Add user_data param and pass it to the code factory.
+	Pass context to verify_code, calling it before releasing said
+	context.
+	(main): Add NULL user_data to test_jit call.
+	* jit.dg/test-accessing-struct.c (verify_code): Add context
+	param.
+	* jit.dg/test-calling-external-function.c (verify_code):
+	Likewise.
+	* jit.dg/test-combination.c (verify_code): Likewise.
+	* jit.dg/test-dot-product.c (verify_code): Likewise.
+	* jit.dg/test-expressions.c (verify_code): Likewise.
+	* jit.dg/test-factorial.c (verify_code): Likewise.
+	* jit.dg/test-failure.c (verify_code): Likewise.
+	* jit.dg/test-fibonacci.c (verify_code): Likewise.
+	* jit.dg/test-hello-world.c (verify_code): Likewise.
+	* jit.dg/test-string-literal.c (verify_code): Likewise.
+	* jit.dg/test-sum-of-squares.c (verify_code): Likewise.
+	* jit.dg/test-types.c (verify_code): Likewise.
+	* jit.dg/test-using-global.c (verify_code): Likewise.
+	* jit.dg/test-null-passed-to-api.c (verify_code): Likewise;
+	use context to verify that the library provides a sane error
+	message to the client code.
+
 2013-10-21  David Malcolm  <dmalcolm@redhat.com>
 
 	* jit.dg/test-expressions.c (test_global): New.
diff --git a/gcc/testsuite/jit.dg/harness.h b/gcc/testsuite/jit.dg/harness.h
index 4ffbcbf..8e75924 100644
--- a/gcc/testsuite/jit.dg/harness.h
+++ b/gcc/testsuite/jit.dg/harness.h
@@ -8,7 +8,7 @@
     code_making_callback (gcc_jit_context *ctxt, void * user_data);
 
     extern void
-    verify_code (gcc_jit_result *result);
+    verify_code (gcc_jit_context *ctxt, gcc_jit_result *result);
 
  */
 #include <stdlib.h>
@@ -47,12 +47,15 @@ static char test[1024];
     }                                        \
   } while (0)
 
+#define CHECK_STRING_VALUE(ACTUAL, EXPECTED) \
+  check_string_value ((ACTUAL), (EXPECTED));
+
 /* Hooks that testcases should provide.  */
 extern int
 code_making_callback (gcc_jit_context *ctxt, void * user_data);
 
 extern void
-verify_code (gcc_jit_result *result);
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result);
 
 /* Implement framework needed for turning the testcase hooks into an
    executable.  test-combination.c combines multiple testcases into one
@@ -60,9 +63,37 @@ verify_code (gcc_jit_result *result);
    off this part of harness.h.  */
 #ifndef TEST_COMBINATION
 
+void check_string_value (const char *actual, const char *expected)
+{
+  if (actual && !expected)
+    {
+      fail ("%s: actual: \"%s\" != expected: NULL", test, actual);
+	fprintf (stderr, "incorrect value\n");
+	abort ();
+    }
+    if (expected && !actual)
+      {
+	fail ("%s: actual: NULL != expected: \"%s\"", test, expected);
+	fprintf (stderr, "incorrect value\n");
+	abort ();
+      }
+    if (actual && expected)
+      {
+	if (strcmp (actual, expected))
+	  {
+	    fail ("%s: actual: \"%s\" != expected: \"%s\"", test, actual, expected);
+	    fprintf (stderr, "incorrect valuen");
+	    abort ();
+	  }
+	pass ("%s: actual: \"%s\" == expected: \"%s\"", test, actual, expected);
+      }
+    else
+      pass ("%s: actual: NULL == expected: NULL");
+}
+
 /* Run one iteration of the test.  */
 static void
-test_jit (const char *argv0)
+test_jit (const char *argv0, void *user_data)
 {
   gcc_jit_context *ctxt;
   gcc_jit_result *result;
@@ -70,7 +101,7 @@ test_jit (const char *argv0)
   ctxt = gcc_jit_context_acquire ();
      /* FIXME: error-handling */
 
-  gcc_jit_context_set_code_factory (ctxt, code_making_callback, NULL);
+  gcc_jit_context_set_code_factory (ctxt, code_making_callback, user_data);
 
   /* Set up options.  */
   gcc_jit_context_set_str_option (
@@ -106,9 +137,9 @@ test_jit (const char *argv0)
      in a mutex for now.  */
   result = gcc_jit_context_compile (ctxt);
 
-  gcc_jit_context_release (ctxt);
+  verify_code (ctxt, result);
 
-  verify_code (result);
+  gcc_jit_context_release (ctxt);
 
   /* Once we're done with the code, this unloads the built .so file: */
   gcc_jit_result_release (result);
@@ -144,7 +175,7 @@ main (int argc, char **argv)
                 i, 5);
 
       //printf ("ITERATION %d\n", i);
-      test_jit (argv[0]);
+      test_jit (argv[0], NULL);
       //printf ("\n");
     }
 
diff --git a/gcc/testsuite/jit.dg/test-accessing-struct.c b/gcc/testsuite/jit.dg/test-accessing-struct.c
index 4e197c5..46c6f5b 100644
--- a/gcc/testsuite/jit.dg/test-accessing-struct.c
+++ b/gcc/testsuite/jit.dg/test-accessing-struct.c
@@ -88,7 +88,7 @@ code_making_callback (gcc_jit_context *ctxt, void *user_data)
 }
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   typedef void (*fn_type) (struct foo *);
   CHECK_NON_NULL (result);
diff --git a/gcc/testsuite/jit.dg/test-calling-external-function.c b/gcc/testsuite/jit.dg/test-calling-external-function.c
index 6e5dd7d..bfc0641 100644
--- a/gcc/testsuite/jit.dg/test-calling-external-function.c
+++ b/gcc/testsuite/jit.dg/test-calling-external-function.c
@@ -95,7 +95,7 @@ called_function (int i, int j, int k)
 }
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   typedef void (*fn_type) (int);
   CHECK_NON_NULL (result);
diff --git a/gcc/testsuite/jit.dg/test-combination.c b/gcc/testsuite/jit.dg/test-combination.c
index 3338d94..00fbee6 100644
--- a/gcc/testsuite/jit.dg/test-combination.c
+++ b/gcc/testsuite/jit.dg/test-combination.c
@@ -115,17 +115,17 @@ code_making_callback (gcc_jit_context *ctxt, void * user_data)
 }
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
-  verify_code_accessing_struct (result);
-  verify_code_calling_external_function (result);
-  verify_code_dot_product (result);
-  verify_code_expressions (result);
-  verify_code_factorial (result);
-  verify_code_fibonacci (result);
-  verify_code_hello_world (result);
-  verify_code_string_literal (result);
-  verify_code_sum_of_squares (result);
-  verify_code_types (result);
-  verify_code_using_global (result);
+  verify_code_accessing_struct (ctxt, result);
+  verify_code_calling_external_function (ctxt, result);
+  verify_code_dot_product (ctxt, result);
+  verify_code_expressions (ctxt, result);
+  verify_code_factorial (ctxt, result);
+  verify_code_fibonacci (ctxt, result);
+  verify_code_hello_world (ctxt, result);
+  verify_code_string_literal (ctxt, result);
+  verify_code_sum_of_squares (ctxt, result);
+  verify_code_types (ctxt, result);
+  verify_code_using_global (ctxt, result);
 }
diff --git a/gcc/testsuite/jit.dg/test-dot-product.c b/gcc/testsuite/jit.dg/test-dot-product.c
index 3a8a59a..dffccae 100644
--- a/gcc/testsuite/jit.dg/test-dot-product.c
+++ b/gcc/testsuite/jit.dg/test-dot-product.c
@@ -99,7 +99,7 @@ code_making_callback (gcc_jit_context *ctxt, void *user_data)
 }
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   typedef double (*my_dot_product_fn_type) (int n, double *a, double *b);
   CHECK_NON_NULL (result);
diff --git a/gcc/testsuite/jit.dg/test-expressions.c b/gcc/testsuite/jit.dg/test-expressions.c
index aaaf394..c270082 100644
--- a/gcc/testsuite/jit.dg/test-expressions.c
+++ b/gcc/testsuite/jit.dg/test-expressions.c
@@ -560,7 +560,7 @@ code_making_callback (gcc_jit_context *ctxt, void *user_data)
 }
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   CHECK_NON_NULL (result);
 
diff --git a/gcc/testsuite/jit.dg/test-factorial.c b/gcc/testsuite/jit.dg/test-factorial.c
index 5c3b237..758cd2d 100644
--- a/gcc/testsuite/jit.dg/test-factorial.c
+++ b/gcc/testsuite/jit.dg/test-factorial.c
@@ -92,7 +92,7 @@ code_making_callback (gcc_jit_context *ctxt, void *user_data)
 }
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   typedef int (*my_factorial_fn_type) (int);
   CHECK_NON_NULL (result);
diff --git a/gcc/testsuite/jit.dg/test-failure.c b/gcc/testsuite/jit.dg/test-failure.c
index ac31964..4a7b788 100644
--- a/gcc/testsuite/jit.dg/test-failure.c
+++ b/gcc/testsuite/jit.dg/test-failure.c
@@ -12,7 +12,7 @@ code_making_callback (gcc_jit_context *ctxt, void *user_data)
 }
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   CHECK_VALUE (result, NULL);
 }
diff --git a/gcc/testsuite/jit.dg/test-fibonacci.c b/gcc/testsuite/jit.dg/test-fibonacci.c
index 16d8a46..23903fa 100644
--- a/gcc/testsuite/jit.dg/test-fibonacci.c
+++ b/gcc/testsuite/jit.dg/test-fibonacci.c
@@ -132,7 +132,7 @@ FIRST_LINE + 7: }
 }
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   typedef int (*my_fibonacci_fn_type) (int);
   CHECK_NON_NULL (result);
diff --git a/gcc/testsuite/jit.dg/test-hello-world.c b/gcc/testsuite/jit.dg/test-hello-world.c
index 0e3af81..1c18ce1b 100644
--- a/gcc/testsuite/jit.dg/test-hello-world.c
+++ b/gcc/testsuite/jit.dg/test-hello-world.c
@@ -53,7 +53,7 @@ code_making_callback (gcc_jit_context *ctxt, void *user_data)
 }
 
 extern void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   typedef void (*fn_type) (const char *);
   CHECK_NON_NULL (result);
diff --git a/gcc/testsuite/jit.dg/test-null-passed-to-api.c b/gcc/testsuite/jit.dg/test-null-passed-to-api.c
index 245fde0..1e9d89c 100644
--- a/gcc/testsuite/jit.dg/test-null-passed-to-api.c
+++ b/gcc/testsuite/jit.dg/test-null-passed-to-api.c
@@ -21,10 +21,14 @@ code_making_callback (gcc_jit_context *ctxt, void *user_data)
 }
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   /* Ensure that the bad API usage prevents the API giving a bogus
      result back.  */
   CHECK_VALUE (result, NULL);
+
+  /* Verify that the correct error message was emitted.  */
+  CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+		      "gcc_jit_context_new_function: NULL return_type");
 }
 
diff --git a/gcc/testsuite/jit.dg/test-string-literal.c b/gcc/testsuite/jit.dg/test-string-literal.c
index cd373ad..b9ba895 100644
--- a/gcc/testsuite/jit.dg/test-string-literal.c
+++ b/gcc/testsuite/jit.dg/test-string-literal.c
@@ -37,7 +37,7 @@ code_making_callback (gcc_jit_context *ctxt, void *user_data)
 }
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   typedef const char *(*fn_type) (void);
   CHECK_NON_NULL (result);
diff --git a/gcc/testsuite/jit.dg/test-sum-of-squares.c b/gcc/testsuite/jit.dg/test-sum-of-squares.c
index 48ac93f..934d58d 100644
--- a/gcc/testsuite/jit.dg/test-sum-of-squares.c
+++ b/gcc/testsuite/jit.dg/test-sum-of-squares.c
@@ -119,7 +119,7 @@ code_making_callback (gcc_jit_context *ctxt, void *user_data)
 }
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   typedef int (*loop_test_fn_type) (int);
   CHECK_NON_NULL (result);
diff --git a/gcc/testsuite/jit.dg/test-types.c b/gcc/testsuite/jit.dg/test-types.c
index 819c40a..e4a042e 100644
--- a/gcc/testsuite/jit.dg/test-types.c
+++ b/gcc/testsuite/jit.dg/test-types.c
@@ -241,7 +241,7 @@ code_making_callback (gcc_jit_context *ctxt, void *user_data)
 }
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   typedef void (*fn_type) (struct zoo *);
   CHECK_NON_NULL (result);
diff --git a/gcc/testsuite/jit.dg/test-using-global.c b/gcc/testsuite/jit.dg/test-using-global.c
index 8eabc31..f9390f8 100644
--- a/gcc/testsuite/jit.dg/test-using-global.c
+++ b/gcc/testsuite/jit.dg/test-using-global.c
@@ -53,7 +53,7 @@ code_making_callback (gcc_jit_context *ctxt, void *user_data)
 int the_global;
 
 void
-verify_code (gcc_jit_result *result)
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
 {
   typedef void (*fn_type) (void);
   CHECK_NON_NULL (result);
