[jit] Include locations in error reports where available

David Malcolm dmalcolm@redhat.com
Thu Mar 13 20:53:00 GMT 2014


Committed to branch dmalcolm/jit:

Update the error-handling machinery to pass around (recording::location *)
values (aka a gcc_jit_location *), printing them when reporting errors,
where available (they can be NULL).

Also, in gcc::jit::recording::context::errors_occurred, consider
errors as having occurred if they occured on a parent (or ancestor)
context.

gcc/jit/
	* internal-api.c (gcc::jit::recording::context::set_str_option):
	Provide NULL recording::location to add_error.
	(gcc::jit::recording::context::set_int_option): Likewise.
	(gcc::jit::recording::context::set_bool_option): Likewise.
	(gcc::jit::playback::context::compile): Likewise.
	(gcc::jit::recording::context::add_error): Add recording::location
	param.
	(gcc::jit::recording::context::add_error_va): Likewise; print it
	when present; add "error: " to stderr messages.
	(gcc::jit::recording::location::replay_into): Provide
	recording::location to the playback::location.

	(gcc::jit::recording::function::validate): Add locations to the
	add_error invocations.
	(gcc::jit::recording::block::validate): Likewise.
	(gcc::jit::playback::context::get_type): Likewise.
	(gcc::jit::playback::context::new_unary_op): Likewise.
	(gcc::jit::playback::context::new_binary_op): Likewise.
	(gcc::jit::playback::context::new_comparison): Likewise.

	(gcc::jit::recording::block::get_loc): New.
	(gcc::jit::recording::block::get_first_statement): New.

	(gcc::jit::playback::context::build_cast): Pass in higher-level
	arguments in the hope of eventually providing better error
	messages when a cast isn't possible.
	(gcc::jit::playback::context::new_cast): As above.

	(gcc::jit::playback::context::add_error): Add playback::location
	parameter, using it to provide the corresponding
	recording::location (if any) when reporting the error to the
	recording::context.
	(gcc::jit::playback::context::add_error_va): Likewise.
	(gcc::jit::playback::context::new_location): Likewise.
	(gcc::jit::playback::source_line::get_location): Likewise.
	(gcc::jit::playback::location::location): Likewise.

	* internal-api.h (gcc::jit::recording::context::add_error): Add
	recording::location param.
	(gcc::jit::recording::context::add_error_va): Likewise.

	(gcc::jit::recording::context::errors_occurred): Also consider
	errors that occur on a parent or ancestor context, recursively.

	(gcc::jit::recording::block::get_loc): New.
	(gcc::jit::recording::block::get_first_statement): New.
	(gcc::jit::recording::statement::get_loc): New.

	(gcc::jit::playback::context::new_location): Add recording::location
	parameter.

	(gcc::jit::playback::context::add_error): Add playback::location
	parameter.
	(gcc::jit::playback::context::add_error_va): Likewise.

	(gcc::jit::playback::context::build_cast): Pass in higher-level
	arguments in the hope of eventually providing better error
	messages when a cast isn't possible.

	(gcc::jit::playback::source_line::get_location): Add
	recording::location parameter.
	(gcc::jit::playback::location::location): Likewise.
	(gcc::jit::playback::location::get_recording_loc): New.
	(gcc::jit::playback::location::m_recording_loc): New.

	* jit-builtins.c (gcc::jit::builtins_manager::get_builtin_function):
	Provide NULL recording::location to add_error.
	(gcc::jit::builtins_manager::make_primitive_type): Likewise.

	* libgccjit.c (RETURN_VAL_IF_FAIL): Add location argument.
	(RETURN_VAL_IF_FAIL_PRINTF1): Likewise.
	(RETURN_VAL_IF_FAIL_PRINTF2): Likewise.
	(RETURN_VAL_IF_FAIL_PRINTF3): Likewise.
	(RETURN_VAL_IF_FAIL_PRINTF4): Likewise.
	(RETURN_VAL_IF_FAIL_PRINTF6): Likewise.
	(RETURN_NULL_IF_FAIL): Likewise.
	(RETURN_NULL_IF_FAIL_PRINTF1): Likewise.
	(RETURN_NULL_IF_FAIL_PRINTF2): Likewise.
	(RETURN_NULL_IF_FAIL_PRINTF3): Likewise.
	(RETURN_NULL_IF_FAIL_PRINTF4): Likewise.
	(RETURN_NULL_IF_FAIL_PRINTF6): Likewise.
	(RETURN_IF_FAIL): Likewise.
	(RETURN_IF_FAIL_PRINTF1): Likewise.
	(RETURN_IF_FAIL_PRINTF2): Likewise.
	(RETURN_IF_FAIL_PRINTF4): Likewise.
	(RETURN_IF_NOT_VALID_BLOCK): Likewise.
	(RETURN_NULL_IF_NOT_VALID_BLOCK): Likewise.

	(jit_error): Likewise.

	(gcc_jit_location_as_object): Provided location argument to
	error-handling macros.
	(gcc_jit_type_as_object): Likewise.
	(gcc_jit_context_get_type): Likewise.
	(gcc_jit_context_get_int_type): Likewise.
	(gcc_jit_type_get_pointer): Likewise.
	(gcc_jit_type_get_const): Likewise.
	(gcc_jit_type_get_volatile): Likewise.
	(gcc_jit_context_new_array_type): Likewise.
	(gcc_jit_context_new_field): Likewise.
	(gcc_jit_context_new_struct_type): Likewise.
	(gcc_jit_context_new_opaque_struct): Likewise.
	(gcc_jit_struct_as_type): Likewise.
	(gcc_jit_struct_set_fields): Likewise.
	(gcc_jit_context_new_param): Likewise.
	(gcc_jit_param_as_object): Likewise.
	(gcc_jit_param_as_lvalue): Likewise.
	(gcc_jit_param_as_rvalue): Likewise.
	(gcc_jit_context_new_function): Likewise.
	(gcc_jit_context_get_builtin_function): Likewise.
	(gcc_jit_function_as_object): Likewise.
	(gcc_jit_function_get_param): Likewise.
	(gcc_jit_function_dump_to_dot): Likewise.
	(gcc_jit_function_new_block): Likewise.
	(gcc_jit_block_as_object): Likewise.
	(gcc_jit_block_get_function): Likewise.
	(gcc_jit_context_new_global): Likewise.
	(gcc_jit_lvalue_as_object): Likewise.
	(gcc_jit_lvalue_as_rvalue): Likewise.
	(gcc_jit_rvalue_as_object): Likewise.
	(gcc_jit_rvalue_get_type): Likewise.
	(gcc_jit_context_new_rvalue_from_int): Likewise.
	(gcc_jit_context_zero): Likewise.
	(gcc_jit_context_one): Likewise.
	(gcc_jit_context_new_rvalue_from_double): Likewise.
	(gcc_jit_context_new_rvalue_from_ptr): Likewise.
	(gcc_jit_context_null): Likewise.
	(gcc_jit_context_new_string_literal): Likewise.
	(gcc_jit_context_new_unary_op): Likewise.
	(gcc_jit_context_new_binary_op): Likewise.
	(gcc_jit_context_new_comparison): Likewise.
	(gcc_jit_context_new_call): Likewise.
	(gcc_jit_context_new_cast): Likewise.
	(gcc_jit_context_new_array_access): Likewise.
	(gcc_jit_object_get_context): Likewise.
	(gcc_jit_object_get_debug_string): Likewise.
	(gcc_jit_lvalue_access_field): Likewise.
	(gcc_jit_rvalue_access_field): Likewise.
	(gcc_jit_rvalue_dereference_field): Likewise.
	(gcc_jit_rvalue_dereference_field): Likewise.
	(gcc_jit_rvalue_dereference): Likewise.
	(gcc_jit_lvalue_get_address): Likewise.
	(gcc_jit_function_new_local): Likewise.
	(gcc_jit_block_add_eval): Likewise.
	(gcc_jit_block_add_assignment): Likewise.
	(gcc_jit_block_add_assignment_op): Likewise.
	(gcc_jit_block_end_with_conditional): Likewise.
	(gcc_jit_block_add_comment): Likewise.
	(gcc_jit_block_end_with_jump): Likewise.
	(gcc_jit_block_end_with_return): Likewise.
	(gcc_jit_block_end_with_void_return): Likewise.
	(gcc_jit_context_set_str_option): Likewise.
	(gcc_jit_context_set_int_option): Likewise.
	(gcc_jit_context_set_bool_option): Likewise.
	(gcc_jit_context_compile): Likewise.
	(gcc_jit_context_dump_to_file): Likewise.
	(gcc_jit_context_get_first_error): Likewise.
	(gcc_jit_result_get_code): Likewise.
	(gcc_jit_result_get_code): Likewise.
	(gcc_jit_result_release): Likewise.
---
 gcc/jit/ChangeLog.jit  | 163 +++++++++++++++++++
 gcc/jit/internal-api.c | 135 ++++++++++------
 gcc/jit/internal-api.h |  38 +++--
 gcc/jit/jit-builtins.c |   5 +-
 gcc/jit/libgccjit.c    | 417 +++++++++++++++++++++++++------------------------
 5 files changed, 498 insertions(+), 260 deletions(-)

diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit
index 2d47442..87f10a3 100644
--- a/gcc/jit/ChangeLog.jit
+++ b/gcc/jit/ChangeLog.jit
@@ -1,3 +1,166 @@
+2014-03-13  David Malcolm  <dmalcolm@redhat.com>
+
+	* internal-api.c (gcc::jit::recording::context::set_str_option):
+	Provide NULL recording::location to add_error.
+	(gcc::jit::recording::context::set_int_option): Likewise.
+	(gcc::jit::recording::context::set_bool_option): Likewise.
+	(gcc::jit::playback::context::compile): Likewise.
+	(gcc::jit::recording::context::add_error): Add recording::location
+	param.
+	(gcc::jit::recording::context::add_error_va): Likewise; print it
+	when present; add "error: " to stderr messages.
+	(gcc::jit::recording::location::replay_into): Provide
+	recording::location to the playback::location.
+
+	(gcc::jit::recording::function::validate): Add locations to the
+	add_error invocations.
+	(gcc::jit::recording::block::validate): Likewise.
+	(gcc::jit::playback::context::get_type): Likewise.
+	(gcc::jit::playback::context::new_unary_op): Likewise.
+	(gcc::jit::playback::context::new_binary_op): Likewise.
+	(gcc::jit::playback::context::new_comparison): Likewise.
+
+	(gcc::jit::recording::block::get_loc): New.
+	(gcc::jit::recording::block::get_first_statement): New.
+
+	(gcc::jit::playback::context::build_cast): Pass in higher-level
+	arguments in the hope of eventually providing better error
+	messages when a cast isn't possible.
+	(gcc::jit::playback::context::new_cast): As above.
+
+	(gcc::jit::playback::context::add_error): Add playback::location
+	parameter, using it to provide the corresponding
+	recording::location (if any) when reporting the error to the
+	recording::context.
+	(gcc::jit::playback::context::add_error_va): Likewise.
+	(gcc::jit::playback::context::new_location): Likewise.
+	(gcc::jit::playback::source_line::get_location): Likewise.
+	(gcc::jit::playback::location::location): Likewise.
+
+	* internal-api.h (gcc::jit::recording::context::add_error): Add
+	recording::location param.
+	(gcc::jit::recording::context::add_error_va): Likewise.
+
+	(gcc::jit::recording::context::errors_occurred): Also consider
+	errors that occur on a parent or ancestor context, recursively.
+
+	(gcc::jit::recording::block::get_loc): New.
+	(gcc::jit::recording::block::get_first_statement): New.
+	(gcc::jit::recording::statement::get_loc): New.
+
+	(gcc::jit::playback::context::new_location): Add recording::location
+	parameter.
+
+	(gcc::jit::playback::context::add_error): Add playback::location
+	parameter.
+	(gcc::jit::playback::context::add_error_va): Likewise.
+
+	(gcc::jit::playback::context::build_cast): Pass in higher-level
+	arguments in the hope of eventually providing better error
+	messages when a cast isn't possible.
+
+	(gcc::jit::playback::source_line::get_location): Add
+	recording::location parameter.
+	(gcc::jit::playback::location::location): Likewise.
+	(gcc::jit::playback::location::get_recording_loc): New.
+	(gcc::jit::playback::location::m_recording_loc): New.
+
+	* jit-builtins.c (gcc::jit::builtins_manager::get_builtin_function):
+	Provide NULL recording::location to add_error.
+	(gcc::jit::builtins_manager::make_primitive_type): Likewise.
+
+	* libgccjit.c (RETURN_VAL_IF_FAIL): Add location argument.
+	(RETURN_VAL_IF_FAIL_PRINTF1): Likewise.
+	(RETURN_VAL_IF_FAIL_PRINTF2): Likewise.
+	(RETURN_VAL_IF_FAIL_PRINTF3): Likewise.
+	(RETURN_VAL_IF_FAIL_PRINTF4): Likewise.
+	(RETURN_VAL_IF_FAIL_PRINTF6): Likewise.
+	(RETURN_NULL_IF_FAIL): Likewise.
+	(RETURN_NULL_IF_FAIL_PRINTF1): Likewise.
+	(RETURN_NULL_IF_FAIL_PRINTF2): Likewise.
+	(RETURN_NULL_IF_FAIL_PRINTF3): Likewise.
+	(RETURN_NULL_IF_FAIL_PRINTF4): Likewise.
+	(RETURN_NULL_IF_FAIL_PRINTF6): Likewise.
+	(RETURN_IF_FAIL): Likewise.
+	(RETURN_IF_FAIL_PRINTF1): Likewise.
+	(RETURN_IF_FAIL_PRINTF2): Likewise.
+	(RETURN_IF_FAIL_PRINTF4): Likewise.
+	(RETURN_IF_NOT_VALID_BLOCK): Likewise.
+	(RETURN_NULL_IF_NOT_VALID_BLOCK): Likewise.
+
+	(jit_error): Likewise.
+
+	(gcc_jit_location_as_object): Provided location argument to
+	error-handling macros.
+	(gcc_jit_type_as_object): Likewise.
+	(gcc_jit_context_get_type): Likewise.
+	(gcc_jit_context_get_int_type): Likewise.
+	(gcc_jit_type_get_pointer): Likewise.
+	(gcc_jit_type_get_const): Likewise.
+	(gcc_jit_type_get_volatile): Likewise.
+	(gcc_jit_context_new_array_type): Likewise.
+	(gcc_jit_context_new_field): Likewise.
+	(gcc_jit_context_new_struct_type): Likewise.
+	(gcc_jit_context_new_opaque_struct): Likewise.
+	(gcc_jit_struct_as_type): Likewise.
+	(gcc_jit_struct_set_fields): Likewise.
+	(gcc_jit_context_new_param): Likewise.
+	(gcc_jit_param_as_object): Likewise.
+	(gcc_jit_param_as_lvalue): Likewise.
+	(gcc_jit_param_as_rvalue): Likewise.
+	(gcc_jit_context_new_function): Likewise.
+	(gcc_jit_context_get_builtin_function): Likewise.
+	(gcc_jit_function_as_object): Likewise.
+	(gcc_jit_function_get_param): Likewise.
+	(gcc_jit_function_dump_to_dot): Likewise.
+	(gcc_jit_function_new_block): Likewise.
+	(gcc_jit_block_as_object): Likewise.
+	(gcc_jit_block_get_function): Likewise.
+	(gcc_jit_context_new_global): Likewise.
+	(gcc_jit_lvalue_as_object): Likewise.
+	(gcc_jit_lvalue_as_rvalue): Likewise.
+	(gcc_jit_rvalue_as_object): Likewise.
+	(gcc_jit_rvalue_get_type): Likewise.
+	(gcc_jit_context_new_rvalue_from_int): Likewise.
+	(gcc_jit_context_zero): Likewise.
+	(gcc_jit_context_one): Likewise.
+	(gcc_jit_context_new_rvalue_from_double): Likewise.
+	(gcc_jit_context_new_rvalue_from_ptr): Likewise.
+	(gcc_jit_context_null): Likewise.
+	(gcc_jit_context_new_string_literal): Likewise.
+	(gcc_jit_context_new_unary_op): Likewise.
+	(gcc_jit_context_new_binary_op): Likewise.
+	(gcc_jit_context_new_comparison): Likewise.
+	(gcc_jit_context_new_call): Likewise.
+	(gcc_jit_context_new_cast): Likewise.
+	(gcc_jit_context_new_array_access): Likewise.
+	(gcc_jit_object_get_context): Likewise.
+	(gcc_jit_object_get_debug_string): Likewise.
+	(gcc_jit_lvalue_access_field): Likewise.
+	(gcc_jit_rvalue_access_field): Likewise.
+	(gcc_jit_rvalue_dereference_field): Likewise.
+	(gcc_jit_rvalue_dereference_field): Likewise.
+	(gcc_jit_rvalue_dereference): Likewise.
+	(gcc_jit_lvalue_get_address): Likewise.
+	(gcc_jit_function_new_local): Likewise.
+	(gcc_jit_block_add_eval): Likewise.
+	(gcc_jit_block_add_assignment): Likewise.
+	(gcc_jit_block_add_assignment_op): Likewise.
+	(gcc_jit_block_end_with_conditional): Likewise.
+	(gcc_jit_block_add_comment): Likewise.
+	(gcc_jit_block_end_with_jump): Likewise.
+	(gcc_jit_block_end_with_return): Likewise.
+	(gcc_jit_block_end_with_void_return): Likewise.
+	(gcc_jit_context_set_str_option): Likewise.
+	(gcc_jit_context_set_int_option): Likewise.
+	(gcc_jit_context_set_bool_option): Likewise.
+	(gcc_jit_context_compile): Likewise.
+	(gcc_jit_context_dump_to_file): Likewise.
+	(gcc_jit_context_get_first_error): Likewise.
+	(gcc_jit_result_get_code): Likewise.
+	(gcc_jit_result_get_code): Likewise.
+	(gcc_jit_result_release): Likewise.
+
 2014-03-10  David Malcolm  <dmalcolm@redhat.com>
 
 	* libgccjit++.h (gccjit::context::new_rvalue): Make these
diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c
index 17c8e9e..692dffb 100644
--- a/gcc/jit/internal-api.c
+++ b/gcc/jit/internal-api.c
@@ -530,7 +530,8 @@ recording::context::set_str_option (enum gcc_jit_str_option opt,
 {
   if (opt < 0 || opt >= GCC_JIT_NUM_STR_OPTIONS)
     {
-      add_error ("unrecognized (enum gcc_jit_str_option) value: %i", opt);
+      add_error (NULL,
+		 "unrecognized (enum gcc_jit_str_option) value: %i", opt);
       return;
     }
   m_str_options[opt] = value;
@@ -542,7 +543,8 @@ recording::context::set_int_option (enum gcc_jit_int_option opt,
 {
   if (opt < 0 || opt >= GCC_JIT_NUM_INT_OPTIONS)
     {
-      add_error ("unrecognized (enum gcc_jit_int_option) value: %i", opt);
+      add_error (NULL,
+		 "unrecognized (enum gcc_jit_int_option) value: %i", opt);
       return;
     }
   m_int_options[opt] = value;
@@ -554,7 +556,8 @@ recording::context::set_bool_option (enum gcc_jit_bool_option opt,
 {
   if (opt < 0 || opt >= GCC_JIT_NUM_BOOL_OPTIONS)
     {
-      add_error ("unrecognized (enum gcc_jit_bool_option) value: %i", opt);
+      add_error (NULL,
+		 "unrecognized (enum gcc_jit_bool_option) value: %i", opt);
       return;
     }
   m_bool_options[opt] = value ? true : false;
@@ -588,16 +591,16 @@ recording::context::compile ()
 }
 
 void
-recording::context::add_error (const char *fmt, ...)
+recording::context::add_error (location *loc, const char *fmt, ...)
 {
   va_list ap;
   va_start (ap, fmt);
-  add_error_va (fmt, ap);
+  add_error_va (loc, fmt, ap);
   va_end (ap);
 }
 
 void
-recording::context::add_error_va (const char *fmt, va_list ap)
+recording::context::add_error_va (location *loc, const char *fmt, va_list ap)
 {
   char buf[1024];
   vsnprintf (buf, sizeof (buf) - 1, fmt, ap);
@@ -606,9 +609,15 @@ recording::context::add_error_va (const char *fmt, va_list ap)
   if (!progname)
     progname = "libgccjit.so";
 
-  fprintf (stderr, "%s: %s\n",
-	   progname,
-	   buf);
+  if (loc)
+    fprintf (stderr, "%s: %s: error: %s\n",
+	     progname,
+	     loc->get_debug_string (),
+	     buf);
+  else
+    fprintf (stderr, "%s: error: %s\n",
+	     progname,
+	     buf);
 
   if (!m_error_count)
     {
@@ -760,7 +769,10 @@ recording::string::make_debug_string ()
 void
 recording::location::replay_into (replayer *r)
 {
-  m_playback_obj = r->new_location (m_filename->c_str (), m_line, m_column);
+  m_playback_obj = r->new_location (this,
+				    m_filename->c_str (),
+				    m_line,
+				    m_column);
 }
 
 recording::string *
@@ -1375,7 +1387,8 @@ recording::function::validate ()
   if (m_kind != GCC_JIT_FUNCTION_IMPORTED
       && m_return_type != m_ctxt->get_type (GCC_JIT_TYPE_VOID))
     if (0 == m_blocks.length ())
-      m_ctxt->add_error ("function %s returns non-void (type: %s)"
+      m_ctxt->add_error (m_loc,
+			 "function %s returns non-void (type: %s)"
 			 " but has no blocks",
 			 get_debug_string (),
 			 m_return_type->get_debug_string ());
@@ -1431,7 +1444,8 @@ recording::function::validate ()
 	block *b;
 	FOR_EACH_VEC_ELT (m_blocks, i, b)
 	  if (!b->m_is_reachable)
-	    m_ctxt->add_error ("unreachable block: %s",
+	    m_ctxt->add_error (b->get_loc (),
+			       "unreachable block: %s",
 			       b->get_debug_string ());
       }
     }
@@ -1571,7 +1585,10 @@ recording::block::validate ()
 {
   if (!has_been_terminated ())
     {
-      m_func->get_context ()->add_error ("unterminated block in %s: %s",
+      statement *stmt = get_last_statement ();
+      location *loc = stmt ? stmt->get_loc () : NULL;
+      m_func->get_context ()->add_error (loc,
+					 "unterminated block in %s: %s",
 					 m_func->get_debug_string (),
 					 get_debug_string ());
       return false;
@@ -1580,6 +1597,25 @@ recording::block::validate ()
   return true;
 }
 
+recording::location *
+recording::block::get_loc () const
+{
+  recording::statement *stmt = get_first_statement ();
+  if (stmt)
+    return stmt->get_loc ();
+  else
+    return NULL;
+}
+
+recording::statement *
+recording::block::get_first_statement () const
+{
+  if (m_statements.length ())
+    return m_statements[0];
+  else
+    return NULL;
+}
+
 recording::statement *
 recording::block::get_last_statement () const
 {
@@ -2339,7 +2375,8 @@ get_type (enum gcc_jit_types type_)
   tree type_node = get_tree_node_for_type (type_);
   if (NULL == type_node)
     {
-      add_error ("unrecognized (enum gcc_jit_types) value: %i", type_);
+      add_error (NULL,
+		 "unrecognized (enum gcc_jit_types) value: %i", type_);
       return NULL;
     }
 
@@ -2687,7 +2724,7 @@ new_unary_op (location *loc,
   switch (op)
     {
     default:
-      add_error ("unrecognized (enum gcc_jit_unary_op) value: %i", op);
+      add_error (loc, "unrecognized (enum gcc_jit_unary_op) value: %i", op);
       return NULL;
 
     case GCC_JIT_UNARY_OP_MINUS:
@@ -2735,7 +2772,7 @@ new_binary_op (location *loc,
   switch (op)
     {
     default:
-      add_error ("unrecognized (enum gcc_jit_binary_op) value: %i", op);
+      add_error (loc, "unrecognized (enum gcc_jit_binary_op) value: %i", op);
       return NULL;
 
     case GCC_JIT_BINARY_OP_PLUS:
@@ -2813,7 +2850,7 @@ new_comparison (location *loc,
   switch (op)
     {
     default:
-      add_error ("unrecognized (enum gcc_jit_comparison) value: %i", op);
+      add_error (loc, "unrecognized (enum gcc_jit_comparison) value: %i", op);
       return NULL;
 
     case GCC_JIT_COMPARISON_EQ:
@@ -2887,7 +2924,9 @@ new_call (location *loc,
 }
 
 tree
-playback::context::build_cast (tree expr, tree dst_type)
+playback::context::build_cast (playback::location *loc,
+			       playback::rvalue *expr,
+			       playback::type *type_)
 {
   /* For comparison, see:
      - c/c-typeck.c:build_c_cast
@@ -2895,38 +2934,40 @@ playback::context::build_cast (tree expr, tree dst_type)
      - convert.h
 
      Only some kinds of cast are currently supported here.  */
-  tree ret = NULL;
-  ret = targetm.convert_to_type (dst_type, expr);
-  if (ret)
-      return ret;
-  enum tree_code dst_code = TREE_CODE (dst_type);
+  tree t_expr = expr->as_tree ();
+  tree t_dst_type = type_->as_tree ();
+  tree t_ret = NULL;
+  t_ret = targetm.convert_to_type (t_dst_type, t_expr);
+  if (t_ret)
+      return t_ret;
+  enum tree_code dst_code = TREE_CODE (t_dst_type);
   switch (dst_code)
     {
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
-      ret = convert_to_integer (dst_type, expr);
+      t_ret = convert_to_integer (t_dst_type, t_expr);
       goto maybe_fold;
 
     case BOOLEAN_TYPE:
       /* Compare with c_objc_common_truthvalue_conversion and
 	 c_common_truthvalue_conversion. */
-      /* For now, convert to: (expr != 0)  */
-      ret = build2 (NE_EXPR, dst_type,
-		    expr, integer_zero_node);
+      /* For now, convert to: (t_expr != 0)  */
+      t_ret = build2 (NE_EXPR, t_dst_type,
+		      t_expr, integer_zero_node);
       goto maybe_fold;
 
     case REAL_TYPE:
-      ret = convert_to_real (dst_type, expr);
+      t_ret = convert_to_real (t_dst_type, t_expr);
       goto maybe_fold;
 
     default:
-      add_error ("can't handle cast");
+      add_error (loc, "can't handle cast");
       return error_mark_node;
 
     maybe_fold:
-      if (TREE_CODE (ret) != C_MAYBE_CONST_EXPR)
-	ret = fold (ret);
-      return ret;
+      if (TREE_CODE (t_ret) != C_MAYBE_CONST_EXPR)
+	t_ret = fold (t_ret);
+      return t_ret;
     }
 }
 
@@ -2937,8 +2978,7 @@ new_cast (playback::location *loc,
 	  playback::type *type_)
 {
 
-  tree t_cast = build_cast (expr->as_tree (),
-			    type_->as_tree ());
+  tree t_cast = build_cast (loc, expr, type_);
   if (loc)
     set_tree_location (t_cast, loc);
   return new rvalue (this, t_cast);
@@ -3486,7 +3526,8 @@ compile ()
   switch (get_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL))
     {
     default:
-      add_error ("unrecognized optimization level: %i",
+      add_error (NULL,
+		 "unrecognized optimization level: %i",
 		 get_int_option (GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL));
       return NULL;
 
@@ -3786,19 +3827,21 @@ handle_locations ()
 
 void
 playback::context::
-add_error (const char *fmt, ...)
+add_error (location *loc, const char *fmt, ...)
 {
   va_list ap;
   va_start (ap, fmt);
-  m_recording_ctxt->add_error_va (fmt, ap);
+  m_recording_ctxt->add_error_va (loc ? loc->get_recording_loc () : NULL,
+				  fmt, ap);
   va_end (ap);
 }
 
 void
 playback::context::
-add_error_va (const char *fmt, va_list ap)
+add_error_va (location *loc, const char *fmt, va_list ap)
 {
-  m_recording_ctxt->add_error_va (fmt, ap);
+  m_recording_ctxt->add_error_va (loc ? loc->get_recording_loc () : NULL,
+				  fmt, ap);
 }
 
 result::
@@ -3835,7 +3878,8 @@ get_code (const char *funcname)
 
 playback::location *
 playback::context::
-new_location (const char *filename,
+new_location (recording::location *rloc,
+	      const char *filename,
 	      int line,
 	      int column)
 {
@@ -3844,7 +3888,7 @@ new_location (const char *filename,
   /* Likewise for the line within the file.  */
   source_line *src_line = src_file->get_source_line (line);
   /* Likewise for the column within the line.  */
-  location *loc = src_line->get_location (column);
+  location *loc = src_line->get_location (rloc, column);
   return loc;
 }
 
@@ -3913,7 +3957,7 @@ playback::source_line::source_line (source_file *file, int line_num) :
 
 playback::location *
 playback::source_line::
-get_location (int column_num)
+get_location (recording::location *rloc, int column_num)
 {
   int i;
   location *loc;
@@ -3924,13 +3968,16 @@ get_location (int column_num)
       return loc;
 
   /* Not found.  */
-  loc = new location (this, column_num);
+  loc = new location (rloc, this, column_num);
   m_locations.safe_push (loc);
   return loc;
 }
 
-playback::location::location (source_line *line, int column_num) :
+playback::location::location (recording::location *loc,
+			      source_line *line,
+			      int column_num) :
   m_srcloc (UNKNOWN_LOCATION),
+  m_recording_loc (loc),
   m_line (line),
   m_column_num(column_num)
 {
diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h
index 23352fc..5048f41 100644
--- a/gcc/jit/internal-api.h
+++ b/gcc/jit/internal-api.h
@@ -296,18 +296,21 @@ public:
   compile ();
 
   void
-  add_error (const char *fmt, ...)
-      GNU_PRINTF(2, 3);
+  add_error (location *loc, const char *fmt, ...)
+      GNU_PRINTF(3, 4);
 
   void
-  add_error_va (const char *fmt, va_list ap)
-      GNU_PRINTF(2, 0);
+  add_error_va (location *loc, const char *fmt, va_list ap)
+      GNU_PRINTF(3, 0);
 
   const char *
   get_first_error () const;
 
   bool errors_occurred () const
   {
+    if (m_parent_ctxt)
+      if (m_parent_ctxt->errors_occurred ())
+	return true;
     return m_error_count;
   }
 
@@ -968,6 +971,9 @@ public:
 
   bool validate ();
 
+  location *get_loc () const;
+
+  statement *get_first_statement () const;
   statement *get_last_statement () const;
 
   int get_successor_blocks (block **next1, block **next2) const;
@@ -1351,6 +1357,8 @@ public:
 
   void write_to_dump (dump &d);
 
+  location *get_loc () const { return m_loc; }
+
 protected:
   statement (block *b, location *loc)
   : memento (b->m_ctxt),
@@ -1554,7 +1562,8 @@ public:
   void replay ();
 
   location *
-  new_location (const char *filename,
+  new_location (recording::location *rloc,
+		const char *filename,
 		int line,
 		int column);
 
@@ -1680,12 +1689,12 @@ public:
   compile ();
 
   void
-  add_error (const char *fmt, ...)
-      GNU_PRINTF(2, 3);
+  add_error (location *loc, const char *fmt, ...)
+      GNU_PRINTF(3, 4);
 
   void
-  add_error_va (const char *fmt, va_list ap)
-      GNU_PRINTF(2, 0);
+  add_error_va (location *loc, const char *fmt, va_list ap)
+      GNU_PRINTF(3, 0);
 
   const char *
   get_first_error () const;
@@ -1713,7 +1722,9 @@ private:
   void dump_generated_code ();
 
   tree
-  build_cast (tree expr, tree dst_type);
+  build_cast (location *loc,
+	      rvalue *expr,
+	      type *type_);
 
   source_file *
   get_source_file (const char *filename);
@@ -2016,7 +2027,7 @@ public:
   source_line (source_file *file, int line_num);
 
   location *
-  get_location (int column_num);
+  get_location (recording::location *rloc, int column_num);
 
   int get_line_num () const { return m_line_num; }
 
@@ -2032,13 +2043,16 @@ private:
 class location : public wrapper
 {
 public:
-  location (source_line *line, int column_num);
+  location (recording::location *loc, source_line *line, int column_num);
 
   int get_column_num () const { return m_column_num; }
 
+  recording::location *get_recording_loc () const { return m_recording_loc; }
+
   source_location m_srcloc;
 
 private:
+  recording::location *m_recording_loc;
   source_line *m_line;
   int m_column_num;
 };
diff --git a/gcc/jit/jit-builtins.c b/gcc/jit/jit-builtins.c
index afc773d..160ef20 100644
--- a/gcc/jit/jit-builtins.c
+++ b/gcc/jit/jit-builtins.c
@@ -137,7 +137,7 @@ builtins_manager::get_builtin_function (const char *name)
   enum built_in_function builtin_id;
   if (!find_builtin_by_name (name, &builtin_id))
     {
-      m_ctxt->add_error ("builtin \"%s\" not found", name);
+      m_ctxt->add_error (NULL, "builtin \"%s\" not found", name);
       return NULL;
     }
 
@@ -283,7 +283,8 @@ builtins_manager::make_primitive_type (enum jit_builtin_type type_id)
     {
     default:
       // only some of these types are implemented so far:
-      m_ctxt->add_error ("unimplemented primitive type for builtin: %d", type_id);
+      m_ctxt->add_error (NULL,
+			 "unimplemented primitive type for builtin: %d", type_id);
       return NULL;
 
     case BT_VOID: return m_ctxt->get_type (GCC_JIT_TYPE_VOID);
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index 817d1b5..936576c 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -84,117 +84,117 @@ struct gcc_jit_param : public gcc::jit::recording::param
 
 /* TODO: mark failure branches as unlikely? */
 
-#define RETURN_VAL_IF_FAIL(TEST_EXPR, RETURN_EXPR, CTXT, ERR_MSG)	\
+#define RETURN_VAL_IF_FAIL(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_MSG)	\
   JIT_BEGIN_STMT							\
     if (!(TEST_EXPR))							\
       {								\
-	jit_error ((CTXT), "%s: %s", __func__, (ERR_MSG));		\
+	jit_error ((CTXT), (LOC), "%s: %s", __func__, (ERR_MSG));	\
 	return (RETURN_EXPR);						\
       }								\
   JIT_END_STMT
 
-#define RETURN_VAL_IF_FAIL_PRINTF1(TEST_EXPR, RETURN_EXPR, CTXT, ERR_FMT, A0) \
+#define RETURN_VAL_IF_FAIL_PRINTF1(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0) \
   JIT_BEGIN_STMT							\
     if (!(TEST_EXPR))							\
       {								\
-	jit_error ((CTXT), "%s: " ERR_FMT,				\
+	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,			\
 		   __func__, (A0));				\
 	return (RETURN_EXPR);						\
       }								\
   JIT_END_STMT
 
-#define RETURN_VAL_IF_FAIL_PRINTF2(TEST_EXPR, RETURN_EXPR, CTXT, ERR_FMT, A0, A1) \
+#define RETURN_VAL_IF_FAIL_PRINTF2(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
   JIT_BEGIN_STMT							\
     if (!(TEST_EXPR))							\
       {								\
-	jit_error ((CTXT), "%s: " ERR_FMT,				\
+	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
 		   __func__, (A0), (A1));				\
 	return (RETURN_EXPR);						\
       }								\
   JIT_END_STMT
 
-#define RETURN_VAL_IF_FAIL_PRINTF3(TEST_EXPR, RETURN_EXPR, CTXT, ERR_FMT, A0, A1, A2) \
+#define RETURN_VAL_IF_FAIL_PRINTF3(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2) \
   JIT_BEGIN_STMT							\
     if (!(TEST_EXPR))							\
       {								\
-	jit_error ((CTXT), "%s: " ERR_FMT,				\
+	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
 		   __func__, (A0), (A1), (A2));			\
 	return (RETURN_EXPR);						\
       }								\
   JIT_END_STMT
 
-#define RETURN_VAL_IF_FAIL_PRINTF4(TEST_EXPR, RETURN_EXPR, CTXT, ERR_FMT, A0, A1, A2, A3) \
+#define RETURN_VAL_IF_FAIL_PRINTF4(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
   JIT_BEGIN_STMT							\
     if (!(TEST_EXPR))							\
       {								\
-	jit_error ((CTXT), "%s: " ERR_FMT,				\
+	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
 		   __func__, (A0), (A1), (A2), (A3));			\
 	return (RETURN_EXPR);						\
       }								\
   JIT_END_STMT
 
-#define RETURN_VAL_IF_FAIL_PRINTF6(TEST_EXPR, RETURN_EXPR, CTXT, ERR_FMT, A0, A1, A2, A3, A4, A5) \
+#define RETURN_VAL_IF_FAIL_PRINTF6(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5) \
   JIT_BEGIN_STMT							\
     if (!(TEST_EXPR))							\
       {								\
-	jit_error ((CTXT), "%s: " ERR_FMT,				\
+	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
 		   __func__, (A0), (A1), (A2), (A3), (A4), (A5));	\
 	return (RETURN_EXPR);						\
       }								\
   JIT_END_STMT
 
-#define RETURN_NULL_IF_FAIL(TEST_EXPR, CTXT, ERR_MSG) \
-  RETURN_VAL_IF_FAIL ((TEST_EXPR), NULL, (CTXT), (ERR_MSG))
+#define RETURN_NULL_IF_FAIL(TEST_EXPR, CTXT, LOC, ERR_MSG) \
+  RETURN_VAL_IF_FAIL ((TEST_EXPR), NULL, (CTXT), (LOC), (ERR_MSG))
 
-#define RETURN_NULL_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, ERR_FMT, A0) \
-  RETURN_VAL_IF_FAIL_PRINTF1 (TEST_EXPR, NULL, CTXT, ERR_FMT, A0)
+#define RETURN_NULL_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, LOC, ERR_FMT, A0) \
+  RETURN_VAL_IF_FAIL_PRINTF1 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0)
 
-#define RETURN_NULL_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, ERR_FMT, A0, A1) \
-  RETURN_VAL_IF_FAIL_PRINTF2 (TEST_EXPR, NULL, CTXT, ERR_FMT, A0, A1)
+#define RETURN_NULL_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
+  RETURN_VAL_IF_FAIL_PRINTF2 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1)
 
-#define RETURN_NULL_IF_FAIL_PRINTF3(TEST_EXPR, CTXT, ERR_FMT, A0, A1, A2) \
-  RETURN_VAL_IF_FAIL_PRINTF3 (TEST_EXPR, NULL, CTXT, ERR_FMT, A0, A1, A2)
+#define RETURN_NULL_IF_FAIL_PRINTF3(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2) \
+  RETURN_VAL_IF_FAIL_PRINTF3 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2)
 
-#define RETURN_NULL_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, ERR_FMT, A0, A1, A2, A3) \
-  RETURN_VAL_IF_FAIL_PRINTF4 (TEST_EXPR, NULL, CTXT, ERR_FMT, A0, A1, A2, A3)
+#define RETURN_NULL_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
+  RETURN_VAL_IF_FAIL_PRINTF4 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3)
 
-#define RETURN_NULL_IF_FAIL_PRINTF6(TEST_EXPR, CTXT, ERR_FMT, A0, A1, A2, A3, A4, A5) \
-  RETURN_VAL_IF_FAIL_PRINTF6 (TEST_EXPR, NULL, CTXT, ERR_FMT, A0, A1, A2, A3, A4, A5)
+#define RETURN_NULL_IF_FAIL_PRINTF6(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5) \
+  RETURN_VAL_IF_FAIL_PRINTF6 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5)
 
-#define RETURN_IF_FAIL(TEST_EXPR, CTXT, ERR_MSG)			\
+#define RETURN_IF_FAIL(TEST_EXPR, CTXT, LOC, ERR_MSG)			\
   JIT_BEGIN_STMT							\
     if (!(TEST_EXPR))							\
       {								\
-	jit_error ((CTXT), "%s: %s", __func__, (ERR_MSG));		\
+	jit_error ((CTXT), (LOC), "%s: %s", __func__, (ERR_MSG));		\
 	return;							\
       }								\
   JIT_END_STMT
 
-#define RETURN_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, ERR_FMT, A0) \
+#define RETURN_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, LOC, ERR_FMT, A0) \
   JIT_BEGIN_STMT							\
     if (!(TEST_EXPR))							\
       {								\
-	jit_error ((CTXT), "%s: " ERR_FMT,				\
+	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
 		   __func__, (A0));					\
 	return;							\
       }								\
   JIT_END_STMT
 
-#define RETURN_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, ERR_FMT, A0, A1) \
+#define RETURN_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
   JIT_BEGIN_STMT							\
     if (!(TEST_EXPR))							\
       {								\
-	jit_error ((CTXT), "%s: " ERR_FMT,				\
+	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
 		   __func__, (A0), (A1));				\
 	return;							\
       }								\
   JIT_END_STMT
 
-#define RETURN_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, ERR_FMT, A0, A1, A2, A3) \
+#define RETURN_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
   JIT_BEGIN_STMT							\
     if (!(TEST_EXPR))							\
       {								\
-	jit_error ((CTXT), "%s: " ERR_FMT,				\
+	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
 		   __func__, (A0), (A1), (A2), (A3));			\
 	return;							\
       }								\
@@ -202,40 +202,46 @@ struct gcc_jit_param : public gcc::jit::recording::param
 
 /* Check that BLOCK is non-NULL, and that it's OK to add statements to
    it.  */
-#define RETURN_IF_NOT_VALID_BLOCK(BLOCK) \
+#define RETURN_IF_NOT_VALID_BLOCK(BLOCK, LOC)				\
   JIT_BEGIN_STMT							\
-    RETURN_IF_FAIL ((BLOCK), NULL, "NULL block");			\
+    RETURN_IF_FAIL ((BLOCK), NULL, (LOC), "NULL block");		\
     RETURN_IF_FAIL_PRINTF2 (						\
       !(BLOCK)->has_been_terminated (),				\
       (BLOCK)->get_context (),						\
+      (LOC),								\
       "adding to terminated block: %s (already terminated by: %s)",	\
       (BLOCK)->get_debug_string (),					\
       (BLOCK)->get_last_statement ()->get_debug_string ());		\
   JIT_END_STMT
 
-#define RETURN_NULL_IF_NOT_VALID_BLOCK(BLOCK) \
+#define RETURN_NULL_IF_NOT_VALID_BLOCK(BLOCK, LOC)			\
   JIT_BEGIN_STMT							\
-    RETURN_NULL_IF_FAIL ((BLOCK), NULL, "NULL block");			\
+    RETURN_NULL_IF_FAIL ((BLOCK), NULL, (LOC), "NULL block");		\
     RETURN_NULL_IF_FAIL_PRINTF2 (					\
       !(BLOCK)->has_been_terminated (),				\
       (BLOCK)->get_context (),						\
+      (LOC),								\
       "adding to terminated block: %s (already terminated by: %s)",	\
       (BLOCK)->get_debug_string (),					\
       (BLOCK)->get_last_statement ()->get_debug_string ());		\
   JIT_END_STMT
 
 static void
-jit_error (gcc::jit::recording::context *ctxt, const char *fmt, ...)
-  GNU_PRINTF(2, 3);
+jit_error (gcc::jit::recording::context *ctxt,
+	   gcc_jit_location *loc,
+	   const char *fmt, ...)
+  GNU_PRINTF(3, 4);
 
 static void
-jit_error (gcc::jit::recording::context *ctxt, const char *fmt, ...)
+jit_error (gcc::jit::recording::context *ctxt,
+	   gcc_jit_location *loc,
+	   const char *fmt, ...)
 {
   va_list ap;
   va_start (ap, fmt);
 
   if (ctxt)
-    ctxt->add_error_va (fmt, ap);
+    ctxt->add_error_va (loc, fmt, ap);
   else
     {
       /* No context?  Send to stderr.  */
@@ -277,7 +283,7 @@ gcc_jit_context_new_location (gcc_jit_context *ctxt,
 			      int line,
 			      int column)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
 
   return (gcc_jit_location *)ctxt->new_location (filename, line, column);
 }
@@ -285,7 +291,7 @@ gcc_jit_context_new_location (gcc_jit_context *ctxt,
 gcc_jit_object *
 gcc_jit_location_as_object (gcc_jit_location *loc)
 {
-  RETURN_NULL_IF_FAIL (loc, NULL, "NULL location");
+  RETURN_NULL_IF_FAIL (loc, NULL, NULL, "NULL location");
 
   return static_cast <gcc_jit_object *> (loc->as_object ());
 }
@@ -293,7 +299,7 @@ gcc_jit_location_as_object (gcc_jit_location *loc)
 gcc_jit_object *
 gcc_jit_type_as_object (gcc_jit_type *type)
 {
-  RETURN_NULL_IF_FAIL (type, NULL, "NULL type");
+  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
 
   return static_cast <gcc_jit_object *> (type->as_object ());
 }
@@ -302,7 +308,7 @@ gcc_jit_type *
 gcc_jit_context_get_type (gcc_jit_context *ctxt,
 			  enum gcc_jit_types type)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
   /* The inner function checks "type" for us.  */
 
   return (gcc_jit_type *)ctxt->get_type (type);
@@ -312,8 +318,8 @@ gcc_jit_type *
 gcc_jit_context_get_int_type (gcc_jit_context *ctxt,
 			      int num_bytes, int is_signed)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (num_bytes >= 0, ctxt, "negative size");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (num_bytes >= 0, ctxt, NULL, "negative size");
 
   return (gcc_jit_type *)ctxt->get_int_type (num_bytes, is_signed);
 }
@@ -321,7 +327,7 @@ gcc_jit_context_get_int_type (gcc_jit_context *ctxt,
 gcc_jit_type *
 gcc_jit_type_get_pointer (gcc_jit_type *type)
 {
-  RETURN_NULL_IF_FAIL (type, NULL, "NULL type");
+  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
 
   return (gcc_jit_type *)type->get_pointer ();
 }
@@ -329,7 +335,7 @@ gcc_jit_type_get_pointer (gcc_jit_type *type)
 gcc_jit_type *
 gcc_jit_type_get_const (gcc_jit_type *type)
 {
-  RETURN_NULL_IF_FAIL (type, NULL, "NULL type");
+  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
 
   return (gcc_jit_type *)type->get_const ();
 }
@@ -337,7 +343,7 @@ gcc_jit_type_get_const (gcc_jit_type *type)
 gcc_jit_type *
 gcc_jit_type_get_volatile (gcc_jit_type *type)
 {
-  RETURN_NULL_IF_FAIL (type, NULL, "NULL type");
+  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
 
   return (gcc_jit_type *)type->get_volatile ();
 }
@@ -348,8 +354,8 @@ gcc_jit_context_new_array_type (gcc_jit_context *ctxt,
 				gcc_jit_type *element_type,
 				int num_elements)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (element_type, ctxt, "NULL type");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
+  RETURN_NULL_IF_FAIL (element_type, ctxt, loc, "NULL type");
 
   return (gcc_jit_type *)ctxt->new_array_type (loc,
 					       element_type,
@@ -362,9 +368,9 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt,
 			   gcc_jit_type *type,
 			   const char *name)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (type, ctxt, "NULL type");
-  RETURN_NULL_IF_FAIL (name, ctxt, "NULL name");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
+  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
 
   return (gcc_jit_field *)ctxt->new_field (loc, type, name);
 }
@@ -372,7 +378,7 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt,
 gcc_jit_object *
 gcc_jit_field_as_object (gcc_jit_field *field)
 {
-  RETURN_NULL_IF_FAIL (field, NULL, "NULL field");
+  RETURN_NULL_IF_FAIL (field, NULL, NULL, "NULL field");
 
   return static_cast <gcc_jit_object *> (field->as_object ());
 }
@@ -384,16 +390,16 @@ gcc_jit_context_new_struct_type (gcc_jit_context *ctxt,
 				 int num_fields,
 				 gcc_jit_field **fields)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (name, ctxt, "NULL name");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
   if (num_fields)
-    RETURN_NULL_IF_FAIL (fields, ctxt, "NULL fields ptr");
+    RETURN_NULL_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
   for (int i = 0; i < num_fields; i++)
     {
-      RETURN_NULL_IF_FAIL (fields[i], ctxt, "NULL field ptr");
+      RETURN_NULL_IF_FAIL (fields[i], ctxt, loc, "NULL field ptr");
       RETURN_NULL_IF_FAIL_PRINTF2 (
 	NULL == fields[i]->get_container (),
-	ctxt,
+	ctxt, loc,
 	"%s is already a field of %s",
 	fields[i]->get_debug_string (),
 	fields[i]->get_container ()->get_debug_string ());
@@ -412,8 +418,8 @@ gcc_jit_context_new_opaque_struct (gcc_jit_context *ctxt,
 				   gcc_jit_location *loc,
 				   const char *name)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (name, ctxt, "NULL name");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
+  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
 
   return (gcc_jit_struct *)ctxt->new_struct_type (loc, name);
 }
@@ -421,7 +427,7 @@ gcc_jit_context_new_opaque_struct (gcc_jit_context *ctxt,
 gcc_jit_type *
 gcc_jit_struct_as_type (gcc_jit_struct *struct_type)
 {
-  RETURN_NULL_IF_FAIL (struct_type, NULL, "NULL struct_type");
+  RETURN_NULL_IF_FAIL (struct_type, NULL, NULL, "NULL struct_type");
 
   return static_cast <gcc_jit_type *> (struct_type->as_type ());
 }
@@ -432,20 +438,20 @@ gcc_jit_struct_set_fields (gcc_jit_struct *struct_type,
 			   int num_fields,
 			   gcc_jit_field **fields)
 {
-  RETURN_IF_FAIL (struct_type, NULL, "NULL struct_type");
+  RETURN_IF_FAIL (struct_type, NULL, loc, "NULL struct_type");
   gcc::jit::recording::context *ctxt = struct_type->m_ctxt;
   RETURN_IF_FAIL_PRINTF1 (
-    NULL == struct_type->get_fields (), ctxt,
+    NULL == struct_type->get_fields (), ctxt, loc,
     "%s already has had fields set",
     struct_type->get_debug_string ());
   if (num_fields)
-    RETURN_IF_FAIL (fields, ctxt, "NULL fields ptr");
+    RETURN_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
   for (int i = 0; i < num_fields; i++)
     {
-      RETURN_IF_FAIL (fields[i], ctxt, "NULL field ptr");
+      RETURN_IF_FAIL (fields[i], ctxt, loc, "NULL field ptr");
       RETURN_IF_FAIL_PRINTF2 (
 	NULL == fields[i]->get_container (),
-	ctxt,
+	ctxt, loc,
 	"%s is already a field of %s",
 	fields[i]->get_debug_string (),
 	fields[i]->get_container ()->get_debug_string ());
@@ -462,9 +468,9 @@ gcc_jit_context_new_param (gcc_jit_context *ctxt,
 			   gcc_jit_type *type,
 			   const char *name)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (type, ctxt, "NULL type");
-  RETURN_NULL_IF_FAIL (name, ctxt, "NULL name");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
+  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
+  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
 
   return (gcc_jit_param *)ctxt->new_param (loc, type, name);
 }
@@ -472,7 +478,7 @@ gcc_jit_context_new_param (gcc_jit_context *ctxt,
 gcc_jit_object *
 gcc_jit_param_as_object (gcc_jit_param *param)
 {
-  RETURN_NULL_IF_FAIL (param, NULL, "NULL param");
+  RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");
 
   return static_cast <gcc_jit_object *> (param->as_object ());
 }
@@ -480,7 +486,7 @@ gcc_jit_param_as_object (gcc_jit_param *param)
 gcc_jit_lvalue *
 gcc_jit_param_as_lvalue (gcc_jit_param *param)
 {
-  RETURN_NULL_IF_FAIL (param, NULL, "NULL param");
+  RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");
 
   return (gcc_jit_lvalue *)param->as_lvalue ();
 }
@@ -488,7 +494,7 @@ gcc_jit_param_as_lvalue (gcc_jit_param *param)
 gcc_jit_rvalue *
 gcc_jit_param_as_rvalue (gcc_jit_param *param)
 {
-  RETURN_NULL_IF_FAIL (param, NULL, "NULL param");
+  RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");
 
   return (gcc_jit_rvalue *)param->as_rvalue ();
 }
@@ -503,9 +509,9 @@ gcc_jit_context_new_function (gcc_jit_context *ctxt,
 			      gcc_jit_param **params,
 			      int is_variadic)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (return_type, ctxt, "NULL return_type");
-  RETURN_NULL_IF_FAIL (name, ctxt, "NULL name");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
+  RETURN_NULL_IF_FAIL (return_type, ctxt, loc, "NULL return_type");
+  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
   /* The assembler can only handle certain names, so for now, enforce
      C's rules for identiers upon the name.
      Eventually we'll need some way to interact with e.g. C++ name mangling.  */
@@ -514,7 +520,7 @@ gcc_jit_context_new_function (gcc_jit_context *ctxt,
     char ch = *name;
     RETURN_NULL_IF_FAIL_PRINTF2 (
 	IS_ASCII_ALPHA (ch) || ch == '_',
-	ctxt,
+	ctxt, loc,
 	"name \"%s\" contains invalid character: '%c'",
 	name, ch);
     /* Subsequent chars: */
@@ -522,18 +528,20 @@ gcc_jit_context_new_function (gcc_jit_context *ctxt,
       {
 	RETURN_NULL_IF_FAIL_PRINTF2 (
 	  IS_ASCII_ALNUM (ch) || ch == '_',
-	  ctxt,
+	  ctxt, loc,
 	  "name \"%s\" contains invalid character: '%c'",
 	  name, ch);
       }
   }
-  RETURN_NULL_IF_FAIL ((num_params == 0) || params, ctxt, "NULL params");
+  RETURN_NULL_IF_FAIL_PRINTF1 (
+    (num_params == 0) || params,
+    ctxt, loc,
+    "NULL params creating function %s", name);
   for (int i = 0; i < num_params; i++)
-    if (!params[i])
-      {
-	jit_error (ctxt, "%s: NULL parameter %i", __func__, i);
-	return NULL;
-      }
+    RETURN_NULL_IF_FAIL_PRINTF2 (
+      params[i],
+      ctxt, loc,
+      "NULL parameter %i creating function %s", i, name);
 
   return (gcc_jit_function*)
     ctxt->new_function (loc, kind, return_type, name,
@@ -547,8 +555,8 @@ gcc_jit_function *
 gcc_jit_context_get_builtin_function (gcc_jit_context *ctxt,
 				      const char *name)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (name, ctxt, "NULL name");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (name, ctxt, NULL, "NULL name");
 
   return static_cast <gcc_jit_function *> (ctxt->get_builtin_function (name));
 }
@@ -556,7 +564,7 @@ gcc_jit_context_get_builtin_function (gcc_jit_context *ctxt,
 gcc_jit_object *
 gcc_jit_function_as_object (gcc_jit_function *func)
 {
-  RETURN_NULL_IF_FAIL (func, NULL, "NULL function");
+  RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
 
   return static_cast <gcc_jit_object *> (func->as_object ());
 }
@@ -564,12 +572,12 @@ gcc_jit_function_as_object (gcc_jit_function *func)
 gcc_jit_param *
 gcc_jit_function_get_param (gcc_jit_function *func, int index)
 {
-  RETURN_NULL_IF_FAIL (func, NULL, "NULL function");
+  RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
   gcc::jit::recording::context *ctxt = func->m_ctxt;
-  RETURN_NULL_IF_FAIL (index >= 0, ctxt, "negative index");
+  RETURN_NULL_IF_FAIL (index >= 0, ctxt, NULL, "negative index");
   int num_params = func->get_params ().length ();
   RETURN_NULL_IF_FAIL_PRINTF3 (index < num_params,
-			       ctxt,
+			       ctxt, NULL,
 			       "index of %d is too large (%s has %d params)",
 			       index,
 			       func->get_debug_string (),
@@ -582,9 +590,9 @@ void
 gcc_jit_function_dump_to_dot (gcc_jit_function *func,
 			      const char *path)
 {
-  RETURN_IF_FAIL (func, NULL, "NULL function");
+  RETURN_IF_FAIL (func, NULL, NULL, "NULL function");
   gcc::jit::recording::context *ctxt = func->m_ctxt;
-  RETURN_IF_FAIL (path, ctxt, "NULL path");
+  RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
 
   func->dump_to_dot (path);
 }
@@ -593,9 +601,9 @@ gcc_jit_block*
 gcc_jit_function_new_block (gcc_jit_function *func,
 			    const char *name)
 {
-  RETURN_NULL_IF_FAIL (func, NULL, "NULL function");
+  RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
   RETURN_NULL_IF_FAIL (func->get_kind () != GCC_JIT_FUNCTION_IMPORTED,
-		       func->get_context (),
+		       func->get_context (), NULL,
 		       "cannot add block to an imported function");
   /* name can be NULL.  */
 
@@ -605,7 +613,7 @@ gcc_jit_function_new_block (gcc_jit_function *func,
 gcc_jit_object *
 gcc_jit_block_as_object (gcc_jit_block *block)
 {
-  RETURN_NULL_IF_FAIL (block, NULL, "NULL block");
+  RETURN_NULL_IF_FAIL (block, NULL, NULL, "NULL block");
 
   return static_cast <gcc_jit_object *> (block->as_object ());
 }
@@ -613,7 +621,7 @@ gcc_jit_block_as_object (gcc_jit_block *block)
 gcc_jit_function *
 gcc_jit_block_get_function (gcc_jit_block *block)
 {
-  RETURN_NULL_IF_FAIL (block, NULL, "NULL block");
+  RETURN_NULL_IF_FAIL (block, NULL, NULL, "NULL block");
 
   return static_cast <gcc_jit_function *> (block->get_function ());
 }
@@ -624,9 +632,9 @@ gcc_jit_context_new_global (gcc_jit_context *ctxt,
 			    gcc_jit_type *type,
 			    const char *name)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (type, ctxt, "NULL type");
-  RETURN_NULL_IF_FAIL (name, ctxt, "NULL name");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
+  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
+  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
 
   return (gcc_jit_lvalue *)ctxt->new_global (loc, type, name);
 }
@@ -634,7 +642,7 @@ gcc_jit_context_new_global (gcc_jit_context *ctxt,
 gcc_jit_object *
 gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue)
 {
-  RETURN_NULL_IF_FAIL (lvalue, NULL, "NULL lvalue");
+  RETURN_NULL_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
 
   return static_cast <gcc_jit_object *> (lvalue->as_object ());
 }
@@ -642,7 +650,7 @@ gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue)
 gcc_jit_rvalue *
 gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue *lvalue)
 {
-  RETURN_NULL_IF_FAIL (lvalue, NULL, "NULL lvalue");
+  RETURN_NULL_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
 
   return (gcc_jit_rvalue *)lvalue->as_rvalue ();
 }
@@ -650,7 +658,7 @@ gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue *lvalue)
 gcc_jit_object *
 gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue)
 {
-  RETURN_NULL_IF_FAIL (rvalue, NULL, "NULL rvalue");
+  RETURN_NULL_IF_FAIL (rvalue, NULL, NULL, "NULL rvalue");
 
   return static_cast <gcc_jit_object *> (rvalue->as_object ());
 }
@@ -658,7 +666,7 @@ gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue)
 gcc_jit_type *
 gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue)
 {
-  RETURN_NULL_IF_FAIL (rvalue, NULL, "NULL rvalue");
+  RETURN_NULL_IF_FAIL (rvalue, NULL, NULL, "NULL rvalue");
 
   return static_cast <gcc_jit_type *> (rvalue->get_type ());
 }
@@ -668,8 +676,8 @@ gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt,
 				     gcc_jit_type *numeric_type,
 				     int value)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (numeric_type, ctxt, "NULL type");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (numeric_type, ctxt, NULL, "NULL type");
 
   return (gcc_jit_rvalue *)ctxt->new_rvalue_from_int (numeric_type, value);
 }
@@ -678,8 +686,8 @@ gcc_jit_rvalue *
 gcc_jit_context_zero (gcc_jit_context *ctxt,
 		      gcc_jit_type *numeric_type)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (numeric_type, ctxt, "NULL type");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (numeric_type, ctxt, NULL, "NULL type");
 
   return gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0);
 }
@@ -688,8 +696,8 @@ gcc_jit_rvalue *
 gcc_jit_context_one (gcc_jit_context *ctxt,
 		     gcc_jit_type *numeric_type)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (numeric_type, ctxt, "NULL type");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (numeric_type, ctxt, NULL, "NULL type");
 
   return gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1);
 }
@@ -699,8 +707,8 @@ gcc_jit_context_new_rvalue_from_double (gcc_jit_context *ctxt,
 					gcc_jit_type *numeric_type,
 					double value)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (numeric_type, ctxt, "NULL type");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (numeric_type, ctxt, NULL, "NULL type");
 
   return (gcc_jit_rvalue *)ctxt->new_rvalue_from_double (numeric_type, value);
 }
@@ -710,10 +718,11 @@ gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt,
 				     gcc_jit_type *pointer_type,
 				     void *value)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (pointer_type, ctxt, "NULL type");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (pointer_type, ctxt, NULL, "NULL type");
   RETURN_NULL_IF_FAIL_PRINTF1 (
-    pointer_type->dereference (), ctxt,
+    pointer_type->dereference (),
+    ctxt, NULL,
     "not a pointer type (type: %s)",
     pointer_type->get_debug_string ());
 
@@ -724,10 +733,11 @@ gcc_jit_rvalue *
 gcc_jit_context_null (gcc_jit_context *ctxt,
 		      gcc_jit_type *pointer_type)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (pointer_type, ctxt, "NULL type");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (pointer_type, ctxt, NULL, "NULL type");
   RETURN_NULL_IF_FAIL_PRINTF1 (
-    pointer_type->dereference (), ctxt,
+    pointer_type->dereference (),
+    ctxt, NULL,
     "not a pointer type (type: %s)",
     pointer_type->get_debug_string ());
 
@@ -738,8 +748,8 @@ gcc_jit_rvalue *
 gcc_jit_context_new_string_literal (gcc_jit_context *ctxt,
 				    const char *value)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (value, ctxt, "NULL value");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (value, ctxt, NULL, "NULL value");
 
   return (gcc_jit_rvalue *)ctxt->new_string_literal (value);
 }
@@ -751,10 +761,10 @@ gcc_jit_context_new_unary_op (gcc_jit_context *ctxt,
 			      gcc_jit_type *result_type,
 			      gcc_jit_rvalue *rvalue)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
   /* op is checked by the inner function.  */
-  RETURN_NULL_IF_FAIL (result_type, ctxt, "NULL result_type");
-  RETURN_NULL_IF_FAIL (rvalue, ctxt, "NULL rvalue");
+  RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
+  RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
 
   return (gcc_jit_rvalue *)ctxt->new_unary_op (loc, op, result_type, rvalue);
 }
@@ -766,14 +776,14 @@ gcc_jit_context_new_binary_op (gcc_jit_context *ctxt,
 			       gcc_jit_type *result_type,
 			       gcc_jit_rvalue *a, gcc_jit_rvalue *b)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
   /* op is checked by the inner function.  */
-  RETURN_NULL_IF_FAIL (result_type, ctxt, "NULL result_type");
-  RETURN_NULL_IF_FAIL (a, ctxt, "NULL a");
-  RETURN_NULL_IF_FAIL (b, ctxt, "NULL b");
+  RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
+  RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
+  RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
   RETURN_NULL_IF_FAIL_PRINTF4 (
     a->get_type () == b->get_type (),
-    ctxt,
+    ctxt, loc,
     "mismatching types for binary op:"
     " a: %s (type: %s) b: %s (type: %s)",
     a->get_debug_string (),
@@ -790,13 +800,13 @@ gcc_jit_context_new_comparison (gcc_jit_context *ctxt,
 				enum gcc_jit_comparison op,
 				gcc_jit_rvalue *a, gcc_jit_rvalue *b)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
   /* op is checked by the inner function.  */
-  RETURN_NULL_IF_FAIL (a, ctxt, "NULL a");
-  RETURN_NULL_IF_FAIL (b, ctxt, "NULL b");
+  RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
+  RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
   RETURN_NULL_IF_FAIL_PRINTF4 (
     a->get_type ()->unqualified () == b->get_type ()->unqualified (),
-    ctxt,
+    ctxt, loc,
     "mismatching types for comparison:"
     " a: %s (type: %s) b: %s (type: %s)",
     a->get_debug_string (),
@@ -813,17 +823,17 @@ gcc_jit_context_new_call (gcc_jit_context *ctxt,
 			  gcc_jit_function *func,
 			  int numargs , gcc_jit_rvalue **args)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (func, ctxt, "NULL function");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
+  RETURN_NULL_IF_FAIL (func, ctxt, loc, "NULL function");
   if (numargs)
-    RETURN_NULL_IF_FAIL (args, ctxt, "NULL args");
+    RETURN_NULL_IF_FAIL (args, ctxt, loc, "NULL args");
 
   int min_num_params = func->get_params ().length ();
   bool is_variadic = func->is_variadic ();
 
   RETURN_NULL_IF_FAIL_PRINTF3 (
     numargs >= min_num_params,
-    ctxt,
+    ctxt, loc,
     "not enough arguments to function \"%s\""
     " (got %i args, expected %i)",
     func->get_name ()->c_str (),
@@ -831,7 +841,7 @@ gcc_jit_context_new_call (gcc_jit_context *ctxt,
 
   RETURN_NULL_IF_FAIL_PRINTF3 (
     (numargs == min_num_params || is_variadic),
-    ctxt,
+    ctxt, loc,
     "too many arguments to function \"%s\""
     " (got %i args, expected %i)",
     func->get_name ()->c_str (),
@@ -844,7 +854,7 @@ gcc_jit_context_new_call (gcc_jit_context *ctxt,
 
       RETURN_NULL_IF_FAIL_PRINTF4 (
 	arg,
-	ctxt,
+	ctxt, loc,
 	"NULL argument %i to function \"%s\":"
 	" param %s (type: %s)",
 	i + 1,
@@ -855,7 +865,7 @@ gcc_jit_context_new_call (gcc_jit_context *ctxt,
       RETURN_NULL_IF_FAIL_PRINTF6 (
 	compatible_types (param->get_type (),
 			  arg->get_type ()),
-	ctxt,
+	ctxt, loc,
 	"mismatching types for argument %d of function \"%s\":"
 	" assignment to param %s (type: %s) from %s (type: %s)",
 	i + 1,
@@ -878,9 +888,9 @@ gcc_jit_context_new_cast (gcc_jit_context *ctxt,
 			  gcc_jit_rvalue *rvalue,
 			  gcc_jit_type *type)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (rvalue, ctxt, "NULL rvalue");
-  RETURN_NULL_IF_FAIL (type, ctxt, "NULL type");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
+  RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
+  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
 
   return static_cast <gcc_jit_rvalue *> (ctxt->new_cast (loc, rvalue, type));
 }
@@ -891,11 +901,12 @@ gcc_jit_context_new_array_access (gcc_jit_context *ctxt,
 				  gcc_jit_rvalue *ptr,
 				  gcc_jit_rvalue *index)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_NULL_IF_FAIL (ptr, ctxt, "NULL ptr");
-  RETURN_NULL_IF_FAIL (index, ctxt, "NULL index");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
+  RETURN_NULL_IF_FAIL (ptr, ctxt, loc, "NULL ptr");
+  RETURN_NULL_IF_FAIL (index, ctxt, loc, "NULL index");
   RETURN_NULL_IF_FAIL_PRINTF2 (
-    ptr->get_type ()->dereference (), ctxt,
+    ptr->get_type ()->dereference (),
+    ctxt, loc,
     "%s (type: %s) is not a pointer",
     ptr->get_debug_string (),
     ptr->get_type ()->get_debug_string ());
@@ -906,7 +917,7 @@ gcc_jit_context_new_array_access (gcc_jit_context *ctxt,
 gcc_jit_context *
 gcc_jit_object_get_context (gcc_jit_object *obj)
 {
-  RETURN_NULL_IF_FAIL (obj, NULL, "NULL object");
+  RETURN_NULL_IF_FAIL (obj, NULL, NULL, "NULL object");
 
   return static_cast <gcc_jit_context *> (obj->get_context ());
 }
@@ -914,7 +925,7 @@ gcc_jit_object_get_context (gcc_jit_object *obj)
 const char *
 gcc_jit_object_get_debug_string (gcc_jit_object *obj)
 {
-  RETURN_NULL_IF_FAIL (obj, NULL, "NULL object");
+  RETURN_NULL_IF_FAIL (obj, NULL, NULL, "NULL object");
 
   return obj->get_debug_string ();
 }
@@ -924,10 +935,10 @@ gcc_jit_lvalue_access_field (gcc_jit_lvalue *struct_,
 			     gcc_jit_location *loc,
 			     gcc_jit_field *field)
 {
-  RETURN_NULL_IF_FAIL (struct_, NULL, "NULL struct");
+  RETURN_NULL_IF_FAIL (struct_, NULL, loc, "NULL struct");
   gcc::jit::recording::context *ctxt = struct_->m_ctxt;
-  RETURN_NULL_IF_FAIL (field, ctxt, "NULL field");
-  RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt,
+  RETURN_NULL_IF_FAIL (field, ctxt, loc, "NULL field");
+  RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
 			       "field %s has not been placed in a struct",
 			       field->get_debug_string ());
 
@@ -939,10 +950,10 @@ gcc_jit_rvalue_access_field (gcc_jit_rvalue *struct_,
 			     gcc_jit_location *loc,
 			     gcc_jit_field *field)
 {
-  RETURN_NULL_IF_FAIL (struct_, NULL, "NULL struct");
+  RETURN_NULL_IF_FAIL (struct_, NULL, loc, "NULL struct");
   gcc::jit::recording::context *ctxt = struct_->m_ctxt;
-  RETURN_NULL_IF_FAIL (field, ctxt, "NULL field");
-  RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt,
+  RETURN_NULL_IF_FAIL (field, ctxt, loc, "NULL field");
+  RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
 			       "field %s has not been placed in a struct",
 			       field->get_debug_string ());
 
@@ -954,15 +965,16 @@ gcc_jit_rvalue_dereference_field (gcc_jit_rvalue *ptr,
 				  gcc_jit_location *loc,
 				  gcc_jit_field *field)
 {
-  RETURN_NULL_IF_FAIL (ptr, NULL, "NULL ptr");
-  RETURN_NULL_IF_FAIL (field, NULL, "NULL field");
+  RETURN_NULL_IF_FAIL (ptr, NULL, loc, "NULL ptr");
+  RETURN_NULL_IF_FAIL (field, NULL, loc, "NULL field");
   gcc::jit::recording::type *underlying_type =
     ptr->get_type ()->dereference ();
-  RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt,
+  RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
 			       "field %s has not been placed in a struct",
 			       field->get_debug_string ());
   RETURN_NULL_IF_FAIL_PRINTF3 (
-    underlying_type, ptr->m_ctxt,
+    underlying_type,
+    ptr->m_ctxt, loc,
     "dereference of non-pointer %s (type: %s) when accessing ->%s",
     ptr->get_debug_string (),
     ptr->get_type ()->get_debug_string (),
@@ -970,7 +982,7 @@ gcc_jit_rvalue_dereference_field (gcc_jit_rvalue *ptr,
   RETURN_NULL_IF_FAIL_PRINTF2 (
     (field->get_container ()->unqualified ()
      == underlying_type->unqualified ()),
-    ptr->m_ctxt,
+    ptr->m_ctxt, loc,
     "%s is not a field of %s",
     field->get_debug_string (),
     underlying_type->get_debug_string ());
@@ -982,13 +994,14 @@ gcc_jit_lvalue *
 gcc_jit_rvalue_dereference (gcc_jit_rvalue *rvalue,
 			    gcc_jit_location *loc)
 {
-  RETURN_NULL_IF_FAIL (rvalue, NULL, "NULL rvalue");
+  RETURN_NULL_IF_FAIL (rvalue, NULL, loc, "NULL rvalue");
 
   gcc::jit::recording::type *underlying_type =
     rvalue->get_type ()->dereference ();
 
   RETURN_NULL_IF_FAIL_PRINTF2 (
-    underlying_type, rvalue->m_ctxt,
+    underlying_type,
+    rvalue->m_ctxt, loc,
     "dereference of non-pointer %s (type: %s)",
     rvalue->get_debug_string (),
     rvalue->get_type ()->get_debug_string ());
@@ -1000,7 +1013,7 @@ gcc_jit_rvalue *
 gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue,
 			    gcc_jit_location *loc)
 {
-  RETURN_NULL_IF_FAIL (lvalue, NULL, "NULL lvalue");
+  RETURN_NULL_IF_FAIL (lvalue, NULL, loc, "NULL lvalue");
 
   return (gcc_jit_rvalue *)lvalue->get_address (loc);
 }
@@ -1011,13 +1024,13 @@ gcc_jit_function_new_local (gcc_jit_function *func,
 			    gcc_jit_type *type,
 			    const char *name)
 {
-  RETURN_NULL_IF_FAIL (func, NULL, "NULL function");
+  RETURN_NULL_IF_FAIL (func, NULL, loc, "NULL function");
   gcc::jit::recording::context *ctxt = func->m_ctxt;
   RETURN_NULL_IF_FAIL (func->get_kind () != GCC_JIT_FUNCTION_IMPORTED,
-		       ctxt,
+		       ctxt, loc,
 		       "Cannot add locals to an imported function");
-  RETURN_NULL_IF_FAIL (type, ctxt, "NULL type");
-  RETURN_NULL_IF_FAIL (name, ctxt, "NULL name");
+  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
+  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
 
   return (gcc_jit_lvalue *)func->new_local (loc, type, name);
 }
@@ -1027,9 +1040,9 @@ gcc_jit_block_add_eval (gcc_jit_block *block,
 			gcc_jit_location *loc,
 			gcc_jit_rvalue *rvalue)
 {
-  RETURN_IF_NOT_VALID_BLOCK (block);
+  RETURN_IF_NOT_VALID_BLOCK (block, loc);
   gcc::jit::recording::context *ctxt = block->get_context ();
-  RETURN_IF_FAIL (rvalue, ctxt, "NULL rvalue");
+  RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
 
   return block->add_eval (loc, rvalue);
 }
@@ -1040,14 +1053,14 @@ gcc_jit_block_add_assignment (gcc_jit_block *block,
 			      gcc_jit_lvalue *lvalue,
 			      gcc_jit_rvalue *rvalue)
 {
-  RETURN_IF_NOT_VALID_BLOCK (block);
+  RETURN_IF_NOT_VALID_BLOCK (block, loc);
   gcc::jit::recording::context *ctxt = block->get_context ();
-  RETURN_IF_FAIL (lvalue, ctxt, "NULL lvalue");
-  RETURN_IF_FAIL (rvalue, ctxt, "NULL rvalue");
+  RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue");
+  RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
   RETURN_IF_FAIL_PRINTF4 (
     compatible_types (lvalue->get_type (),
 		      rvalue->get_type ()),
-    ctxt,
+    ctxt, loc,
     "mismatching types:"
     " assignment to %s (type: %s) from %s (type: %s)",
     lvalue->get_debug_string (),
@@ -1065,11 +1078,11 @@ gcc_jit_block_add_assignment_op (gcc_jit_block *block,
 				 enum gcc_jit_binary_op op,
 				 gcc_jit_rvalue *rvalue)
 {
-  RETURN_IF_NOT_VALID_BLOCK (block);
+  RETURN_IF_NOT_VALID_BLOCK (block, loc);
   gcc::jit::recording::context *ctxt = block->get_context ();
-  RETURN_IF_FAIL (lvalue, ctxt, "NULL lvalue");
+  RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue");
   /* FIXME: op is checked by new_binary_op */
-  RETURN_IF_FAIL (rvalue, ctxt, "NULL rvalue");
+  RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
 
   return block->add_assignment_op (loc, lvalue, op, rvalue);
 }
@@ -1090,19 +1103,19 @@ gcc_jit_block_end_with_conditional (gcc_jit_block *block,
 				    gcc_jit_block *on_true,
 				    gcc_jit_block *on_false)
 {
-  RETURN_IF_NOT_VALID_BLOCK (block);
+  RETURN_IF_NOT_VALID_BLOCK (block, loc);
   gcc::jit::recording::context *ctxt = block->get_context ();
-  RETURN_IF_FAIL (boolval, ctxt, "NULL boolval");
+  RETURN_IF_FAIL (boolval, ctxt, loc, "NULL boolval");
   RETURN_IF_FAIL_PRINTF2 (
-   is_bool (boolval), ctxt,
+   is_bool (boolval), ctxt, loc,
    "%s (type: %s) is not of boolean type ",
    boolval->get_debug_string (),
    boolval->get_type ()->get_debug_string ());
-  RETURN_IF_FAIL (on_true, ctxt, "NULL on_true");
-  RETURN_IF_FAIL (on_true, ctxt, "NULL on_false");
+  RETURN_IF_FAIL (on_true, ctxt, loc, "NULL on_true");
+  RETURN_IF_FAIL (on_true, ctxt, loc, "NULL on_false");
   RETURN_IF_FAIL_PRINTF4 (
     block->get_function () == on_true->get_function (),
-    ctxt,
+    ctxt, loc,
     "\"on_true\" block is not in same function:"
     " source block %s is in function %s"
     " whereas target block %s is in function %s",
@@ -1112,7 +1125,7 @@ gcc_jit_block_end_with_conditional (gcc_jit_block *block,
     on_true->get_function ()->get_debug_string ());
   RETURN_IF_FAIL_PRINTF4 (
     block->get_function () == on_false->get_function (),
-    ctxt,
+    ctxt, loc,
     "\"on_false\" block is not in same function:"
     " source block %s is in function %s"
     " whereas target block %s is in function %s",
@@ -1129,9 +1142,9 @@ gcc_jit_block_add_comment (gcc_jit_block *block,
 			   gcc_jit_location *loc,
 			   const char *text)
 {
-  RETURN_IF_NOT_VALID_BLOCK (block);
+  RETURN_IF_NOT_VALID_BLOCK (block, loc);
   gcc::jit::recording::context *ctxt = block->get_context ();
-  RETURN_IF_FAIL (text, ctxt, "NULL text");
+  RETURN_IF_FAIL (text, ctxt, loc, "NULL text");
 
   block->add_comment (loc, text);
 }
@@ -1141,12 +1154,12 @@ gcc_jit_block_end_with_jump (gcc_jit_block *block,
 			     gcc_jit_location *loc,
 			     gcc_jit_block *target)
 {
-  RETURN_IF_NOT_VALID_BLOCK (block);
+  RETURN_IF_NOT_VALID_BLOCK (block, loc);
   gcc::jit::recording::context *ctxt = block->get_context ();
-  RETURN_IF_FAIL (target, ctxt, "NULL target");
+  RETURN_IF_FAIL (target, ctxt, loc, "NULL target");
   RETURN_IF_FAIL_PRINTF4 (
     block->get_function () == target->get_function (),
-    ctxt,
+    ctxt, loc,
     "target block is not in same function:"
     " source block %s is in function %s"
     " whereas target block %s is in function %s",
@@ -1163,15 +1176,15 @@ gcc_jit_block_end_with_return (gcc_jit_block *block,
 			       gcc_jit_location *loc,
 			       gcc_jit_rvalue *rvalue)
 {
-  RETURN_IF_NOT_VALID_BLOCK (block);
+  RETURN_IF_NOT_VALID_BLOCK (block, loc);
   gcc::jit::recording::context *ctxt = block->get_context ();
   gcc::jit::recording::function *func = block->get_function ();
-  RETURN_IF_FAIL (rvalue, ctxt, "NULL rvalue");
+  RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
   RETURN_IF_FAIL_PRINTF4 (
     compatible_types (
       func->get_return_type (),
       rvalue->get_type ()),
-    ctxt,
+    ctxt, loc,
     "mismatching types:"
     " return of %s (type: %s) in function %s (return type: %s)",
     rvalue->get_debug_string (),
@@ -1186,12 +1199,12 @@ void
 gcc_jit_block_end_with_void_return (gcc_jit_block *block,
 				    gcc_jit_location *loc)
 {
-  RETURN_IF_NOT_VALID_BLOCK (block);
+  RETURN_IF_NOT_VALID_BLOCK (block, loc);
   gcc::jit::recording::context *ctxt = block->get_context ();
   gcc::jit::recording::function *func = block->get_function ();
   RETURN_IF_FAIL_PRINTF2 (
     func->get_return_type () == ctxt->get_type (GCC_JIT_TYPE_VOID),
-    ctxt,
+    ctxt, loc,
     "mismatching types:"
     " void return in function %s (return type: %s)",
     func->get_debug_string (),
@@ -1209,7 +1222,7 @@ gcc_jit_context_set_str_option (gcc_jit_context *ctxt,
 				enum gcc_jit_str_option opt,
 				const char *value)
 {
-  RETURN_IF_FAIL (ctxt, NULL, "NULL context");
+  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
   /* opt is checked by the inner function.
      value can be NULL.  */
 
@@ -1221,7 +1234,7 @@ gcc_jit_context_set_int_option (gcc_jit_context *ctxt,
 				enum gcc_jit_int_option opt,
 				int value)
 {
-  RETURN_IF_FAIL (ctxt, NULL, "NULL context");
+  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
   /* opt is checked by the inner function.  */
 
   ctxt->set_int_option (opt, value);
@@ -1232,7 +1245,7 @@ gcc_jit_context_set_bool_option (gcc_jit_context *ctxt,
 				 enum gcc_jit_bool_option opt,
 				 int value)
 {
-  RETURN_IF_FAIL (ctxt, NULL, "NULL context");
+  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
   /* opt is checked by the inner function.  */
 
   ctxt->set_bool_option (opt, value);
@@ -1241,7 +1254,7 @@ gcc_jit_context_set_bool_option (gcc_jit_context *ctxt,
 gcc_jit_result *
 gcc_jit_context_compile (gcc_jit_context *ctxt)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
 
   return (gcc_jit_result *)ctxt->compile ();
 }
@@ -1251,15 +1264,15 @@ gcc_jit_context_dump_to_file (gcc_jit_context *ctxt,
 			      const char *path,
 			      int update_locations)
 {
-  RETURN_IF_FAIL (ctxt, NULL, "NULL context");
-  RETURN_IF_FAIL (path, ctxt, "NULL path");
+  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+  RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
   ctxt->dump_to_file (path, update_locations);
 }
 
 const char *
 gcc_jit_context_get_first_error (gcc_jit_context *ctxt)
 {
-  RETURN_NULL_IF_FAIL (ctxt, NULL, "NULL context");
+  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
 
   return ctxt->get_first_error ();
 }
@@ -1268,8 +1281,8 @@ void *
 gcc_jit_result_get_code (gcc_jit_result *result,
 			 const char *fnname)
 {
-  RETURN_NULL_IF_FAIL (result, NULL, "NULL result");
-  RETURN_NULL_IF_FAIL (fnname, NULL, "NULL fnname");
+  RETURN_NULL_IF_FAIL (result, NULL, NULL, "NULL result");
+  RETURN_NULL_IF_FAIL (fnname, NULL, NULL, "NULL fnname");
 
   return result->get_code (fnname);
 }
@@ -1277,7 +1290,7 @@ gcc_jit_result_get_code (gcc_jit_result *result,
 void
 gcc_jit_result_release (gcc_jit_result *result)
 {
-  RETURN_IF_FAIL (result, NULL, "NULL result");
+  RETURN_IF_FAIL (result, NULL, NULL, "NULL result");
 
   delete result;
 }
-- 
1.8.5.3



More information about the Gcc-patches mailing list