[diagnostics-branch] use precise locations in C front-end

Aldy Hernandez aldyh@redhat.com
Fri Dec 12 17:40:00 GMT 2008


Hi folks.

The following patch is a top down approach for adding more precise
location information to the C front-end.  We start with the parser, and
push locations down as we build expressions and declarations.

Virtually all the C front-end is done, with the big exception of the
build_fold*/fold* infrastructure.

The other languages are currently using place-holders in the form of
input_location for now.

I'll be leaving on vacation till mid January, so the rest of the work
will have to wait till then.

Tested on x86-Linux.

Aldy, Professional Gypsy

	* c-tree.h (check_for_loop_decls, undeclared_variable,
	build_component_ref, build_array_ref, build_external_ref,
	c_expr_sizeof_expr, c_expr_sizeof_type, parser_build_unary_op,
	build_conditional_expr, build_compound_expr, c_cast_expr,
	build_c_cast, build_asm_expr, c_end_compound_stmt, c_finish_stmt_expr,
	c_finish_return, c_finish_omp_parallel, c_finish_omp_task): New
	argument.
	* c-semantics.c (build_stmt): Same.
	(build_case_label): Same.
	* c-decl.c (c_finish_incomplete_decl): Pass location on down.
	(undeclared_variable): New argument.
	(make_label): Same.
	(lookup_label): Pass location on down.
	(define_label): Same.
	(finish_decl): Same.
	(build_compound_literal): Same.
	(finish_struct): Same.
	(finish_function): Do not set location here.
	(check_for_loop_decls): New argument.
	* tree.c (save_expr): Set location.
	(build_empty_stmt): New argument.
	* tree.h (build_empty_stmt): New argument to build_empty_stmt.
	(CAN_HAVE_LOCATION_P): Make sure we have a non empty node.
	* builtins.c (gimplify_va_arg_expr): Use locations.
	(expand_builtin_sync_operation): Same.
	* c-typeck.c (build_component_ref): New argument.
	(build_array_ref): Same.
	(build_external_ref): Same.
	(c_expr_sizeof_expr): Same.
	(c_expr_sizeof_type): Same.
	(parser_build_unary_op): Same.
	(build_conditional_expr): Same.
	(build_compound_expr): Pass location on down.
	(build_compound_expr): New argument.
	(build_c_cast): Same.
	(c_cast_expr): Same.
	(build_asm_expr): Same.
	(c_finish_return): Same.
	(c_process_expr_stmt): Pass location on down.
	(c_finish_stmt_expr): New argument.
	(push_clenaup): Same.
	(c_finish_omp_parallel): Same.
	(c_finish_omp_task): Same.
	* gimplify.c (gimplify_call_expr): Pass location on down.
	* c-omp.c (c_finish_omp_master): New argument.
	(c_finish_omp_critical): Same.
	(c_finish_omp_ordered): Same.
	(c_finish_omp_barrier): Same.
	(-c_finish_omp_taskwait): Same.
	(c_finish_omp_atomic): Same.
	(c_finish_omp_flush): Same.
	* tree-inline.c (copy_tree_body_r): Pass location on down.
	* c-gimplify.c (c_build_bind_expr): New argument.
	* c-common.c (c_common_truthvalue_conversion): Pass location on down.
	(c_sizeof_or_alignof_type): New argument.
	(c_alignof_expr): Same.
	(build_va_arg): Same.
	(c_add_case_label): Same.
	* c-common.h (c_sizeof_or_alignof_type, c_alignof_expr,
	c_sizeof, c_alignof, build_va_arg, build_stmt, build_case_label,
	c_build_bind_expr, objc_build_selector_expr, objc_build_throw_stmt,
	c_finish_omp_master, c_finish_omp_critical, c_finish_omp_ordered,
	c_finish_omp_barrier, c_finish_omp_atomic, c_finish_omp_flush,
	c_finish_omp_taskwait, c_finish_omp_for, c_split_parallel_clauses):
	New argument.
	* stub-objc.c (objc_build_selector_expr): Same.
	(objc_build_throw_stmt): Same.
	* c-parser.c (c_parser_declaration_or_fndef): Pass location on down.
	(c_parser_initelt): Same.
	(c_parser_compound_statement): Same.
	(c_parser_compound_statement_nostart): Same.
	(c_parser_label): Same.
	(c_parser_statement_after_labels): Same.
	(c_parser_if_body): Same.
	(c_parser_else_body): Same.
	(c_parser_if_statement): Same.
	(c_parser_switch_statement): Same.
	(c_parser_while_statement): Same.
	(c_parser_do_statement): Same.
	(c_parser_for_statement): Same.
	(c_parser_asm_statement): Same.
	(c_parser_conditional_expression): Same.
	(c_parser_binary_expression): Same.
	(c_parser_cast_expression): Same.
	(c_parser_unary_expression): Same.
	(c_parser_sizeof_expression): Same.
	(c_parser_alignof_expression): Same.
	(c_parser_postfix_expression): Same.
	(c_parser_expression): Same.
	(c_parser_objc_receiver): Same.
	(c_parser_omp_variable_list): Same.
	(c_parser_omp_structured_block): Same.
	(c_parser_omp_atomic): New argument.
	(c_parser_omp_barrier): Same.
	(c_parser_omp_critical): Same.
	(c_parser_omp_flush): Pass location on down.
	(c_parser_omp_for_loop): New argument.
	(c_parser_omp_for): Same.
	(c_parser_omp_master): Same.
	(c_parser_omp_ordered): Same.
	(c_parser_omp_sections_scope): Same.
	(c_parser_omp_sections): Same.
	(c_parser_omp_parallel): Same.
	(c_parser_omp_single): Same.
	(c_parser_omp_task): Same.
	(c_parser_omp_taskwait): Pass location on down.
	(c_parser_omp_construct): Same.
	(c_parser_omp_threadprivate): Same.

java/
	* java-gimplify.c (java_gimplify_block): New argument to
	build_empty_stmt.
	* expr.c (force_evaluation_order): Same.
objc/
	* objc-act.c (objc_build_component_ref): Pass location to
	build_compound_ref.
	(build_module_initializer_routine): Pass location to
	c_end_compound_stmt.
	(objc_generate_static_init_call): Pass location to build_stmt.
	(build_typed_selector_reference): New location argument.
	(build_selector_reference): Same.
	(objc_substitute_decl): Pass location to build_array_ref.
	(next_sjlj_build_try_catch_finally): Pass location to build_stmt.
	(objc_begin_catch_clause): Same.
	(objc_finish_try_stmt): Same.
	(objc_finish_catch_clause): Pass location to c_end_compound_stmt.
	(objc_build_throw_stmt): New argument.
	(generate_shared_structures): Pass location to build_c_cast.
	(objc_build_message_expr): Use local location.
	(objc_finish_message_expr): Use input_location.
	(build_objc_method_call): New argument.
	(objc_build_selector_expr): Same.
	(get_super_receiver): Pass location to build_c_cast,
	build_modify_expr, build_compound_expr.
testsuite/
	* gcc.dg/gomp/pr27415.c: Move firstprivate diagnostics to correct
	line.
	* gcc.dg/label-decl-2.c: Move label diagnostic to correct line.
objcp/
	* objcp-decl.h (c_end_compound_stmt): New argument.
cp/
	* typeck.c (cxx_sizeof_or_alignof_type): Pass location to
	c_sizeof_or_alignof_type.
	(build_array_ref): New argument.
	(build_compound_expr): Same.
	(build_const_cast): Same.
	(build_ptrmemfunc): Pass location to build_c_cast.
	* init.c (avoid_placement_new_aliasing): Pass location to
	build_stmt.
	(build_vec_delete_1): Pass location to cp_build_modify_expr,
	build_compound_expr.
	* class.c (build_vtbl_ref_1): Pass location to build_array_ref.
	* decl.c (poplevel): Pass location to c_build_bind_expr.
	(finish_case_label): Pass location to build_case_label.
	(finish_constructor_body): Same.
	(finish_destructor_body): Pass location to build_stmt.
	(cxx_maybe_build_cleanup): Same, but to build_compound_expr.
	* call.c (build_new_op): Pass location to build_array_ref.
	(build_x_va_arg): Pass location to build_va_arg.
	* except.c (expand_end_catch_block): Pass location to
	build_stmt.
	* cp-tree.h (build_array_ref): New argument.
	(build_compound_expr): Same.
	(build_c_cast): Same.
	* cp-gimplify.c (gimplify_if_stmt): Pass location on down.
	(gimplify_switch_stmt): Same.
	* typeck2.c (split_nonconstant_init_1): Same.
	* pt.c (tsubst_copy): Same.
	* semantics.c (add_decl_expr): Same.
	(do_poplevel): Same.
	(push_cleanup): Same.
	(finish_goto_stmt): Same.
	(finish_expr_stmt): Same.
	(begin_if_stmt): Same.
	(begin_while_stmt): Same.
	(begin_do_stmt): Same.
	(finish_return_stmt): Same.
	(begin_for_stmt): Same.
	(finish_break_stmt): Same.
	(finish_continue_stmt): Same.
	(begin_switch_stmt): Same.
	(begin_try_block): Same.
	(begin_handler): Same.
	(finish_asm_stmt): Same.
	(finish_label_stmt): Same.
	(finish_stmt_expr_expr): Same.
	(finalize_nrv_r): Same.
	(finish_omp_atomic): Same.
	* name-lookup.c (do_using_directive): Same.
	* decl2.c (grok_array_decl): Same.
	* parser.c (cp_parser_cast_expression): Same.
	(cp_parser_selection_statement): Same.
	(cp_parser_implicitly_scoped_statement): Same.
	(cp_parser_objc_selector_expression): Same.
	(cp_parser_objc_synchronized_statement): Same.
	(cp_parser_objc_throw_statement): Same.
	(cp_parser_omp_critical): Same.
	(cp_parser_omp_master): Same.
fortran/
	* trans-array.c (gfc_trans_allocate_array_storage): Pass
	location on down.
	(gfc_trans_array_constructor_value): Same.
	(gfc_trans_scalarized_loop_end): Same.
	(gfc_conv_ss_startstride): Same.
	(gfc_trans_g77_array): Same.
	(gfc_trans_dummy_array_bias): Same.
	(gfc_conv_array_parameter): Same.
	(structure_alloc_comps): Same.
	* trans-expr.c (gfc_conv_function_call): Same.
	(fill_with_spaces): Same.
	(gfc_trans_string_copy): Same.
	(gfc_trans_scalar_assign): Same.
	* trans-stmt.c (gfc_trans_goto): Same.
	(gfc_trans_if_1): Same.
	(gfc_trans_simple_do): Same.
	(gfc_trans_do): Same.
	(gfc_trans_do_while): Same.
	(gfc_trans_logical_select): Same.
	(gfc_trans_select): Same.
	(gfc_trans_forall_loop): Same.
	(gfc_trans_nested_forall_loop): Same.
	(generate_loop_for_temp_to_lhs): Same.
	(generate_loop_for_rhs_to_temp): Same.
	(gfc_trans_forall_1): Same.
	(gfc_trans_where_assign): Same.
	(gfc_trans_where_3): Same.
	(gfc_trans_allocate): Same.
	* trans.c (gfc_finish_block): Same.
	(gfc_trans_runtime_check): Same.
	(gfc_call_malloc): Same.
	(gfc_allocate_with_status): Same.
	(gfc_call_free): Same.
	(gfc_deallocate_with_status): Same.
	(gfc_call_realloc): Same.
	(gfc_trans_code): Same.
	* trans-decl.c (gfc_init_default_dt): Same.
	(gfc_generate_constructors): Same.
	* trans-io.c (gfc_trans_io_runtime_check): Same.
	* trans-intrinsic.c (gfc_conv_intrinsic_ctime): Same.
	(gfc_conv_intrinsic_fdate): Same.
	(gfc_conv_intrinsic_ttynam): Same.
	(gfc_conv_intrinsic_minmax): Same.
	(gfc_conv_intrinsic_minmax_char): Same.
	(gfc_conv_intrinsic_anyall): Same.
	(gfc_conv_intrinsic_count): Same.
	(gfc_conv_intrinsic_arith): Same.
	(gfc_conv_intrinsic_minmaxloc): Same.
	(gfc_conv_intrinsic_minmaxval): Same.
	(gfc_conv_intrinsic_rrspacing): Same.
	(gfc_conv_intrinsic_array_transfer): Same.
	(gfc_conv_intrinsic_trim): Same.
	(gfc_conv_intrinsic_repeat): Same.

Index: java/java-gimplify.c
===================================================================
--- java/java-gimplify.c	(revision 141983)
+++ java/java-gimplify.c	(working copy)
@@ -182,7 +182,7 @@ java_gimplify_block (tree java_block)
 
   /* Don't bother with empty blocks.  */
   if (! body)
-    return build_empty_stmt ();
+    return build_empty_stmt (input_location);
 
   if (IS_EMPTY_STMT (body))
     return body;
Index: java/expr.c
===================================================================
--- java/expr.c	(revision 142042)
+++ java/expr.c	(working copy)
@@ -3798,7 +3798,7 @@ force_evaluation_order (tree node)
 tree
 build_java_empty_stmt (void)
 {
-  tree t = build_empty_stmt ();
+  tree t = build_empty_stmt (input_location);
   return t;
 }
 
Index: tree.c
===================================================================
--- tree.c	(revision 142042)
+++ tree.c	(working copy)
@@ -2324,6 +2324,7 @@ save_expr (tree expr)
     return t;
 
   t = build1 (SAVE_EXPR, TREE_TYPE (expr), t);
+  SET_EXPR_LOCATION (t, EXPR_LOCATION (expr));
 
   /* This expression might be placed ahead of a jump to ensure that the
      value was computed on both sides of the jump.  So make sure it isn't
@@ -7988,12 +7989,14 @@ initializer_zerop (const_tree init)
     }
 }
 
-/* Build an empty statement.  */
+/* Build an empty statement at location LOC.  */
 
 tree
-build_empty_stmt (void)
+build_empty_stmt (location_t loc)
 {
-  return build1 (NOP_EXPR, void_type_node, size_zero_node);
+  tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
+  SET_EXPR_LOCATION (t, loc);
+  return t;
 }
 
 
Index: tree.h
===================================================================
--- tree.h	(revision 142042)
+++ tree.h	(working copy)
@@ -1576,7 +1576,7 @@ struct tree_constructor GTY(())
 
 /* True if a tree is an expression or statement that can have a
    location.  */
-#define CAN_HAVE_LOCATION_P(NODE) (EXPR_P (NODE))
+#define CAN_HAVE_LOCATION_P(NODE) ((NODE) && EXPR_P (NODE))
 
 extern void protected_set_expr_location (tree, location_t);
 
@@ -3964,7 +3964,7 @@ extern tree build_decl_stat (location_t,
 extern tree build_fn_decl (const char *, tree);
 #define build_decl(l,c,t,q) build_decl_stat (l,c,t,q MEM_STAT_INFO)
 extern tree build_block (tree, tree, tree, tree);
-extern tree build_empty_stmt (void);
+extern tree build_empty_stmt (location_t);
 extern tree build_omp_clause (enum omp_clause_code);
 
 extern tree build_vl_exp_stat (enum tree_code, int MEM_STAT_DECL);
Index: builtins.c
===================================================================
--- builtins.c	(revision 142042)
+++ builtins.c	(working copy)
@@ -4926,6 +4926,8 @@ gimplify_va_arg_expr (tree *expr_p, gimp
   tree valist = TREE_OPERAND (*expr_p, 0);
   tree type = TREE_TYPE (*expr_p);
   tree t;
+  location_t loc = EXPR_HAS_LOCATION (*expr_p) ? EXPR_LOCATION (*expr_p) :
+    UNKNOWN_LOCATION;
 
   /* Verify that valist is of the proper type.  */
   have_va_type = TREE_TYPE (valist);
@@ -4935,7 +4937,7 @@ gimplify_va_arg_expr (tree *expr_p, gimp
 
   if (have_va_type == NULL_TREE)
     {
-      error ("first argument to %<va_arg%> not of type %<va_list%>");
+      error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
       return GS_ERROR;
     }
 
@@ -4950,19 +4952,20 @@ gimplify_va_arg_expr (tree *expr_p, gimp
       /* Unfortunately, this is merely undefined, rather than a constraint
 	 violation, so we cannot make this an error.  If this call is never
 	 executed, the program is still strictly conforming.  */
-      warned = warning (0, "%qT is promoted to %qT when passed through %<...%>",
-			type, promoted_type);
+      warned = warning_at (loc, 0,
+	  		   "%qT is promoted to %qT when passed through %<...%>",
+			   type, promoted_type);
       if (!gave_help && warned)
 	{
 	  gave_help = true;
-	  inform (input_location, "(so you should pass %qT not %qT to %<va_arg%>)",
-		   promoted_type, type);
+	  inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
+		  promoted_type, type);
 	}
 
       /* We can, however, treat "undefined" any way we please.
 	 Call abort to encourage the user to fix the program.  */
       if (warned)
-	inform (input_location, "if this code is reached, the program will abort");
+	inform (loc, "if this code is reached, the program will abort");
       t = build_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 0);
       gimplify_and_add (t, pre_p);
 
@@ -5988,6 +5991,7 @@ expand_builtin_sync_operation (enum mach
 {
   rtx val, mem;
   enum machine_mode old_mode;
+  location_t loc = EXPR_LOCATION (exp);
 
   if (code == NOT && warn_sync_nand)
     {
@@ -6008,8 +6012,7 @@ expand_builtin_sync_operation (enum mach
 	    break;
 
 	  fndecl = implicit_built_in_decls[BUILT_IN_FETCH_AND_NAND_N];
-	  inform (input_location,
-		  "%qD changed semantics in GCC 4.4", fndecl);
+	  inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
 	  warned_f_a_n = true;
 	  break;
 
@@ -6023,8 +6026,7 @@ expand_builtin_sync_operation (enum mach
 	    break;
 
 	  fndecl = implicit_built_in_decls[BUILT_IN_NAND_AND_FETCH_N];
-	  inform (input_location,
-		  "%qD changed semantics in GCC 4.4", fndecl);
+	  inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
 	  warned_n_a_f = true;
 	  break;
 
Index: objc/objc-act.c
===================================================================
--- objc/objc-act.c	(revision 142042)
+++ objc/objc-act.c	(working copy)
@@ -145,7 +145,7 @@ static void finish_objc (void);
 /* Code generation.  */
 
 static tree objc_build_constructor (tree, tree);
-static tree build_objc_method_call (int, tree, tree, tree, tree);
+static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
 static tree get_proto_encoding (tree);
 static tree lookup_interface (tree);
 static tree objc_add_static_instance (tree, tree);
@@ -1256,7 +1256,7 @@ objc_build_component_ref (tree datum, tr
   return finish_class_member_access_expr (datum, component, false,
                                           tf_warning_or_error);
 #else
-  return build_component_ref (datum, component);
+  return build_component_ref (input_location, datum, component);
 #endif
 }
 
@@ -2368,7 +2368,7 @@ build_module_initializer_routine (void)
 	     (NULL_TREE,
 	      build_unary_op (input_location, ADDR_EXPR,
 			      UOBJC_MODULES_decl, 0))));
-  add_stmt (c_end_compound_stmt (body, true));
+  add_stmt (c_end_compound_stmt (input_location, body, true));
 
   TREE_PUBLIC (current_function_decl) = 0;
 
@@ -2401,7 +2401,7 @@ objc_static_init_needed_p (void)
 tree
 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
 {
-  add_stmt (build_stmt (EXPR_STMT,
+  add_stmt (build_stmt (input_location, EXPR_STMT,
 			build_function_call (input_location,
 					     GNU_INIT_decl, NULL_TREE)));
 
@@ -2632,10 +2632,11 @@ get_proto_encoding (tree proto)
 }
 
 /* sel_ref_chain is a list whose "value" fields will be instances of
-   identifier_node that represent the selector.  */
+   identifier_node that represent the selector.  LOC is the location of
+   the @selector.  */
 
 static tree
-build_typed_selector_reference (tree ident, tree prototype)
+build_typed_selector_reference (location_t loc, tree ident, tree prototype)
 {
   tree *chain = &sel_ref_chain;
   tree expr;
@@ -2653,16 +2654,15 @@ build_typed_selector_reference (tree ide
   *chain = tree_cons (prototype, ident, NULL_TREE);
 
  return_at_index:
-  expr = build_unary_op (input_location, ADDR_EXPR,
-			 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
-					  build_int_cst (NULL_TREE, index),
-					  input_location),
+  expr = build_unary_op (loc, ADDR_EXPR,
+			 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
+					  build_int_cst (NULL_TREE, index)),
 			 1);
   return convert (objc_selector_type, expr);
 }
 
 static tree
-build_selector_reference (tree ident)
+build_selector_reference (location_t loc, tree ident)
 {
   tree *chain = &sel_ref_chain;
   tree expr;
@@ -2673,9 +2673,8 @@ build_selector_reference (tree ident)
       if (TREE_VALUE (*chain) == ident)
 	return (flag_next_runtime
 		? TREE_PURPOSE (*chain)
-		: build_array_ref (UOBJC_SELECTOR_TABLE_decl,
-				   build_int_cst (NULL_TREE, index),
-				   input_location));
+		: build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
+				   build_int_cst (NULL_TREE, index)));
 
       index++;
       chain = &TREE_CHAIN (*chain);
@@ -2687,9 +2686,8 @@ build_selector_reference (tree ident)
 
   return (flag_next_runtime
 	  ? expr
-	  : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
-			     build_int_cst (NULL_TREE, index),
-			     input_location));
+	  : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
+			     build_int_cst (NULL_TREE, index)));
 }
 
 static GTY(()) int class_reference_idx;
@@ -3075,11 +3073,11 @@ objc_substitute_decl (tree expr, tree ol
 				    newexpr),
 	      DECL_NAME (TREE_OPERAND (expr, 1)));
     case ARRAY_REF:
-      return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
+      return build_array_ref (input_location,
+			      objc_substitute_decl (TREE_OPERAND (expr, 0),
 						    oldexpr,
 						    newexpr),
-			      TREE_OPERAND (expr, 1),
-			      input_location);
+			      TREE_OPERAND (expr, 1));
     case INDIRECT_REF:
       return build_indirect_ref (input_location,
 				 objc_substitute_decl (TREE_OPERAND (expr, 0),
@@ -3740,7 +3738,7 @@ next_sjlj_build_try_catch_finally (void)
   if (cur_try_context->catch_list)
     {
       tree caught_decl = objc_build_exc_ptr ();
-      catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
+      catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
       TREE_SIDE_EFFECTS (catch_seq) = 1;
 
       t = next_sjlj_build_exc_extract (caught_decl);
@@ -3764,7 +3762,7 @@ next_sjlj_build_try_catch_finally (void)
 
   /* Build the complete FINALLY statement list.  */
   t = next_sjlj_build_try_exit ();
-  t = build_stmt (COND_EXPR,
+  t = build_stmt (input_location, COND_EXPR,
 		  c_common_truthvalue_conversion 
 		    (input_location, rethrow_decl),
 		  NULL, t);
@@ -3777,7 +3775,7 @@ next_sjlj_build_try_catch_finally (void)
   t = tree_cons (NULL, rethrow_decl, NULL);
   t = build_function_call (input_location,
 			   objc_exception_throw_decl, t);
-  t = build_stmt (COND_EXPR,
+  t = build_stmt (input_location, COND_EXPR,
 		  c_common_truthvalue_conversion (input_location, 
 						  rethrow_decl),
 		  t, NULL);
@@ -3863,7 +3861,7 @@ objc_begin_catch_clause (tree decl)
 
   /* Record the data for the catch in the try context so that we can
      finalize it later.  */
-  t = build_stmt (CATCH_EXPR, type, compound);
+  t = build_stmt (input_location, CATCH_EXPR, type, compound);
   cur_try_context->current_catch = t;
 
   /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime.  */
@@ -3883,7 +3881,7 @@ objc_finish_catch_clause (void)
   cur_try_context->current_catch = NULL;
   cur_try_context->end_catch_locus = input_location;
 
-  CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
+  CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
   append_to_statement_list (c, &cur_try_context->catch_list);
 }
 
@@ -3925,12 +3923,12 @@ objc_finish_try_stmt (void)
       stmt = c->try_body;
       if (c->catch_list)
 	{
-          stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
+          stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
 	  SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
 	}
       if (c->finally_body)
 	{
-	  stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
+	  stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
 	  SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
 	}
     }
@@ -3942,7 +3940,7 @@ objc_finish_try_stmt (void)
 }
 
 tree
-objc_build_throw_stmt (tree throw_expr)
+objc_build_throw_stmt (location_t loc, tree throw_expr)
 {
   tree args;
 
@@ -3955,7 +3953,7 @@ objc_build_throw_stmt (tree throw_expr)
       if (cur_try_context == NULL
           || cur_try_context->current_catch == NULL)
 	{
-	  error ("%<@throw%> (rethrow) used outside of a @catch block");
+	  error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
 	  return NULL_TREE;
 	}
 
@@ -3967,7 +3965,7 @@ objc_build_throw_stmt (tree throw_expr)
   /* A throw is just a call to the runtime throw function with the
      object as a parameter.  */
   args = tree_cons (NULL, throw_expr, NULL);
-  return add_stmt (build_function_call (input_location,
+  return add_stmt (build_function_call (loc,
 					objc_exception_throw_decl, args));
 }
 
@@ -5817,13 +5815,14 @@ generate_shared_structures (int cls_flag
   if (my_super_id)
     {
       super_expr = add_objc_string (my_super_id, class_names);
-      super_expr = build_c_cast (cast_type, super_expr); /* cast! */
+      super_expr = build_c_cast (input_location,
+				 cast_type, super_expr); /* cast! */
     }
   else
     super_expr = build_int_cst (NULL_TREE, 0);
 
   root_expr = add_objc_string (my_root_id, class_names);
-  root_expr = build_c_cast (cast_type, root_expr); /* cast! */
+  root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
 
   if (CLASS_PROTOCOL_LIST (implementation_template))
     {
@@ -6244,6 +6243,7 @@ tree
 objc_build_message_expr (tree mess)
 {
   tree receiver = TREE_PURPOSE (mess);
+  location_t loc;
   tree sel_name;
 #ifdef OBJCPLUS
   tree args = TREE_PURPOSE (TREE_VALUE (mess));
@@ -6255,6 +6255,11 @@ objc_build_message_expr (tree mess)
   if (TREE_CODE (receiver) == ERROR_MARK)
     return error_mark_node;
 
+  if (CAN_HAVE_LOCATION_P (receiver))
+    loc = EXPR_LOCATION (receiver);
+  else
+    loc = input_location;
+
   /* Obtain the full selector name.  */
   if (TREE_CODE (args) == IDENTIFIER_NODE)
     /* A unary selector.  */
@@ -6372,8 +6377,10 @@ objc_finish_message_expr (tree receiver,
 	{
 	  if (!CLASS_SUPER_NAME (implementation_template))
 	    {
-	      error ("no super class declared in @interface for %qs",
-		     IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
+	      error_at (input_location,
+			"no super class declared in @interface for %qs",
+			IDENTIFIER_POINTER (CLASS_NAME
+					    (implementation_template)));
 	      return error_mark_node;
 	    }
 	  rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
@@ -6410,9 +6417,10 @@ objc_finish_message_expr (tree receiver,
 		= lookup_method_in_protocol_list (rprotos, sel_name, 0);
 
 	      if (method_prototype)
-		warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
-			 IDENTIFIER_POINTER (sel_name),
-			 IDENTIFIER_POINTER (sel_name));
+		warning_at (input_location, 0,
+			    "found %<-%s%> instead of %<+%s%> in protocol(s)",
+			    IDENTIFIER_POINTER (sel_name),
+			    IDENTIFIER_POINTER (sel_name));
 	    }
 	}
     }
@@ -6469,8 +6477,8 @@ objc_finish_message_expr (tree receiver,
 	}
       else
 	{
-	  warning (0, "invalid receiver type %qs",
-		   gen_type_name (orig_rtype));
+	  warning_at (input_location, 0, "invalid receiver type %qs",
+		      gen_type_name (orig_rtype));
 	  /* After issuing the "invalid receiver" warning, perform method
 	     lookup as if we were messaging 'id'.  */
 	  rtype = rprotos = NULL_TREE;
@@ -6484,9 +6492,9 @@ objc_finish_message_expr (tree receiver,
   if (!method_prototype)
     {
       if (rprotos)
-	warning (0, "%<%c%s%> not found in protocol(s)",
-		 (class_tree ? '+' : '-'),
-		 IDENTIFIER_POINTER (sel_name));
+	warning_at (input_location, 0, "%<%c%s%> not found in protocol(s)",
+		    (class_tree ? '+' : '-'),
+		    IDENTIFIER_POINTER (sel_name));
 
       if (!rtype)
 	method_prototype
@@ -6498,23 +6506,26 @@ objc_finish_message_expr (tree receiver,
       static bool warn_missing_methods = false;
 
       if (rtype)
-	warning (0, "%qs may not respond to %<%c%s%>",
-		 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
-		 (class_tree ? '+' : '-'),
-		 IDENTIFIER_POINTER (sel_name));
+	warning_at (input_location, 0, "%qs may not respond to %<%c%s%>",
+		    IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
+		    (class_tree ? '+' : '-'),
+		    IDENTIFIER_POINTER (sel_name));
       /* If we are messaging an 'id' or 'Class' object and made it here,
 	 then we have failed to find _any_ instance or class method,
 	 respectively.  */
       else
-	warning (0, "no %<%c%s%> method found",
-		 (class_tree ? '+' : '-'),
-		 IDENTIFIER_POINTER (sel_name));
+	warning_at (input_location, 0, "no %<%c%s%> method found",
+		    (class_tree ? '+' : '-'),
+		    IDENTIFIER_POINTER (sel_name));
 
       if (!warn_missing_methods)
 	{
-	  warning (0, "(Messages without a matching method signature");
-	  warning (0, "will be assumed to return %<id%> and accept");
-	  warning (0, "%<...%> as arguments.)");
+	  warning_at (input_location, 
+		      0, "(Messages without a matching method signature");
+	  warning_at (input_location, 
+		      0, "will be assumed to return %<id%> and accept");
+	  warning_at (input_location, 
+		      0, "%<...%> as arguments.)");
 	  warn_missing_methods = true;
 	}
     }
@@ -6526,11 +6537,12 @@ objc_finish_message_expr (tree receiver,
      These are the object itself and the selector.  */
 
   if (flag_typed_selectors)
-    selector = build_typed_selector_reference (sel_name, method_prototype);
+    selector = build_typed_selector_reference (input_location,
+					       sel_name, method_prototype);
   else
-    selector = build_selector_reference (sel_name);
+    selector = build_selector_reference (input_location, sel_name);
 
-  retval = build_objc_method_call (super, method_prototype,
+  retval = build_objc_method_call (input_location, super, method_prototype,
 				   receiver,
 				   selector, method_params);
 
@@ -6543,11 +6555,12 @@ objc_finish_message_expr (tree receiver,
    looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
    assuming the method has prototype METHOD_PROTOTYPE.
    (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
+   LOC is the location of the expression to build.
    Use METHOD_PARAMS as list of args to pass to the method.
    If SUPER_FLAG is nonzero, we look up the superclass's method.  */
 
 static tree
-build_objc_method_call (int super_flag, tree method_prototype,
+build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
 			tree lookup_object, tree selector,
 			tree method_params)
 {
@@ -6574,7 +6587,7 @@ build_objc_method_call (int super_flag, 
 	(method_prototype, METHOD_REF, super_flag)));
   tree method, t;
 
-  lookup_object = build_c_cast (rcv_p, lookup_object);
+  lookup_object = build_c_cast (loc, rcv_p, lookup_object);
 
   /* Use SAVE_EXPR to avoid evaluating the receiver twice.  */
   lookup_object = save_expr (lookup_object);
@@ -6610,7 +6623,7 @@ build_objc_method_call (int super_flag, 
 
       t = tree_cons (NULL_TREE, selector, NULL_TREE);
       t = tree_cons (NULL_TREE, lookup_object, t);
-      method = build_function_call (input_location,
+      method = build_function_call (loc,
 				    sender, t);
 
       /* Pass the object to the method.  */
@@ -6622,7 +6635,7 @@ build_objc_method_call (int super_flag, 
   /* ??? Selector is not at this point something we can use inside
      the compiler itself.  Set it to garbage for the nonce.  */
   t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
-  return build_function_call (input_location,
+  return build_function_call (loc,
 			      t, method_params);
 }
 
@@ -6714,9 +6727,10 @@ objc_build_protocol_expr (tree protoname
 
 /* This function is called by the parser when a @selector() expression
    is found, in order to compile it.  It is only called by the parser
-   and only to compile a @selector().  */
+   and only to compile a @selector().  LOC is the location of the
+   @selector.  */
 tree
-objc_build_selector_expr (tree selnamelist)
+objc_build_selector_expr (location_t loc, tree selnamelist)
 {
   tree selname;
 
@@ -6750,15 +6764,16 @@ objc_build_selector_expr (tree selnameli
       /* If still not found, print out a warning.  */
       if (!hsh)
 	{
-	  warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
+	  warning_at (loc, 0,
+	      	      "undeclared selector %qs", IDENTIFIER_POINTER (selname));
 	}
     }
 
 
   if (flag_typed_selectors)
-    return build_typed_selector_reference (selname, 0);
+    return build_typed_selector_reference (loc, selname, 0);
   else
-    return build_selector_reference (selname);
+    return build_selector_reference (loc, selname);
 }
 
 tree
@@ -8829,7 +8844,8 @@ get_super_receiver (void)
 		super_class
 		  = build_indirect_ref
 		      (input_location,
-		       build_c_cast (build_pointer_type (objc_class_type),
+		       build_c_cast (input_location,
+				     build_pointer_type (objc_class_type),
 				     super_class), "unary *");
 	    }
 	  else
@@ -8851,15 +8867,18 @@ get_super_receiver (void)
 
 	  super_expr
 	    = build_modify_expr (input_location, super_expr, NOP_EXPR,
-				 build_c_cast (TREE_TYPE (super_expr),
+				 build_c_cast (input_location, 
+					       TREE_TYPE (super_expr),
 					       super_class));
 	}
 
-      super_expr_list = build_compound_expr (super_expr_list, super_expr);
+      super_expr_list = build_compound_expr (input_location, 
+					     super_expr_list, super_expr);
 
       super_expr = build_unary_op (input_location, 
 				   ADDR_EXPR, UOBJC_SUPER_decl, 0);
-      super_expr_list = build_compound_expr (super_expr_list, super_expr);
+      super_expr_list = build_compound_expr (input_location,
+					     super_expr_list, super_expr);
 
       return super_expr_list;
     }
Index: testsuite/gcc.dg/gomp/pr27415.c
===================================================================
--- testsuite/gcc.dg/gomp/pr27415.c	(revision 141983)
+++ testsuite/gcc.dg/gomp/pr27415.c	(working copy)
@@ -15,8 +15,8 @@ void
 test2 (void)
 {
   int i = 0;
-#pragma omp parallel for firstprivate (i)
-  for (i = 0; i < 10; i++)			/* { dg-error "should not be firstprivate" } */
+#pragma omp parallel for firstprivate (i)	/* { dg-error "should not be firstprivate" } */
+  for (i = 0; i < 10; i++)
     ;
 }
 
Index: testsuite/gcc.dg/label-decl-2.c
===================================================================
--- testsuite/gcc.dg/label-decl-2.c	(revision 141983)
+++ testsuite/gcc.dg/label-decl-2.c	(working copy)
@@ -8,9 +8,8 @@ typedef int b;
 void
 f (void)
 {
-  __label__ a, b, c, d;
+  __label__ a, b, c, d; /* { dg-warning "ISO C forbids label declarations" "label decls" { target *-*-* } 11 } */
   __extension__ (void)&&d; /* { dg-error "label 'd' used but not defined" } */
-  /* { dg-warning "ISO C forbids label declarations" "label decls" { target *-*-* } 11 } */
   goto c; /* { dg-error "label 'c' used but not defined" } */
  a: (void)0;
  b: (void)0;
Index: objcp/objcp-decl.h
===================================================================
--- objcp/objcp-decl.h	(revision 142042)
+++ objcp/objcp-decl.h	(working copy)
@@ -49,7 +49,7 @@ extern tree objcp_end_compound_stmt (tre
 	objcp_comptypes (type1, type2)
 #define c_begin_compound_stmt(flags) \
 	objcp_begin_compound_stmt (flags)
-#define c_end_compound_stmt(stmt, flags) \
+#define c_end_compound_stmt(loc, stmt, flags)	\
 	objcp_end_compound_stmt (stmt, flags)
 
 #undef OBJC_TYPE_NAME
Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 142042)
+++ cp/typeck.c	(working copy)
@@ -1327,7 +1327,7 @@ cxx_sizeof_or_alignof_type (tree type, e
       return value;
     }
 
-  return c_sizeof_or_alignof_type (complete_type (type),
+  return c_sizeof_or_alignof_type (input_location, complete_type (type),
 				   op == SIZEOF_EXPR,
 				   complain);
 }
@@ -2533,7 +2533,7 @@ cp_build_indirect_ref (tree ptr, const c
    LOC is the location to use in building the array reference.  */
 
 tree
-build_array_ref (tree array, tree idx, location_t loc)
+build_array_ref (location_t loc, tree array, tree idx)
 {
   tree ret;
 
@@ -2553,7 +2553,7 @@ build_array_ref (tree array, tree idx, l
     {
     case COMPOUND_EXPR:
       {
-	tree value = build_array_ref (TREE_OPERAND (array, 1), idx, loc);
+	tree value = build_array_ref (loc, TREE_OPERAND (array, 1), idx);
 	ret = build2 (COMPOUND_EXPR, TREE_TYPE (value),
 		      TREE_OPERAND (array, 0), value);
 	SET_EXPR_LOCATION (ret, loc);
@@ -2563,9 +2563,9 @@ build_array_ref (tree array, tree idx, l
     case COND_EXPR:
       ret = build_conditional_expr
 	      (TREE_OPERAND (array, 0),
-	      build_array_ref (TREE_OPERAND (array, 1), idx, loc),
-	      build_array_ref (TREE_OPERAND (array, 2), idx, loc),
-	      tf_warning_or_error);
+	       build_array_ref (loc, TREE_OPERAND (array, 1), idx),
+	       build_array_ref (loc, TREE_OPERAND (array, 2), idx),
+	       tf_warning_or_error);
       protected_set_expr_location (ret, loc);
       return ret;
 
@@ -4921,7 +4921,7 @@ build_x_compound_expr (tree op1, tree op
 /* Like cp_build_compound_expr, but for the c-common bits.  */
 
 tree
-build_compound_expr (tree lhs, tree rhs)
+build_compound_expr (location_t loc ATTRIBUTE_UNUSED, tree lhs, tree rhs)
 {
   return cp_build_compound_expr (lhs, rhs, tf_warning_or_error);
 }
@@ -5662,7 +5662,7 @@ build_const_cast (tree type, tree expr, 
 /* Like cp_build_c_cast, but for the c-common bits.  */
 
 tree
-build_c_cast (tree type, tree expr)
+build_c_cast (location_t loc ATTRIBUTE_UNUSED, tree type, tree expr)
 {
   return cp_build_c_cast (type, expr, tf_warning_or_error);
 }
@@ -6319,7 +6319,7 @@ build_ptrmemfunc (tree type, tree pfn, i
   /* Handle null pointer to member function conversions.  */
   if (integer_zerop (pfn))
     {
-      pfn = build_c_cast (type, integer_zero_node);
+      pfn = build_c_cast (input_location, type, integer_zero_node);
       return build_ptrmemfunc1 (to_type,
 				integer_zero_node,
 				pfn);
Index: cp/init.c
===================================================================
--- cp/init.c	(revision 142042)
+++ cp/init.c	(working copy)
@@ -1770,13 +1770,14 @@ avoid_placement_new_aliasing (tree t, tr
   if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
       && placement != NULL_TREE
       && TREE_CODE (TREE_TYPE (placement)) == POINTER_TYPE)
-    type_change = build_stmt (CHANGE_DYNAMIC_TYPE_EXPR,
+    type_change = build_stmt (input_location,
+			      CHANGE_DYNAMIC_TYPE_EXPR,
 			      TREE_TYPE (t),
 			      placement);
   else
     {
       /* Build a memory clobber.  */
-      type_change = build_stmt (ASM_EXPR,
+      type_change = build_stmt (input_location, ASM_EXPR,
 				build_string (0, ""),
 				NULL_TREE,
 				NULL_TREE,
@@ -2561,15 +2562,17 @@ build_vec_delete_1 (tree base, tree maxi
 			 fold_convert (ptype, base)));
   tmp = fold_build1 (NEGATE_EXPR, sizetype, size_exp);
   body = build_compound_expr
-    (body, cp_build_modify_expr (tbase, NOP_EXPR,
+    (input_location, 
+     body, cp_build_modify_expr (tbase, NOP_EXPR,
 				 build2 (POINTER_PLUS_EXPR, ptype, tbase, tmp),
 				 tf_warning_or_error));
   body = build_compound_expr
-    (body, build_delete (ptype, tbase, sfk_complete_destructor,
+    (input_location,
+     body, build_delete (ptype, tbase, sfk_complete_destructor,
 			 LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1));
 
   loop = build1 (LOOP_EXPR, void_type_node, body);
-  loop = build_compound_expr (tbase_init, loop);
+  loop = build_compound_expr (input_location, tbase_init, loop);
 
  no_destructor:
   /* If the delete flag is one, or anything else with the low bit set,
@@ -2616,7 +2619,7 @@ build_vec_delete_1 (tree base, tree maxi
   else if (!body)
     body = deallocate_expr;
   else
-    body = build_compound_expr (body, deallocate_expr);
+    body = build_compound_expr (input_location, body, deallocate_expr);
 
   if (!body)
     body = integer_zero_node;
Index: cp/class.c
===================================================================
--- cp/class.c	(revision 142042)
+++ cp/class.c	(working copy)
@@ -627,7 +627,7 @@ build_vtbl_ref_1 (tree instance, tree id
 
   assemble_external (vtbl);
 
-  aref = build_array_ref (vtbl, idx, input_location);
+  aref = build_array_ref (input_location, vtbl, idx);
   TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx);
 
   return aref;
Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 142042)
+++ cp/decl.c	(working copy)
@@ -745,7 +745,7 @@ poplevel (int keep, int reverse, int fun
 	 have pushed a statement list level.  Pop that, create a new
 	 BIND_EXPR for the block, and insert it into the stream.  */
       stmt = pop_stmt_list (current_binding_level->statement_list);
-      stmt = c_build_bind_expr (block, stmt);
+      stmt = c_build_bind_expr (input_location, block, stmt);
       add_stmt (stmt);
     }
 
@@ -2796,7 +2796,7 @@ finish_case_label (location_t loc, tree 
       /* For templates, just add the case label; we'll do semantic
 	 analysis at instantiation-time.  */
       label = build_decl (loc, LABEL_DECL, NULL_TREE, NULL_TREE);
-      return add_stmt (build_case_label (low_value, high_value, label));
+      return add_stmt (build_case_label (loc, low_value, high_value, label));
     }
 
   /* Find the condition on which this switch statement depends.  */
@@ -11917,13 +11917,13 @@ finish_constructor_body (void)
       && (! TYPE_FOR_JAVA (current_class_type)))
     {
       /* Any return from a constructor will end up here.  */
-      add_stmt (build_stmt (LABEL_EXPR, cdtor_label));
+      add_stmt (build_stmt (input_location, LABEL_EXPR, cdtor_label));
 
       val = DECL_ARGUMENTS (current_function_decl);
       val = build2 (MODIFY_EXPR, TREE_TYPE (val),
 		    DECL_RESULT (current_function_decl), val);
       /* Return the address of the object.  */
-      exprstmt = build_stmt (RETURN_EXPR, val);
+      exprstmt = build_stmt (input_location, RETURN_EXPR, val);
       add_stmt (exprstmt);
     }
 }
@@ -11965,7 +11965,7 @@ finish_destructor_body (void)
 
   /* Any return from a destructor will end up here; that way all base
      and member cleanups will be run when the function returns.  */
-  add_stmt (build_stmt (LABEL_EXPR, cdtor_label));
+  add_stmt (build_stmt (input_location, LABEL_EXPR, cdtor_label));
 
   /* In a virtual destructor, we must call delete.  */
   if (DECL_VIRTUAL_P (current_function_decl))
@@ -12003,7 +12003,7 @@ finish_destructor_body (void)
       val = build2 (MODIFY_EXPR, TREE_TYPE (val),
 		    DECL_RESULT (current_function_decl), val);
       /* Return the address of the object.  */
-      exprstmt = build_stmt (RETURN_EXPR, val);
+      exprstmt = build_stmt (input_location, RETURN_EXPR, val);
       add_stmt (exprstmt);
     }
 }
@@ -12586,7 +12586,7 @@ cxx_maybe_build_cleanup (tree decl)
       call = build_delete (TREE_TYPE (addr), addr,
 			   sfk_complete_destructor, flags, 0);
       if (cleanup)
-	cleanup = build_compound_expr (cleanup, call);
+	cleanup = build_compound_expr (input_location, cleanup, call);
       else
 	cleanup = call;
     }
Index: cp/call.c
===================================================================
--- cp/call.c	(revision 141983)
+++ cp/call.c	(working copy)
@@ -4214,7 +4214,7 @@ build_new_op (enum tree_code code, int f
       return cp_build_unary_op (code, arg1, candidates != 0, complain);
 
     case ARRAY_REF:
-      return build_array_ref (arg1, arg2, input_location);
+      return build_array_ref (input_location, arg1, arg2);
 
     case COND_EXPR:
       return build_conditional_expr (arg1, arg2, arg3, complain);
@@ -4887,7 +4887,7 @@ build_x_va_arg (tree expr, tree type)
       return expr;
     }
 
-  return build_va_arg (expr, type);
+  return build_va_arg (input_location, expr, type);
 }
 
 /* TYPE has been given to va_arg.  Apply the default conversions which
Index: cp/except.c
===================================================================
--- cp/except.c	(revision 141983)
+++ cp/except.c	(working copy)
@@ -520,7 +520,7 @@ expand_end_catch_block (void)
 tree
 begin_eh_spec_block (void)
 {
-  tree r = build_stmt (EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
+  tree r = build_stmt (input_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
   add_stmt (r);
   EH_SPEC_STMTS (r) = push_stmt_list ();
   return r;
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 142042)
+++ cp/cp-tree.h	(working copy)
@@ -4916,7 +4916,7 @@ extern tree build_x_indirect_ref		(tree,
                                                  tsubst_flags_t);
 extern tree cp_build_indirect_ref		(tree, const char *,
                                                  tsubst_flags_t);
-extern tree build_array_ref			(tree, tree, location_t);
+extern tree build_array_ref			(location_t, tree, tree);
 extern tree get_member_function_from_ptrfunc	(tree *, tree);
 extern tree cp_build_function_call              (tree, tree, tsubst_flags_t);
 extern tree build_x_binary_op			(enum tree_code, tree,
@@ -4932,12 +4932,12 @@ extern tree build_x_conditional_expr		(t
                                                  tsubst_flags_t);
 extern tree build_x_compound_expr_from_list	(tree, const char *);
 extern tree build_x_compound_expr		(tree, tree, tsubst_flags_t);
-extern tree build_compound_expr                 (tree, tree);
+extern tree build_compound_expr                 (location_t, tree, tree);
 extern tree cp_build_compound_expr		(tree, tree, tsubst_flags_t);
 extern tree build_static_cast			(tree, tree, tsubst_flags_t);
 extern tree build_reinterpret_cast		(tree, tree, tsubst_flags_t);
 extern tree build_const_cast			(tree, tree, tsubst_flags_t);
-extern tree build_c_cast			(tree, tree);
+extern tree build_c_cast			(location_t, tree, tree);
 extern tree cp_build_c_cast			(tree, tree, tsubst_flags_t);
 extern tree build_x_modify_expr			(tree, enum tree_code, tree,
 						 tsubst_flags_t);
Index: cp/cp-gimplify.c
===================================================================
--- cp/cp-gimplify.c	(revision 142042)
+++ cp/cp-gimplify.c	(working copy)
@@ -169,9 +169,9 @@ gimplify_if_stmt (tree *stmt_p)
   else_ = ELSE_CLAUSE (stmt);
 
   if (!then_)
-    then_ = build_empty_stmt ();
+    then_ = build_empty_stmt (locus);
   if (!else_)
-    else_ = build_empty_stmt ();
+    else_ = build_empty_stmt (locus);
 
   if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
     stmt = then_;
@@ -335,7 +335,7 @@ gimplify_switch_stmt (tree *stmt_p, gimp
 
   body = SWITCH_STMT_BODY (stmt);
   if (!body)
-    body = build_empty_stmt ();
+    body = build_empty_stmt (stmt_locus);
 
   t = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt),
 	      SWITCH_STMT_COND (stmt), body, NULL_TREE);
Index: cp/typeck2.c
===================================================================
--- cp/typeck2.c	(revision 141983)
+++ cp/typeck2.c	(working copy)
@@ -517,7 +517,7 @@ split_nonconstant_init_1 (tree dest, tre
 			      NULL_TREE);
 
 	      code = build2 (INIT_EXPR, inner_type, sub, value);
-	      code = build_stmt (EXPR_STMT, code);
+	      code = build_stmt (input_location, EXPR_STMT, code);
 	      add_stmt (code);
 	      continue;
 	    }
@@ -531,7 +531,7 @@ split_nonconstant_init_1 (tree dest, tre
 	  tree cons = copy_node (init);
 	  CONSTRUCTOR_ELTS (init) = NULL;
 	  code = build2 (MODIFY_EXPR, type, dest, cons);
-	  code = build_stmt (EXPR_STMT, code);
+	  code = build_stmt (input_location, EXPR_STMT, code);
 	  add_stmt (code);
 	}
       break;
Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 142042)
+++ cp/pt.c	(working copy)
@@ -9824,7 +9824,7 @@ tsubst_copy (tree t, tree args, tsubst_f
 	  r = non_reference (TREE_TYPE (t));
 	  r = tsubst (r, args, complain, in_decl);
 	  r = build_pointer_type (r);
-	  r = build_c_cast (r, null_node);
+	  r = build_c_cast (input_location, r, null_node);
 	  return cp_build_indirect_ref (r, NULL, tf_warning_or_error);
 	}
       
Index: cp/semantics.c
===================================================================
--- cp/semantics.c	(revision 142042)
+++ cp/semantics.c	(working copy)
@@ -421,7 +421,7 @@ maybe_cleanup_point_expr_void (tree expr
 void
 add_decl_expr (tree decl)
 {
-  tree r = build_stmt (DECL_EXPR, decl);
+  tree r = build_stmt (input_location, DECL_EXPR, decl);
   if (DECL_INITIAL (decl)
       || (DECL_SIZE (decl) && TREE_SIDE_EFFECTS (DECL_SIZE (decl))))
     r = maybe_cleanup_point_expr_void (r);
@@ -442,7 +442,7 @@ do_poplevel (tree stmt_list)
 
   if (!processing_template_decl)
     {
-      stmt_list = c_build_bind_expr (block, stmt_list);
+      stmt_list = c_build_bind_expr (input_location, block, stmt_list);
       /* ??? See c_end_compound_stmt re statement expressions.  */
     }
 
@@ -467,7 +467,7 @@ do_pushlevel (scope_kind sk)
 void
 push_cleanup (tree decl, tree cleanup, bool eh_only)
 {
-  tree stmt = build_stmt (CLEANUP_STMT, NULL, cleanup, decl);
+  tree stmt = build_stmt (input_location, CLEANUP_STMT, NULL, cleanup, decl);
   CLEANUP_EH_ONLY (stmt) = eh_only;
   add_stmt (stmt);
   CLEANUP_BODY (stmt) = push_stmt_list ();
@@ -557,7 +557,7 @@ finish_goto_stmt (tree destination)
 
   check_goto (destination);
 
-  return add_stmt (build_stmt (GOTO_EXPR, destination));
+  return add_stmt (build_stmt (input_location, GOTO_EXPR, destination));
 }
 
 /* COND is the condition-expression for an if, while, etc.,
@@ -620,7 +620,7 @@ finish_expr_stmt (tree expr)
       if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
 	{
 	  if (TREE_CODE (expr) != EXPR_STMT)
-	    expr = build_stmt (EXPR_STMT, expr);
+	    expr = build_stmt (input_location, EXPR_STMT, expr);
 	  expr = maybe_cleanup_point_expr_void (expr);
 	}
 
@@ -641,7 +641,7 @@ begin_if_stmt (void)
 {
   tree r, scope;
   scope = do_pushlevel (sk_block);
-  r = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
+  r = build_stmt (input_location, IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
   TREE_CHAIN (r) = scope;
   begin_cond (&IF_COND (r));
   return r;
@@ -703,7 +703,7 @@ tree
 begin_while_stmt (void)
 {
   tree r;
-  r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE);
+  r = build_stmt (input_location, WHILE_STMT, NULL_TREE, NULL_TREE);
   add_stmt (r);
   WHILE_BODY (r) = do_pushlevel (sk_block);
   begin_cond (&WHILE_COND (r));
@@ -735,7 +735,7 @@ finish_while_stmt (tree while_stmt)
 tree
 begin_do_stmt (void)
 {
-  tree r = build_stmt (DO_STMT, NULL_TREE, NULL_TREE);
+  tree r = build_stmt (input_location, DO_STMT, NULL_TREE, NULL_TREE);
   add_stmt (r);
   DO_BODY (r) = push_stmt_list ();
   return r;
@@ -797,7 +797,7 @@ finish_return_stmt (tree expr)
 	}
     }
 
-  r = build_stmt (RETURN_EXPR, expr);
+  r = build_stmt (input_location, RETURN_EXPR, expr);
   TREE_NO_WARNING (r) |= no_warning;
   r = maybe_cleanup_point_expr_void (r);
   r = add_stmt (r);
@@ -813,7 +813,7 @@ begin_for_stmt (void)
 {
   tree r;
 
-  r = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE,
+  r = build_stmt (input_location, FOR_STMT, NULL_TREE, NULL_TREE,
 		  NULL_TREE, NULL_TREE);
 
   if (flag_new_for_scope > 0)
@@ -904,7 +904,7 @@ finish_for_stmt (tree for_stmt)
 tree
 finish_break_stmt (void)
 {
-  return add_stmt (build_stmt (BREAK_STMT));
+  return add_stmt (build_stmt (input_location, BREAK_STMT));
 }
 
 /* Finish a continue-statement.  */
@@ -912,7 +912,7 @@ finish_break_stmt (void)
 tree
 finish_continue_stmt (void)
 {
-  return add_stmt (build_stmt (CONTINUE_STMT));
+  return add_stmt (build_stmt (input_location, CONTINUE_STMT));
 }
 
 /* Begin a switch-statement.  Returns a new SWITCH_STMT if
@@ -923,7 +923,7 @@ begin_switch_stmt (void)
 {
   tree r, scope;
 
-  r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
+  r = build_stmt (input_location, SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
 
   scope = do_pushlevel (sk_block);
   TREE_CHAIN (r) = scope;
@@ -1007,7 +1007,7 @@ finish_switch_stmt (tree switch_stmt)
 tree
 begin_try_block (void)
 {
-  tree r = build_stmt (TRY_BLOCK, NULL_TREE, NULL_TREE);
+  tree r = build_stmt (input_location, TRY_BLOCK, NULL_TREE, NULL_TREE);
   add_stmt (r);
   TRY_STMTS (r) = push_stmt_list ();
   return r;
@@ -1097,7 +1097,7 @@ begin_handler (void)
 {
   tree r;
 
-  r = build_stmt (HANDLER, NULL_TREE, NULL_TREE);
+  r = build_stmt (input_location, HANDLER, NULL_TREE, NULL_TREE);
   add_stmt (r);
 
   /* Create a binding level for the eh_info and the exception object
@@ -1317,7 +1317,7 @@ finish_asm_stmt (int volatile_p, tree st
 	}
     }
 
-  r = build_stmt (ASM_EXPR, string,
+  r = build_stmt (input_location, ASM_EXPR, string,
 		  output_operands, input_operands,
 		  clobbers);
   ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
@@ -1335,7 +1335,7 @@ finish_label_stmt (tree name)
   if (decl  == error_mark_node)
     return error_mark_node;
 
-  return add_stmt (build_stmt (LABEL_EXPR, decl));
+  return add_stmt (build_stmt (input_location, LABEL_EXPR, decl));
 }
 
 /* Finish a series of declarations for local labels.  G++ allows users
@@ -1688,7 +1688,7 @@ finish_stmt_expr_expr (tree expr, tree s
 
       if (processing_template_decl)
 	{
-	  expr = build_stmt (EXPR_STMT, expr);
+	  expr = build_stmt (input_location, EXPR_STMT, expr);
 	  expr = add_stmt (expr);
 	  /* Mark the last statement so that we can recognize it as such at
 	     template-instantiation time.  */
@@ -3282,7 +3282,7 @@ finalize_nrv_r (tree* tp, int* walk_subt
 	init = build2 (INIT_EXPR, void_type_node, dp->result,
 		       DECL_INITIAL (dp->var));
       else
-	init = build_empty_stmt ();
+	init = build_empty_stmt (*EXPR_LOCUS (*tp));
       DECL_INITIAL (dp->var) = NULL_TREE;
       SET_EXPR_LOCUS (init, EXPR_LOCUS (*tp));
       *tp = init;
@@ -4345,7 +4345,7 @@ finish_omp_atomic (enum tree_code code, 
     }
   if (!dependent_p)
     {
-      stmt = c_finish_omp_atomic (code, lhs, rhs);
+      stmt = c_finish_omp_atomic (input_location, code, lhs, rhs);
       if (stmt == error_mark_node)
 	return;
     }
Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 141983)
+++ cp/name-lookup.c	(working copy)
@@ -3478,7 +3478,7 @@ do_using_directive (tree name_space)
   gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
 
   if (building_stmt_tree ())
-    add_stmt (build_stmt (USING_STMT, name_space));
+    add_stmt (build_stmt (input_location, USING_STMT, name_space));
   name_space = ORIGINAL_NAMESPACE (name_space);
 
   if (!toplevel_bindings_p ())
Index: cp/decl2.c
===================================================================
--- cp/decl2.c	(revision 142042)
+++ cp/decl2.c	(working copy)
@@ -355,7 +355,7 @@ grok_array_decl (tree array_expr, tree i
       if (array_expr == error_mark_node || index_exp == error_mark_node)
 	error ("ambiguous conversion for array subscript");
 
-      expr = build_array_ref (array_expr, index_exp, input_location);
+      expr = build_array_ref (input_location, array_expr, index_exp);
     }
   if (processing_template_decl && expr != error_mark_node)
     return build_min_non_dep (ARRAY_REF, expr, orig_array_expr, orig_index_exp,
Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 142042)
+++ cp/parser.c	(working copy)
@@ -6071,7 +6071,7 @@ cp_parser_cast_expression (cp_parser *pa
 	    return error_mark_node;
 
 	  /* Perform the cast.  */
-	  expr = build_c_cast (type, expr);
+	  expr = build_c_cast (input_location, type, expr);
 	  return expr;
 	}
       else 
@@ -7222,7 +7222,7 @@ cp_parser_selection_statement (cp_parser
 	    if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
 	      {
 	        location_t loc = cp_lexer_peek_token (parser->lexer)->location;
-		add_stmt (build_empty_stmt ());
+		add_stmt (build_empty_stmt (loc));
 		cp_lexer_consume_token (parser->lexer);
 	        if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_ELSE))
 		  warning_at (loc, OPT_Wempty_body, "suggest braces around "
@@ -7245,10 +7245,12 @@ cp_parser_selection_statement (cp_parser
 		/* Parse the else-clause.  */
 	        if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
 	          {
-		    warning_at (cp_lexer_peek_token (parser->lexer)->location,
+		    location_t loc;
+		    loc = cp_lexer_peek_token (parser->lexer)->location;
+		    warning_at (loc,
 				OPT_Wempty_body, "suggest braces around "
 			        "empty body in an %<else%> statement");
-		    add_stmt (build_empty_stmt ());
+		    add_stmt (build_empty_stmt (loc));
 		    cp_lexer_consume_token (parser->lexer);
 		  }
 		else
@@ -7756,8 +7758,9 @@ cp_parser_implicitly_scoped_statement (c
   /* Mark if () ; with a special NOP_EXPR.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
     {
+      location_t loc = cp_lexer_peek_token (parser->lexer)->location;
       cp_lexer_consume_token (parser->lexer);
-      statement = add_stmt (build_empty_stmt ());
+      statement = add_stmt (build_empty_stmt (loc));
     }
   /* if a compound is opened, we simply parse the statement directly.  */
   else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
@@ -19199,6 +19202,7 @@ cp_parser_objc_selector_expression (cp_p
   tree sel_seq = NULL_TREE;
   bool maybe_unary_selector_p = true;
   cp_token *token;
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
 
   cp_lexer_consume_token (parser->lexer);  /* Eat '@selector'.  */
   cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
@@ -19250,7 +19254,7 @@ cp_parser_objc_selector_expression (cp_p
  finish_selector:
   cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
 
-  return objc_build_selector_expr (sel_seq);
+  return objc_build_selector_expr (loc, sel_seq);
 }
 
 /* Parse a list of identifiers.
@@ -20023,6 +20027,7 @@ cp_parser_objc_synchronized_statement (c
 static tree
 cp_parser_objc_throw_statement (cp_parser *parser) {
   tree expr = NULL_TREE;
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
 
   cp_parser_require_keyword (parser, RID_AT_THROW, "%<@throw%>");
 
@@ -20031,7 +20036,7 @@ cp_parser_objc_throw_statement (cp_parse
 
   cp_parser_consume_semicolon_at_end_of_statement (parser);
 
-  return objc_build_throw_stmt (expr);
+  return objc_build_throw_stmt (loc, expr);
 }
 
 /* Parse an Objective-C statement.  */
@@ -20877,7 +20882,7 @@ cp_parser_omp_critical (cp_parser *parse
   cp_parser_require_pragma_eol (parser, pragma_tok);
 
   stmt = cp_parser_omp_structured_block (parser);
-  return c_finish_omp_critical (stmt, name);
+  return c_finish_omp_critical (input_location, stmt, name);
 }
 
 /* OpenMP 2.5:
@@ -21456,7 +21461,8 @@ static tree
 cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok)
 {
   cp_parser_require_pragma_eol (parser, pragma_tok);
-  return c_finish_omp_master (cp_parser_omp_structured_block (parser));
+  return c_finish_omp_master (input_location,
+			      cp_parser_omp_structured_block (parser));
 }
 
 /* OpenMP 2.5:
@@ -21466,8 +21472,9 @@ cp_parser_omp_master (cp_parser *parser,
 static tree
 cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok)
 {
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   cp_parser_require_pragma_eol (parser, pragma_tok);
-  return c_finish_omp_ordered (cp_parser_omp_structured_block (parser));
+  return c_finish_omp_ordered (loc, cp_parser_omp_structured_block (parser));
 }
 
 /* OpenMP 2.5:
Index: c-tree.h
===================================================================
--- c-tree.h	(revision 142042)
+++ c-tree.h	(working copy)
@@ -463,10 +463,10 @@ extern int quals_from_declspecs (const s
 extern struct c_declarator *build_array_declarator (tree, struct c_declspecs *,
 						    bool, bool);
 extern tree build_enumerator (location_t, struct c_enum_contents *, tree, tree);
-extern tree check_for_loop_decls (void);
+extern tree check_for_loop_decls (location_t);
 extern void mark_forward_parm_decls (void);
 extern void declare_parm_level (void);
-extern void undeclared_variable (tree, location_t);
+extern void undeclared_variable (location_t, tree);
 extern tree declare_label (tree);
 extern tree define_label (location_t, tree);
 extern void c_maybe_initialize_eh (void);
@@ -549,21 +549,21 @@ extern void c_incomplete_type_error (con
 extern tree c_type_promotes_to (tree);
 extern struct c_expr default_function_array_conversion (struct c_expr);
 extern tree composite_type (tree, tree);
-extern tree build_component_ref (tree, tree);
-extern tree build_array_ref (tree, tree, location_t);
-extern tree build_external_ref (tree, int, location_t);
+extern tree build_component_ref (location_t, tree, tree);
+extern tree build_array_ref (location_t, tree, tree);
+extern tree build_external_ref (location_t, tree, int);
 extern void pop_maybe_used (bool);
-extern struct c_expr c_expr_sizeof_expr (struct c_expr);
-extern struct c_expr c_expr_sizeof_type (struct c_type_name *);
-extern struct c_expr parser_build_unary_op (enum tree_code, struct c_expr,
-    					    location_t);
+extern struct c_expr c_expr_sizeof_expr (location_t, struct c_expr);
+extern struct c_expr c_expr_sizeof_type (location_t, struct c_type_name *);
+extern struct c_expr parser_build_unary_op (location_t, enum tree_code,
+    					    struct c_expr);
 extern struct c_expr parser_build_binary_op (location_t, 
     					     enum tree_code, struct c_expr,
 					     struct c_expr);
-extern tree build_conditional_expr (tree, tree, tree);
-extern tree build_compound_expr (tree, tree);
-extern tree c_cast_expr (struct c_type_name *, tree);
-extern tree build_c_cast (tree, tree);
+extern tree build_conditional_expr (location_t, tree, tree, tree);
+extern tree build_compound_expr (location_t, tree, tree);
+extern tree c_cast_expr (location_t, struct c_type_name *, tree);
+extern tree build_c_cast (location_t, tree, tree);
 extern void store_init_value (tree, tree);
 extern void error_init (const char *);
 extern void pedwarn_init (location_t, int opt, const char *);
@@ -579,18 +579,18 @@ extern void process_init_element (struct
 extern tree build_compound_literal (location_t, tree, tree);
 extern tree c_start_case (tree);
 extern void c_finish_case (tree);
-extern tree build_asm_expr (tree, tree, tree, tree, bool);
+extern tree build_asm_expr (location_t, tree, tree, tree, tree, bool);
 extern tree build_asm_stmt (tree, tree);
 extern int c_types_compatible_p (tree, tree);
 extern tree c_begin_compound_stmt (bool);
-extern tree c_end_compound_stmt (tree, bool);
+extern tree c_end_compound_stmt (location_t, tree, bool);
 extern void c_finish_if_stmt (location_t, tree, tree, tree, bool);
 extern void c_finish_loop (location_t, tree, tree, tree, tree, tree, bool);
 extern tree c_begin_stmt_expr (void);
-extern tree c_finish_stmt_expr (tree);
+extern tree c_finish_stmt_expr (location_t, tree);
 extern tree c_process_expr_stmt (tree);
 extern tree c_finish_expr_stmt (tree);
-extern tree c_finish_return (tree);
+extern tree c_finish_return (location_t, tree);
 extern tree c_finish_bc_stmt (location_t, tree *, bool);
 extern tree c_finish_goto_label (tree);
 extern tree c_finish_goto_ptr (tree);
@@ -598,9 +598,9 @@ extern void c_begin_vm_scope (unsigned i
 extern void c_end_vm_scope (unsigned int);
 extern tree c_expr_to_decl (tree, bool *, bool *);
 extern tree c_begin_omp_parallel (void);
-extern tree c_finish_omp_parallel (tree, tree);
+extern tree c_finish_omp_parallel (location_t, tree, tree);
 extern tree c_begin_omp_task (void);
-extern tree c_finish_omp_task (tree, tree);
+extern tree c_finish_omp_task (location_t, tree, tree);
 extern tree c_finish_omp_clauses (tree);
 
 /* Set to 0 at beginning of a function definition, set to 1 if
Index: c-semantics.c
===================================================================
--- c-semantics.c	(revision 141983)
+++ c-semantics.c	(working copy)
@@ -103,12 +103,12 @@ pop_stmt_list (tree t)
 
 /* Build a generic statement based on the given type of node and
    arguments. Similar to `build_nt', except that we set
-   EXPR_LOCATION to be the current source location.  */
+   EXPR_LOCATION to LOC. */
 /* ??? This should be obsolete with the lineno_stmt productions
    in the grammar.  */
 
 tree
-build_stmt (enum tree_code code, ...)
+build_stmt (location_t loc, enum tree_code code, ...)
 {
   tree ret;
   int length, i;
@@ -123,7 +123,7 @@ build_stmt (enum tree_code code, ...)
   ret = make_node (code);
   TREE_TYPE (ret) = void_type_node;
   length = TREE_CODE_LENGTH (code);
-  SET_EXPR_LOCATION (ret, input_location);
+  SET_EXPR_LOCATION (ret, loc);
 
   /* TREE_SIDE_EFFECTS will already be set for statements with
      implicit side effects.  Here we make sure it is set for other
@@ -165,7 +165,8 @@ emit_local_var (tree decl)
 /* Create a CASE_LABEL_EXPR tree node and return it.  */
 
 tree
-build_case_label (tree low_value, tree high_value, tree label_decl)
+build_case_label (location_t loc,
+		  tree low_value, tree high_value, tree label_decl)
 {
-  return build_stmt (CASE_LABEL_EXPR, low_value, high_value, label_decl);
+  return build_stmt (loc, CASE_LABEL_EXPR, low_value, high_value, label_decl);
 }
Index: c-decl.c
===================================================================
--- c-decl.c	(revision 142042)
+++ c-decl.c	(working copy)
@@ -546,7 +546,8 @@ c_finish_incomplete_decl (tree decl)
 	  && !DECL_EXTERNAL (decl)
 	  && TYPE_DOMAIN (type) == 0)
 	{
-	  warning (0, "array %q+D assumed to have one element", decl);
+	  warning_at (DECL_SOURCE_LOCATION (decl),
+		      0, "array %q+D assumed to have one element", decl);
 
 	  complete_array_type (&TREE_TYPE (decl), NULL_TREE, true);
 
@@ -2445,7 +2446,7 @@ implicitly_declare (location_t loc, tree
    in an appropriate scope, which will suppress further errors for the
    same identifier.  The error message should be given location LOC.  */
 void
-undeclared_variable (tree id, location_t loc)
+undeclared_variable (location_t loc, tree id)
 {
   static bool already = false;
   struct c_scope *scope;
@@ -2477,7 +2478,7 @@ undeclared_variable (tree id, location_t
    LABEL_DECL with all the proper frills.  */
 
 static tree
-make_label (tree name, location_t location)
+make_label (location_t location, tree name)
 {
   tree label = build_decl (location, LABEL_DECL, name, void_type_node);
 
@@ -2519,7 +2520,7 @@ lookup_label (tree name)
     }
 
   /* No label binding for that identifier; make one.  */
-  label = make_label (name, input_location);
+  label = make_label (input_location, name);
 
   /* Ordinary labels go in the current function scope.  */
   bind (name, label, current_function_scope,
@@ -2548,7 +2549,7 @@ declare_label (tree name)
       return b->decl;
     }
 
-  label = make_label (name, input_location);
+  label = make_label (input_location, name);
   C_DECLARED_LABEL_FLAG (label) = 1;
 
   /* Declared labels go in the current scope.  */
@@ -2596,7 +2597,7 @@ define_label (location_t location, tree 
   else
     {
       /* No label binding for that identifier; make one.  */
-      label = make_label (name, location);
+      label = make_label (location, name);
 
       /* Ordinary labels go in the current function scope.  */
       bind (name, label, current_function_scope,
@@ -3596,7 +3597,8 @@ finish_decl (tree decl, tree init, tree 
 		  add_stmt (bind);
 		  BIND_EXPR_BODY (bind) = push_stmt_list ();
 		}
-	      add_stmt (build_stmt (DECL_EXPR, decl));
+	      add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl),
+				    DECL_EXPR, decl));
 	    }
 	}
 
@@ -3621,7 +3623,7 @@ finish_decl (tree decl, tree init, tree 
     {
       if (!DECL_FILE_SCOPE_P (decl)
 	  && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
-	add_stmt (build_stmt (DECL_EXPR, decl));
+	add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
 
       rest_of_decl_compilation (decl, DECL_FILE_SCOPE_P (decl), 0);
     }
@@ -3753,7 +3755,7 @@ build_compound_literal (location_t loc, 
   if (type == error_mark_node || !COMPLETE_TYPE_P (type))
     return error_mark_node;
 
-  stmt = build_stmt (DECL_EXPR, decl);
+  stmt = build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl);
   complit = build1 (COMPOUND_LITERAL_EXPR, type, stmt);
   TREE_SIDE_EFFECTS (complit) = 1;
 
@@ -5784,7 +5786,8 @@ finish_struct (location_t loc, tree t, t
      parsing parameters, then arrange for the size of a variable sized type
      to be bound now.  */
   if (cur_stmt_list && variably_modified_type_p (t, NULL_TREE))
-    add_stmt (build_stmt (DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t)));
+    add_stmt (build_stmt (loc,
+			  DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t)));
 
   return t;
 }
@@ -6780,14 +6783,13 @@ finish_function (void)
       && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
       == integer_type_node && flag_isoc99)
     {
-      tree stmt = c_finish_return (integer_zero_node);
       /* Hack.  We don't want the middle-end to warn that this return
 	 is unreachable, so we mark its location as special.  Using
 	 UNKNOWN_LOCATION has the problem that it gets clobbered in
 	 annotate_one_with_locus.  A cleaner solution might be to
 	 ensure ! should_carry_locus_p (stmt), but that needs a flag.
       */
-      SET_EXPR_LOCATION (stmt, BUILTINS_LOCATION);
+      c_finish_return (BUILTINS_LOCATION, integer_zero_node);
     }
 
   /* Tie off the statement tree for this function.  */
@@ -6868,10 +6870,11 @@ finish_function (void)
 }
 
 /* Check the declarations given in a for-loop for satisfying the C99
-   constraints.  If exactly one such decl is found, return it.  */
+   constraints.  If exactly one such decl is found, return it.  LOC is
+   the location of the opening parenthesis of the for loop.  */
 
 tree
-check_for_loop_decls (void)
+check_for_loop_decls (location_t loc)
 {
   struct c_binding *b;
   tree one_decl = NULL_TREE;
@@ -6883,10 +6886,11 @@ check_for_loop_decls (void)
       /* If we get here, declarations have been used in a for loop without
 	 the C99 for loop scope.  This doesn't make much sense, so don't
 	 allow it.  */
-      error ("%<for%> loop initial declarations are only allowed in C99 mode");
+      error_at (loc, "%<for%> loop initial declarations "
+		"are only allowed in C99 mode");
       if (hint)
 	{
-	  inform (input_location, 
+	  inform (loc,
 		  "use option -std=c99 or -std=gnu99 to compile your code");
 	  hint = false;
 	}
@@ -6917,29 +6921,36 @@ check_for_loop_decls (void)
       switch (TREE_CODE (decl))
 	{
 	case VAR_DECL:
-	  if (TREE_STATIC (decl))
-	    error ("declaration of static variable %q+D in %<for%> loop "
-		   "initial declaration", decl);
-	  else if (DECL_EXTERNAL (decl))
-	    error ("declaration of %<extern%> variable %q+D in %<for%> loop "
-		   "initial declaration", decl);
+	  {
+	    location_t decl_loc = DECL_SOURCE_LOCATION (decl);
+	    if (TREE_STATIC (decl))
+	      error_at (decl_loc,
+			"declaration of static variable %qD in %<for%> loop "
+			"initial declaration", decl);
+	    else if (DECL_EXTERNAL (decl))
+	      error_at (decl_loc,
+			"declaration of %<extern%> variable %qD in %<for%> loop "
+			"initial declaration", decl);
+	  }
 	  break;
 
 	case RECORD_TYPE:
-	  error ("%<struct %E%> declared in %<for%> loop initial declaration",
-		 id);
+	  error_at (loc,
+		    "%<struct %E%> declared in %<for%> loop initial "
+		    "declaration", id);
 	  break;
 	case UNION_TYPE:
-	  error ("%<union %E%> declared in %<for%> loop initial declaration",
-		 id);
+	  error_at (loc,
+		    "%<union %E%> declared in %<for%> loop initial declaration",
+		    id);
 	  break;
 	case ENUMERAL_TYPE:
-	  error ("%<enum %E%> declared in %<for%> loop initial declaration",
-		 id);
+	  error_at (loc, "%<enum %E%> declared in %<for%> loop "
+		    "initial declaration", id);
 	  break;
 	default:
-	  error ("declaration of non-variable %q+D in %<for%> loop "
-		 "initial declaration", decl);
+	  error_at (loc, "declaration of non-variable "
+		    "%qD in %<for%> loop initial declaration", decl);
 	}
 
       n_decls++;
Index: fortran/trans-array.c
===================================================================
--- fortran/trans-array.c	(revision 141983)
+++ fortran/trans-array.c	(working copy)
@@ -579,7 +579,8 @@ gfc_trans_allocate_array_storage (stmtbl
 	      was_packed = fold_build2 (EQ_EXPR, boolean_type_node,
 					packed, source_data);
 	      tmp = gfc_finish_block (&do_copying);
-	      tmp = build3_v (COND_EXPR, was_packed, tmp, build_empty_stmt ());
+	      tmp = build3_v (COND_EXPR, was_packed, tmp,
+			      build_empty_stmt (input_location));
 	      gfc_add_expr_to_block (pre, tmp);
 
 	      tmp = fold_convert (pvoid_type_node, packed);
@@ -1391,7 +1392,8 @@ gfc_trans_array_constructor_value (stmtb
 					   loopvar, end));
 	  tmp = build1_v (GOTO_EXPR, exit_label);
 	  TREE_USED (exit_label) = 1;
-	  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+	  tmp = build3_v (COND_EXPR, cond, tmp,
+			  build_empty_stmt (input_location));
 	  gfc_add_expr_to_block (&body, tmp);
 
 	  /* The main loop body.  */
@@ -2689,7 +2691,7 @@ gfc_trans_scalarized_loop_end (gfc_loopi
 		      loop->loopvar[n], loop->to[n]);
   tmp = build1_v (GOTO_EXPR, exit_label);
   TREE_USED (exit_label) = 1;
-  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&block, tmp);
 
   /* The main body.  */
@@ -3204,7 +3206,7 @@ gfc_conv_ss_startstride (gfc_loopinfo * 
 	      || ss->expr->symtree->n.sym->attr.not_always_present)
 	    tmp = build3_v (COND_EXPR,
 			    gfc_conv_expr_present (ss->expr->symtree->n.sym),
-			    tmp, build_empty_stmt ());
+			    tmp, build_empty_stmt (input_location));
 
 	  gfc_add_expr_to_block (&block, tmp);
 
@@ -4248,7 +4250,7 @@ gfc_trans_g77_array (gfc_symbol * sym, t
   if (sym->attr.optional || sym->attr.not_always_present)
     {
       tmp = gfc_conv_expr_present (sym);
-      stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+      stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
     }
   
   gfc_add_expr_to_block (&block, stmt);
@@ -4531,7 +4533,7 @@ gfc_trans_dummy_array_bias (gfc_symbol *
   if (optional_arg)
     {
       tmp = gfc_conv_expr_present (sym);
-      stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+      stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
     }
   gfc_add_expr_to_block (&block, stmt);
 
@@ -4560,12 +4562,13 @@ gfc_trans_dummy_array_bias (gfc_symbol *
       tmp = build_fold_indirect_ref (dumdesc);
       tmp = gfc_conv_descriptor_data_get (tmp);
       tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
-      stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+      stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
 
       if (optional_arg)
         {
           tmp = gfc_conv_expr_present (sym);
-          stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+          stmt = build3_v (COND_EXPR, tmp, stmt,
+			   build_empty_stmt (input_location));
         }
       gfc_add_expr_to_block (&block, stmt);
     }
@@ -5364,7 +5367,7 @@ gfc_conv_array_parameter (gfc_se * se, g
 	tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
 			   gfc_conv_expr_present (sym), tmp);
 
-      tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+      tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
 
       gfc_add_expr_to_block (&block, tmp);
       gfc_add_block_to_block (&block, &se->post);
@@ -5566,7 +5569,8 @@ structure_alloc_comps (gfc_symbol * der_
 
       tmp = gfc_finish_block (&fnblock);
       if (null_cond != NULL_TREE)
-	tmp = build3_v (COND_EXPR, null_cond, tmp, build_empty_stmt ());
+	tmp = build3_v (COND_EXPR, null_cond, tmp,
+			build_empty_stmt (input_location));
 
       return tmp;
     }
Index: fortran/trans-expr.c
===================================================================
--- fortran/trans-expr.c	(revision 142042)
+++ fortran/trans-expr.c	(working copy)
@@ -2772,7 +2772,7 @@ gfc_conv_function_call (gfc_se * se, gfc
           tmp = gfc_deallocate_alloc_comp (e->ts.derived, tmp, parm_rank);
 	  if (e->expr_type == EXPR_VARIABLE && e->symtree->n.sym->attr.optional)
 	    tmp = build3_v (COND_EXPR, gfc_conv_expr_present (e->symtree->n.sym),
-			    tmp, build_empty_stmt ());
+			    tmp, build_empty_stmt (input_location));
 
 	  if (e->expr_type != EXPR_VARIABLE)
 	    /* Don't deallocate non-variables until they have been used.  */
@@ -3065,7 +3065,8 @@ fill_with_spaces (tree start, tree type,
   cond = fold_build2 (LE_EXPR, boolean_type_node, i,
 		      fold_convert (sizetype, integer_zero_node));
   tmp = build1_v (GOTO_EXPR, exit_label);
-  tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, build_empty_stmt ());
+  tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
+		     build_empty_stmt (input_location));
   gfc_add_expr_to_block (&loop, tmp);
 
   /* Assignment.  */
@@ -3218,7 +3219,8 @@ gfc_trans_string_copy (stmtblock_t * blo
 
   /* The whole copy_string function is there.  */
   tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
-  tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, build_empty_stmt ());
+  tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
+		     build_empty_stmt (input_location));
   gfc_add_expr_to_block (block, tmp);
 }
 
@@ -4190,7 +4192,8 @@ gfc_trans_scalar_assign (gfc_se * lse, g
 	  tmp = gfc_evaluate_now (lse->expr, &lse->pre);
 	  tmp = gfc_deallocate_alloc_comp (ts.derived, tmp, 0);
 	  if (r_is_var)
-	    tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
+	    tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
+			    tmp);
 	  gfc_add_expr_to_block (&lse->post, tmp);
 	}
 
@@ -4205,7 +4208,8 @@ gfc_trans_scalar_assign (gfc_se * lse, g
       if (r_is_var)
 	{
 	  tmp = gfc_copy_alloc_comp (ts.derived, rse->expr, lse->expr, 0);
-	  tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
+	  tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
+			  tmp);
 	  gfc_add_expr_to_block (&block, tmp);
 	}
     }
Index: fortran/trans-stmt.c
===================================================================
--- fortran/trans-stmt.c	(revision 141983)
+++ fortran/trans-stmt.c	(working copy)
@@ -175,7 +175,7 @@ gfc_trans_goto (gfc_code * code)
       tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, assigned_goto);
       tmp = build3_v (COND_EXPR, tmp,
 		      fold_build1 (GOTO_EXPR, void_type_node, target),
-		      build_empty_stmt ());
+		      build_empty_stmt (input_location));
       gfc_add_expr_to_block (&se.pre, tmp);
       code = code->block;
     }
@@ -618,7 +618,7 @@ gfc_trans_if_1 (gfc_code * code)
   if (code->block)
     elsestmt = gfc_trans_if_1 (code->block);
   else
-    elsestmt = build_empty_stmt ();
+    elsestmt = build_empty_stmt (input_location);
 
   /* Build the condition expression and add it to the condition block.  */
   stmt = fold_build3 (COND_EXPR, void_type_node, if_se.expr, stmt, elsestmt);
@@ -793,7 +793,7 @@ gfc_trans_simple_do (gfc_code * code, st
   tmp = build1_v (GOTO_EXPR, exit_label);
   TREE_USED (exit_label) = 1;
   tmp = fold_build3 (COND_EXPR, void_type_node,
-		     cond, tmp, build_empty_stmt ());
+		     cond, tmp, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&body, tmp);
 
   /* Finish the loop body.  */
@@ -806,7 +806,7 @@ gfc_trans_simple_do (gfc_code * code, st
   else
     cond = fold_build2 (GE_EXPR, boolean_type_node, dovar, to);
   tmp = fold_build3 (COND_EXPR, void_type_node,
-		     cond, tmp, build_empty_stmt ());
+		     cond, tmp, build_empty_stmt (input_location));
   gfc_add_expr_to_block (pblock, tmp);
 
   /* Add the exit label.  */
@@ -935,7 +935,7 @@ gfc_trans_do (gfc_code * code)
       tmp = fold_build2 (LT_EXPR, boolean_type_node, to, from);
       pos = fold_build3 (COND_EXPR, void_type_node, tmp,
 			 build1_v (GOTO_EXPR, exit_label),
-			 build_empty_stmt ());
+			 build_empty_stmt (input_location));
       tmp = fold_build2 (MINUS_EXPR, type, to, from);
       tmp = fold_convert (utype, tmp);
       tmp = fold_build2 (TRUNC_DIV_EXPR, utype, tmp,
@@ -946,7 +946,7 @@ gfc_trans_do (gfc_code * code)
       tmp = fold_build2 (GT_EXPR, boolean_type_node, to, from);
       neg = fold_build3 (COND_EXPR, void_type_node, tmp,
 			 build1_v (GOTO_EXPR, exit_label),
-			 build_empty_stmt ());
+			 build_empty_stmt (input_location));
       tmp = fold_build2 (MINUS_EXPR, type, from, to);
       tmp = fold_convert (utype, tmp);
       tmp = fold_build2 (TRUNC_DIV_EXPR, utype, tmp,
@@ -977,7 +977,7 @@ gfc_trans_do (gfc_code * code)
       /* If the loop is empty, go directly to the exit label.  */
       tmp = fold_build3 (COND_EXPR, void_type_node, tmp,
 			 build1_v (GOTO_EXPR, exit_label),
-			 build_empty_stmt ());
+			 build_empty_stmt (input_location));
       gfc_add_expr_to_block (&block, tmp);
     }
 
@@ -1011,7 +1011,7 @@ gfc_trans_do (gfc_code * code)
 		      build_int_cst (utype, 0));
   tmp = build1_v (GOTO_EXPR, exit_label);
   tmp = fold_build3 (COND_EXPR, void_type_node,
-		     cond, tmp, build_empty_stmt ());
+		     cond, tmp, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&body, tmp);
 
   /* Decrement the loop count.  */
@@ -1085,7 +1085,7 @@ gfc_trans_do_while (gfc_code * code)
   tmp = build1_v (GOTO_EXPR, exit_label);
   TREE_USED (exit_label) = 1;
   tmp = fold_build3 (COND_EXPR, void_type_node,
-		     cond.expr, tmp, build_empty_stmt ());
+		     cond.expr, tmp, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&block, tmp);
 
   /* The main body of the loop.  */
@@ -1330,8 +1330,8 @@ gfc_trans_logical_select (gfc_code * cod
     {
       tree true_tree, false_tree, stmt;
 
-      true_tree = build_empty_stmt ();
-      false_tree = build_empty_stmt ();
+      true_tree = build_empty_stmt (input_location);
+      false_tree = build_empty_stmt (input_location);
 
       /* If we have a case for .TRUE. and for .FALSE., discard the default case.
           Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
@@ -1570,7 +1570,7 @@ gfc_trans_select (gfc_code * code)
 
   /* Empty SELECT constructs are legal.  */
   if (code->block == NULL)
-    return build_empty_stmt ();
+    return build_empty_stmt (input_location);
 
   /* Select the correct translation function.  */
   switch (code->expr->ts.type)
@@ -1845,7 +1845,7 @@ gfc_trans_forall_loop (forall_info *fora
 			  count, build_int_cst (TREE_TYPE (count), 0));
       tmp = build1_v (GOTO_EXPR, exit_label);
       tmp = fold_build3 (COND_EXPR, void_type_node,
-			 cond, tmp, build_empty_stmt ());
+			 cond, tmp, build_empty_stmt (input_location));
       gfc_add_expr_to_block (&block, tmp);
 
       /* The main loop body.  */
@@ -1927,7 +1927,8 @@ gfc_trans_nested_forall_loop (forall_inf
           if (mask)
             {
               tmp = gfc_build_array_ref (mask, maskindex, NULL);
-              body = build3_v (COND_EXPR, tmp, body, build_empty_stmt ());
+              body = build3_v (COND_EXPR, tmp, body,
+			       build_empty_stmt (input_location));
             }
         }
       body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
@@ -2063,7 +2064,8 @@ generate_loop_for_temp_to_lhs (gfc_expr 
 					 TREE_TYPE (wheremaskexpr),
 					 wheremaskexpr);
 	  tmp = fold_build3 (COND_EXPR, void_type_node,
-			     wheremaskexpr, tmp, build_empty_stmt ());
+			     wheremaskexpr, tmp,
+			     build_empty_stmt (input_location));
        }
 
       gfc_add_expr_to_block (&body, tmp);
@@ -2160,7 +2162,7 @@ generate_loop_for_rhs_to_temp (gfc_expr 
 				     TREE_TYPE (wheremaskexpr),
 				     wheremaskexpr);
       tmp = fold_build3 (COND_EXPR, void_type_node,
-			 wheremaskexpr, tmp, build_empty_stmt ());
+			 wheremaskexpr, tmp, build_empty_stmt (input_location));
     }
 
   gfc_add_expr_to_block (&body1, tmp);
@@ -2732,7 +2734,7 @@ gfc_trans_forall_1 (gfc_code * code, for
   if (code->expr
       && code->expr->expr_type == EXPR_CONSTANT
       && !code->expr->value.logical)
-    return build_empty_stmt ();
+    return build_empty_stmt (input_location);
 
   n = 0;
   /* Count the FORALL index number.  */
@@ -3288,7 +3290,7 @@ gfc_trans_where_assign (gfc_expr *expr1,
   else
     tmp = gfc_conv_operator_assign (&lse, &rse, sym);
 
-  tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt ());
+  tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
 
   gfc_add_expr_to_block (&body, tmp);
 
@@ -3341,7 +3343,8 @@ gfc_trans_where_assign (gfc_expr *expr1,
 
           /* Use the scalar assignment as is.  */
           tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, false);
-          tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt ());
+          tmp = build3_v (COND_EXPR, maskexpr, tmp,
+			  build_empty_stmt (input_location));
           gfc_add_expr_to_block (&body, tmp);
 
           /* Increment count2.  */
@@ -3744,7 +3747,7 @@ gfc_trans_where_3 (gfc_code * cblock, gf
 
   tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, false);
   estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts, false, false)
-		 : build_empty_stmt ();
+		 : build_empty_stmt (input_location);
   tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
   gfc_add_expr_to_block (&body, tmp);
   gfc_add_block_to_block (&body, &cse.post);
@@ -3922,7 +3925,7 @@ gfc_trans_allocate (gfc_code * code)
 	      parm = fold_build2 (NE_EXPR, boolean_type_node,
 				  stat, build_int_cst (TREE_TYPE (stat), 0));
 	      tmp = fold_build3 (COND_EXPR, void_type_node,
-				 parm, tmp, build_empty_stmt ());
+				 parm, tmp, build_empty_stmt (input_location));
 	      gfc_add_expr_to_block (&se.pre, tmp);
 	    }
 
Index: fortran/trans.c
===================================================================
--- fortran/trans.c	(revision 142042)
+++ fortran/trans.c	(working copy)
@@ -238,7 +238,7 @@ gfc_finish_block (stmtblock_t * stmtbloc
 
   expr = stmtblock->head;
   if (!expr)
-    expr = build_empty_stmt ();
+    expr = build_empty_stmt (input_location);
 
   stmtblock->head = NULL_TREE;
 
@@ -484,7 +484,7 @@ gfc_trans_runtime_check (bool error, boo
       cond = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
       cond = fold_convert (boolean_type_node, cond);
 
-      tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt ());
+      tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt (input_location));
       gfc_add_expr_to_block (pblock, tmp);
     }
 }
@@ -515,7 +515,7 @@ gfc_call_malloc (stmtblock_t * block, tr
       ("Attempt to allocate a negative amount of memory."));
   tmp = fold_build3 (COND_EXPR, void_type_node, negative,
 		     build_call_expr (gfor_fndecl_runtime_error, 1, msg),
-		     build_empty_stmt ());
+		     build_empty_stmt (input_location));
   gfc_add_expr_to_block (block, tmp);
 
   /* Call malloc and check the result.  */
@@ -533,7 +533,7 @@ gfc_call_malloc (stmtblock_t * block, tr
       ("Memory allocation failed"));
   tmp = fold_build3 (COND_EXPR, void_type_node, null_result,
 		     build_call_expr (gfor_fndecl_os_error, 1, msg),
-		     build_empty_stmt ());
+		     build_empty_stmt (input_location));
   gfc_add_expr_to_block (&block2, tmp);
   malloc_result = gfc_finish_block (&block2);
 
@@ -606,7 +606,7 @@ gfc_allocate_with_status (stmtblock_t * 
       tmp = fold_build3 (COND_EXPR, void_type_node,
 			 fold_build2 (NE_EXPR, boolean_type_node,
 				      status, build_int_cst (status_type, 0)),
-			 tmp, build_empty_stmt ());
+			 tmp, build_empty_stmt (input_location));
       gfc_add_expr_to_block (block, tmp);
     }
 
@@ -663,7 +663,7 @@ gfc_allocate_with_status (stmtblock_t * 
   tmp = fold_build3 (COND_EXPR, void_type_node,
 		     fold_build2 (EQ_EXPR, boolean_type_node, res,
 				  build_int_cst (pvoid_type_node, 0)),
-		     tmp, build_empty_stmt ());
+		     tmp, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&alloc_block, tmp);
 
   cond = fold_build2 (LT_EXPR, boolean_type_node, size,
@@ -789,7 +789,7 @@ gfc_call_free (tree var)
 		      build_int_cst (pvoid_type_node, 0));
   call = build_call_expr (built_in_decls[BUILT_IN_FREE], 1, var);
   tmp = fold_build3 (COND_EXPR, void_type_node, cond, call,
-		     build_empty_stmt ());
+		     build_empty_stmt (input_location));
   gfc_add_expr_to_block (&block, tmp);
 
   return gfc_finish_block (&block);
@@ -853,7 +853,7 @@ gfc_deallocate_with_status (tree pointer
 				       varname);
     }
   else
-    error = build_empty_stmt ();
+    error = build_empty_stmt (input_location);
 
   if (status != NULL_TREE && !integer_zerop (status))
     {
@@ -888,7 +888,7 @@ gfc_deallocate_with_status (tree pointer
 			 fold_build1 (INDIRECT_REF, status_type, status),
 			 build_int_cst (status_type, 0));
       tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp,
-			 build_empty_stmt ());
+			 build_empty_stmt (input_location));
       gfc_add_expr_to_block (&non_null, tmp);
     }
 
@@ -935,7 +935,7 @@ gfc_call_realloc (stmtblock_t * block, t
       ("Attempt to allocate a negative amount of memory."));
   tmp = fold_build3 (COND_EXPR, void_type_node, negative,
 		     build_call_expr (gfor_fndecl_runtime_error, 1, msg),
-		     build_empty_stmt ());
+		     build_empty_stmt (input_location));
   gfc_add_expr_to_block (block, tmp);
 
   /* Call realloc and check the result.  */
@@ -952,14 +952,14 @@ gfc_call_realloc (stmtblock_t * block, t
 						("Out of memory"));
   tmp = fold_build3 (COND_EXPR, void_type_node, null_result,
 		     build_call_expr (gfor_fndecl_os_error, 1, msg),
-		     build_empty_stmt ());
+		     build_empty_stmt (input_location));
   gfc_add_expr_to_block (block, tmp);
 
   /* if (size == 0) then the result is NULL.  */
   tmp = fold_build2 (MODIFY_EXPR, type, res, build_int_cst (type, 0));
   zero = fold_build1 (TRUTH_NOT_EXPR, boolean_type_node, nonzero);
   tmp = fold_build3 (COND_EXPR, void_type_node, zero, tmp,
-		     build_empty_stmt ());
+		     build_empty_stmt (input_location));
   gfc_add_expr_to_block (block, tmp);
 
   return res;
@@ -1037,7 +1037,7 @@ gfc_trans_code (gfc_code * code)
   tree res;
 
   if (!code)
-    return build_empty_stmt ();
+    return build_empty_stmt (input_location);
 
   gfc_start_block (&block);
 
Index: fortran/trans-decl.c
===================================================================
--- fortran/trans-decl.c	(revision 142042)
+++ fortran/trans-decl.c	(working copy)
@@ -2791,7 +2791,7 @@ gfc_init_default_dt (gfc_symbol * sym, t
     {
       present = gfc_conv_expr_present (sym);
       tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present,
-		    tmp, build_empty_stmt ());
+		    tmp, build_empty_stmt (input_location));
     }
   gfc_add_expr_to_block (&fnblock, tmp);
   gfc_free_expr (e);
@@ -3999,7 +3999,7 @@ gfc_generate_constructors (void)
   for (; gfc_static_ctors; gfc_static_ctors = TREE_CHAIN (gfc_static_ctors))
     {
       tmp = build_call_expr (TREE_VALUE (gfc_static_ctors), 0);
-      DECL_SAVED_TREE (fndecl) = build_stmt (EXPR_STMT, tmp);
+      DECL_SAVED_TREE (fndecl) = build_stmt (input_location, EXPR_STMT, tmp);
     }
 
   decl = getdecls ();
Index: fortran/trans-io.c
===================================================================
--- fortran/trans-io.c	(revision 141983)
+++ fortran/trans-io.c	(working copy)
@@ -266,7 +266,7 @@ gfc_trans_io_runtime_check (tree cond, t
       cond = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
       cond = fold_convert (boolean_type_node, cond);
 
-      tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt ());
+      tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt (input_location));
       gfc_add_expr_to_block (pblock, tmp);
     }
 }
Index: fortran/trans-intrinsic.c
===================================================================
--- fortran/trans-intrinsic.c	(revision 142042)
+++ fortran/trans-intrinsic.c	(working copy)
@@ -1354,7 +1354,7 @@ gfc_conv_intrinsic_ctime (gfc_se * se, g
   cond = fold_build2 (GT_EXPR, boolean_type_node,
 		      len, build_int_cst (TREE_TYPE (len), 0));
   tmp = gfc_call_free (var);
-  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&se->post, tmp);
 
   se->expr = var;
@@ -1392,7 +1392,7 @@ gfc_conv_intrinsic_fdate (gfc_se * se, g
   cond = fold_build2 (GT_EXPR, boolean_type_node,
 		      len, build_int_cst (TREE_TYPE (len), 0));
   tmp = gfc_call_free (var);
-  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&se->post, tmp);
 
   se->expr = var;
@@ -1432,7 +1432,7 @@ gfc_conv_intrinsic_ttynam (gfc_se * se, 
   cond = fold_build2 (GT_EXPR, boolean_type_node,
 		      len, build_int_cst (TREE_TYPE (len), 0));
   tmp = gfc_call_free (var);
-  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&se->post, tmp);
 
   se->expr = var;
@@ -1517,10 +1517,12 @@ gfc_conv_intrinsic_minmax (gfc_se * se, 
 	  tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp,
 			     fold_convert (boolean_type_node, isnan));
 	}
-      tmp = build3_v (COND_EXPR, tmp, thencase, build_empty_stmt ());
+      tmp = build3_v (COND_EXPR, tmp, thencase,
+		      build_empty_stmt (input_location));
 
       if (cond != NULL_TREE)
-	tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+	tmp = build3_v (COND_EXPR, cond, tmp,
+			build_empty_stmt (input_location));
 
       gfc_add_expr_to_block (&se->pre, tmp);
       argexpr = argexpr->next;
@@ -1567,7 +1569,7 @@ gfc_conv_intrinsic_minmax_char (gfc_se *
   cond = fold_build2 (GT_EXPR, boolean_type_node,
 		      len, build_int_cst (TREE_TYPE (len), 0));
   tmp = gfc_call_free (var);
-  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&se->post, tmp);
 
   se->expr = var;
@@ -1763,7 +1765,7 @@ gfc_conv_intrinsic_anyall (gfc_se * se, 
   gfc_add_block_to_block (&body, &arrayse.pre);
   tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
 		     build_int_cst (TREE_TYPE (arrayse.expr), 0));
-  tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
+  tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&body, tmp);
   gfc_add_block_to_block (&body, &arrayse.post);
 
@@ -1830,7 +1832,8 @@ gfc_conv_intrinsic_count (gfc_se * se, g
   gfc_copy_loopinfo_to_se (&arrayse, &loop);
   arrayse.ss = arrayss;
   gfc_conv_expr_val (&arrayse, actual->expr);
-  tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
+  tmp = build3_v (COND_EXPR, arrayse.expr, tmp,
+		  build_empty_stmt (input_location));
 
   gfc_add_block_to_block (&body, &arrayse.pre);
   gfc_add_expr_to_block (&body, tmp);
@@ -1942,7 +1945,8 @@ gfc_conv_intrinsic_arith (gfc_se * se, g
       /* We enclose the above in if (mask) {...} .  */
       tmp = gfc_finish_block (&block);
 
-      tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+      tmp = build3_v (COND_EXPR, maskse.expr, tmp,
+		      build_empty_stmt (input_location));
     }
   else
     tmp = gfc_finish_block (&block);
@@ -1960,7 +1964,8 @@ gfc_conv_intrinsic_arith (gfc_se * se, g
       gfc_add_block_to_block (&block, &loop.post);
       tmp = gfc_finish_block (&block);
 
-      tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+      tmp = build3_v (COND_EXPR, maskse.expr, tmp,
+		      build_empty_stmt (input_location));
       gfc_add_expr_to_block (&block, tmp);
       gfc_add_block_to_block (&se->pre, &block);
     }
@@ -2230,7 +2235,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * s
   tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
 		     fold_build2 (op, boolean_type_node,
 				  arrayse.expr, limit), tmp);
-  tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
+  tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&block, tmp);
 
   if (maskss)
@@ -2238,7 +2243,8 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * s
       /* We enclose the above in if (mask) {...}.  */
       tmp = gfc_finish_block (&block);
 
-      tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+      tmp = build3_v (COND_EXPR, maskse.expr, tmp,
+		      build_empty_stmt (input_location));
     }
   else
     tmp = gfc_finish_block (&block);
@@ -2392,14 +2398,15 @@ gfc_conv_intrinsic_minmaxval (gfc_se * s
 
   /* If it is a more extreme value.  */
   tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
-  tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
+  tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&block, tmp);
   gfc_add_block_to_block (&block, &arrayse.post);
 
   tmp = gfc_finish_block (&block);
   if (maskss)
     /* We enclose the above in if (mask) {...}.  */
-    tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+    tmp = build3_v (COND_EXPR, maskse.expr, tmp,
+		    build_empty_stmt (input_location));
   gfc_add_expr_to_block (&body, tmp);
 
   gfc_trans_scalarizing_loops (&loop, &body);
@@ -2414,7 +2421,8 @@ gfc_conv_intrinsic_minmaxval (gfc_se * s
       gfc_add_block_to_block (&block, &loop.post);
       tmp = gfc_finish_block (&block);
 
-      tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+      tmp = build3_v (COND_EXPR, maskse.expr, tmp,
+		      build_empty_stmt (input_location));
       gfc_add_expr_to_block (&block, tmp);
       gfc_add_block_to_block (&se->pre, &block);
     }
@@ -3284,7 +3292,7 @@ gfc_conv_intrinsic_rrspacing (gfc_se * s
 
   cond = fold_build2 (NE_EXPR, boolean_type_node, x,
 		      build_real_from_int_cst (type, integer_zero_node));
-  tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt ());
+  tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&se->pre, tmp);
 
   se->expr = fold_convert (type, x);
@@ -3648,7 +3656,8 @@ gfc_conv_intrinsic_array_transfer (gfc_s
 	  gfc_init_block (&block);
 	  tmp = gfc_conv_array_data (argse.expr);
 	  tmp = fold_build2 (NE_EXPR, boolean_type_node, source, tmp);
-	  tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+	  tmp = build3_v (COND_EXPR, tmp, stmt,
+			  build_empty_stmt (input_location));
 	  gfc_add_expr_to_block (&block, tmp);
 	  gfc_add_block_to_block (&block, &se->post);
 	  gfc_init_block (&se->post);
@@ -4137,7 +4146,7 @@ gfc_conv_intrinsic_trim (gfc_se * se, gf
   cond = fold_build2 (GT_EXPR, boolean_type_node,
 		      len, build_int_cst (TREE_TYPE (len), 0));
   tmp = gfc_call_free (var);
-  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
   gfc_add_expr_to_block (&se->post, tmp);
 
   se->expr = var;
@@ -4228,7 +4237,7 @@ gfc_conv_intrinsic_repeat (gfc_se * se, 
   tmp = build1_v (GOTO_EXPR, exit_label);
   TREE_USED (exit_label) = 1;
   tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
-		     build_empty_stmt ());
+		     build_empty_stmt (input_location));
   gfc_add_expr_to_block (&body, tmp);
 
   /* Call memmove (dest + (i*slen*size), src, slen*size).  */
Index: c-typeck.c
===================================================================
--- c-typeck.c	(revision 142042)
+++ c-typeck.c	(working copy)
@@ -1889,11 +1889,12 @@ lookup_field (tree decl, tree component)
   return tree_cons (NULL_TREE, field, NULL_TREE);
 }
 
-/* Make an expression to refer to the COMPONENT field of
-   structure or union value DATUM.  COMPONENT is an IDENTIFIER_NODE.  */
+/* Make an expression to refer to the COMPONENT field of structure or
+   union value DATUM.  COMPONENT is an IDENTIFIER_NODE.  LOC is the
+   location of the COMPONENT_REF.  */
 
 tree
-build_component_ref (tree datum, tree component)
+build_component_ref (location_t loc, tree datum, tree component)
 {
   tree type = TREE_TYPE (datum);
   enum tree_code code = TREE_CODE (type);
@@ -1917,7 +1918,7 @@ build_component_ref (tree datum, tree co
 
       if (!field)
 	{
-	  error ("%qT has no member named %qE", type, component);
+	  error_at (loc, "%qT has no member named %qE", type, component);
 	  return error_mark_node;
 	}
 
@@ -1941,6 +1942,7 @@ build_component_ref (tree datum, tree co
 
 	  ref = build3 (COMPONENT_REF, subtype, datum, subdatum,
 			NULL_TREE);
+	  SET_EXPR_LOCATION (ref, loc);
 	  if (TREE_READONLY (datum) || TREE_READONLY (subdatum))
 	    TREE_READONLY (ref) = 1;
 	  if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (subdatum))
@@ -1958,8 +1960,9 @@ build_component_ref (tree datum, tree co
       return ref;
     }
   else if (code != ERROR_MARK)
-    error ("request for member %qE in something not a structure or union",
-	   component);
+    error_at (loc,
+	      "request for member %qE in something not a structure or union",
+	      component);
 
   return error_mark_node;
 }
@@ -2046,7 +2049,7 @@ build_indirect_ref (location_t loc, tree
    LOC is the location to use for the returned expression.  */
 
 tree
-build_array_ref (tree array, tree index, location_t loc)
+build_array_ref (location_t loc, tree array, tree index)
 {
   tree ret;
   bool swapped = false;
@@ -2173,7 +2176,7 @@ build_array_ref (tree array, tree index,
    whether this will be used for a function call.  LOC is the source
    location of the identifier.  */
 tree
-build_external_ref (tree id, int fun, location_t loc)
+build_external_ref (location_t loc, tree id, int fun)
 {
   tree ref;
   tree decl = lookup_name (id);
@@ -2193,7 +2196,7 @@ build_external_ref (tree id, int fun, lo
     return error_mark_node;
   else
     {
-      undeclared_variable (id, loc);
+      undeclared_variable (loc, id);
       return error_mark_node;
     }
 
@@ -2308,7 +2311,7 @@ pop_maybe_used (bool used)
 /* Return the result of sizeof applied to EXPR.  */
 
 struct c_expr
-c_expr_sizeof_expr (struct c_expr expr)
+c_expr_sizeof_expr (location_t loc, struct c_expr expr)
 {
   struct c_expr ret;
   if (expr.value == error_mark_node)
@@ -2319,12 +2322,13 @@ c_expr_sizeof_expr (struct c_expr expr)
     }
   else
     {
-      ret.value = c_sizeof (TREE_TYPE (expr.value));
+      ret.value = c_sizeof (loc, TREE_TYPE (expr.value));
       ret.original_code = ERROR_MARK;
       if (c_vla_type_p (TREE_TYPE (expr.value)))
 	{
 	  /* sizeof is evaluated when given a vla (C99 6.5.3.4p2).  */
 	  ret.value = build2 (COMPOUND_EXPR, TREE_TYPE (ret.value), expr.value, ret.value);
+	  SET_EXPR_LOCATION (ret.value, loc);
 	}
       pop_maybe_used (C_TYPE_VARIABLE_SIZE (TREE_TYPE (expr.value)));
     }
@@ -2332,15 +2336,16 @@ c_expr_sizeof_expr (struct c_expr expr)
 }
 
 /* Return the result of sizeof applied to T, a structure for the type
-   name passed to sizeof (rather than the type itself).  */
+   name passed to sizeof (rather than the type itself).  LOC is the
+   location of the original expression.  */
 
 struct c_expr
-c_expr_sizeof_type (struct c_type_name *t)
+c_expr_sizeof_type (location_t loc, struct c_type_name *t)
 {
   tree type;
   struct c_expr ret;
   type = groktypename (t);
-  ret.value = c_sizeof (type);
+  ret.value = c_sizeof (loc, type);
   ret.original_code = ERROR_MARK;
   pop_maybe_used (type != error_mark_node
 		  ? C_TYPE_VARIABLE_SIZE (type) : false);
@@ -2744,7 +2749,7 @@ convert_arguments (int nargs, tree *arga
 */
 
 struct c_expr
-parser_build_unary_op (enum tree_code code, struct c_expr arg, location_t loc)
+parser_build_unary_op (location_t loc, enum tree_code code, struct c_expr arg)
 {
   struct c_expr result;
 
@@ -3409,10 +3414,11 @@ c_mark_addressable (tree exp)
     }
 }
 
-/* Build and return a conditional expression IFEXP ? OP1 : OP2.  */
+/* Build and return a conditional expression IFEXP ? OP1 : OP2.  Set
+   the location of the expression to LOC.  */
 
 tree
-build_conditional_expr (tree ifexp, tree op1, tree op2)
+build_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2)
 {
   tree type1;
   tree type2;
@@ -3442,7 +3448,7 @@ build_conditional_expr (tree ifexp, tree
      In C99 they will be pointers by now.  */
   if (code1 == ARRAY_TYPE || code2 == ARRAY_TYPE)
     {
-      error ("non-lvalue array in conditional expression");
+      error_at (loc, "non-lvalue array in conditional expression");
       return error_mark_node;
     }
 
@@ -3490,14 +3496,14 @@ build_conditional_expr (tree ifexp, tree
 			   && tree_expr_nonnegative_warnv_p (op2, &ovf)))
 		/* OK */;
 	      else
-		warning (OPT_Wsign_compare, "signed and unsigned type in conditional expression");
+		warning_at (loc, OPT_Wsign_compare, "signed and unsigned type in conditional expression");
 	    }
 	}
     }
   else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
     {
       if (code1 != VOID_TYPE || code2 != VOID_TYPE)
-	pedwarn (input_location, OPT_pedantic, 
+	pedwarn (loc, OPT_pedantic, 
 		 "ISO C forbids conditional expr with only one void side");
       result_type = void_type_node;
     }
@@ -3512,7 +3518,7 @@ build_conditional_expr (tree ifexp, tree
       else if (VOID_TYPE_P (TREE_TYPE (type1)))
 	{
 	  if (TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
-	    pedwarn (input_location, OPT_pedantic, 
+	    pedwarn (loc, OPT_pedantic, 
 		     "ISO C forbids conditional expr between "
 		     "%<void *%> and function pointer");
 	  result_type = build_pointer_type (qualify_type (TREE_TYPE (type1),
@@ -3521,7 +3527,7 @@ build_conditional_expr (tree ifexp, tree
       else if (VOID_TYPE_P (TREE_TYPE (type2)))
 	{
 	  if (TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
-	    pedwarn (input_location, OPT_pedantic, 
+	    pedwarn (loc, OPT_pedantic, 
 		     "ISO C forbids conditional expr between "
 		     "%<void *%> and function pointer");
 	  result_type = build_pointer_type (qualify_type (TREE_TYPE (type2),
@@ -3529,7 +3535,7 @@ build_conditional_expr (tree ifexp, tree
 	}
       else
 	{
-	  pedwarn (input_location, 0, 
+	  pedwarn (loc, 0, 
 		   "pointer type mismatch in conditional expression");
 	  result_type = build_pointer_type (void_type_node);
 	}
@@ -3537,7 +3543,7 @@ build_conditional_expr (tree ifexp, tree
   else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
     {
       if (!null_pointer_constant_p (orig_op2))
-	pedwarn (input_location, 0, 
+	pedwarn (loc, 0, 
 		 "pointer/integer type mismatch in conditional expression");
       else
 	{
@@ -3548,7 +3554,7 @@ build_conditional_expr (tree ifexp, tree
   else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
     {
       if (!null_pointer_constant_p (orig_op1))
-	pedwarn (input_location, 0, 
+	pedwarn (loc, 0, 
 		 "pointer/integer type mismatch in conditional expression");
       else
 	{
@@ -3563,7 +3569,7 @@ build_conditional_expr (tree ifexp, tree
 	result_type = void_type_node;
       else
 	{
-	  error ("type mismatch in conditional expression");
+	  error_at (loc, "type mismatch in conditional expression");
 	  return error_mark_node;
 	}
     }
@@ -3579,14 +3585,18 @@ build_conditional_expr (tree ifexp, tree
   if (result_type != TREE_TYPE (op2))
     op2 = convert_and_check (result_type, op2);
 
-  return fold_build3 (COND_EXPR, result_type, ifexp, op1, op2);
+  op1 = fold_build3 (COND_EXPR, result_type, ifexp, op1, op2);
+  protected_set_expr_location (op1, loc);
+  return op1;
 }
 
 /* Return a compound expression that performs two expressions and
-   returns the value of the second of them.  */
+   returns the value of the second of them.
+
+   LOC is the location of the COMPOUND_EXPR.  */
 
 tree
-build_compound_expr (tree expr1, tree expr2)
+build_compound_expr (location_t loc, tree expr1, tree expr2)
 {
   if (!TREE_SIDE_EFFECTS (expr1))
     {
@@ -3603,8 +3613,8 @@ build_compound_expr (tree expr1, tree ex
 		   && CONVERT_EXPR_P (TREE_OPERAND (expr1, 1)))
 	    ; /* (void) a, (void) b, c */
 	  else
-	    warning (OPT_Wunused_value, 
-		     "left-hand operand of comma expression has no effect");
+	    warning_at (loc, OPT_Wunused_value, 
+			"left-hand operand of comma expression has no effect");
 	}
     }
 
@@ -3613,18 +3623,22 @@ build_compound_expr (tree expr1, tree ex
      `foo() + bar(), baz()' the result of the `+' operator is not used,
      so we should issue a warning.  */
   else if (warn_unused_value)
-    warn_if_unused_value (expr1, input_location);
+    warn_if_unused_value (expr1, loc);
 
   if (expr2 == error_mark_node)
     return error_mark_node;
 
-  return build2 (COMPOUND_EXPR, TREE_TYPE (expr2), expr1, expr2);
+  expr1 = build2 (COMPOUND_EXPR, TREE_TYPE (expr2), expr1, expr2);
+  SET_EXPR_LOCATION (expr1, loc);
+  return expr1;
 }
 
-/* Build an expression representing a cast to type TYPE of expression EXPR.  */
+/* Build an expression representing a cast to type TYPE of expression
+   EXPR.  LOC is the location of the cast-- typically the open paren
+   of the cast.  */
 
 tree
-build_c_cast (tree type, tree expr)
+build_c_cast (location_t loc, tree type, tree expr)
 {
   tree value = expr;
 
@@ -3641,13 +3655,13 @@ build_c_cast (tree type, tree expr)
 
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
-      error ("cast specifies array type");
+      error_at (loc, "cast specifies array type");
       return error_mark_node;
     }
 
   if (TREE_CODE (type) == FUNCTION_TYPE)
     {
-      error ("cast specifies function type");
+      error_at (loc, "cast specifies function type");
       return error_mark_node;
     }
 
@@ -3662,7 +3676,7 @@ build_c_cast (tree type, tree expr)
     {
       if (TREE_CODE (type) == RECORD_TYPE
 	  || TREE_CODE (type) == UNION_TYPE)
-	pedwarn (input_location, OPT_pedantic, 
+	pedwarn (loc, OPT_pedantic, 
 		 "ISO C forbids casting nonscalar to the same type");
     }
   else if (TREE_CODE (type) == UNION_TYPE)
@@ -3679,15 +3693,14 @@ build_c_cast (tree type, tree expr)
 	{
 	  tree t;
 
-	  pedwarn (input_location, OPT_pedantic,
-		   "ISO C forbids casts to union type");
+	  pedwarn (loc, OPT_pedantic, "ISO C forbids casts to union type");
 	  t = digest_init (type,
 			   build_constructor_single (type, field, value),
 			   true, 0);
 	  TREE_CONSTANT (t) = TREE_CONSTANT (value);
 	  return t;
 	}
-      error ("cast to union type from type not present in union");
+      error_at (loc, "cast to union type from type not present in union");
       return error_mark_node;
     }
   else
@@ -3695,7 +3708,11 @@ build_c_cast (tree type, tree expr)
       tree otype, ovalue;
 
       if (type == void_type_node)
-	return build1 (CONVERT_EXPR, type, value);
+	{
+	  tree t = build1 (CONVERT_EXPR, type, value);
+	  SET_EXPR_LOCATION (t, loc);
+	  return t;
+	}
 
       otype = TREE_TYPE (value);
 
@@ -3733,12 +3750,14 @@ build_c_cast (tree type, tree expr)
 		 && TREE_CODE (in_otype) == POINTER_TYPE);
 
 	  if (added)
-	    warning (OPT_Wcast_qual, "cast adds new qualifiers to function type");
+	    warning_at (loc, OPT_Wcast_qual,
+			"cast adds new qualifiers to function type");
 
 	  if (discarded)
 	    /* There are qualifiers present in IN_OTYPE that are not
 	       present in IN_TYPE.  */
-	    warning (OPT_Wcast_qual, "cast discards qualifiers from pointer target type");
+	    warning_at (loc, OPT_Wcast_qual,
+			"cast discards qualifiers from pointer target type");
 	}
 
       /* Warn about possible alignment problems.  */
@@ -3753,8 +3772,8 @@ build_c_cast (tree type, tree expr)
 		|| TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE)
 	       && TYPE_MODE (TREE_TYPE (otype)) == VOIDmode)
 	  && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
-	warning (OPT_Wcast_align,
-		 "cast increases required alignment of target type");
+	warning_at (loc, OPT_Wcast_align,
+		    "cast increases required alignment of target type");
 
       if (TREE_CODE (type) == INTEGER_TYPE
 	  && TREE_CODE (otype) == POINTER_TYPE
@@ -3764,21 +3783,23 @@ build_c_cast (tree type, tree expr)
          of cases such as SIG_*, warn about converting constant
          pointers to integers. In some cases it may cause unwanted
          sign extension, and a warning is appropriate.  */
-	warning (OPT_Wpointer_to_int_cast,
-		 "cast from pointer to integer of different size");
+	warning_at (loc, OPT_Wpointer_to_int_cast,
+		    "cast from pointer to integer of different size");
 
       if (TREE_CODE (value) == CALL_EXPR
 	  && TREE_CODE (type) != TREE_CODE (otype))
-	warning (OPT_Wbad_function_cast, "cast from function call of type %qT "
-		 "to non-matching type %qT", otype, type);
+	warning_at (loc, OPT_Wbad_function_cast,
+		    "cast from function call of type %qT "
+		    "to non-matching type %qT", otype, type);
 
       if (TREE_CODE (type) == POINTER_TYPE
 	  && TREE_CODE (otype) == INTEGER_TYPE
 	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
 	  /* Don't warn about converting any constant.  */
 	  && !TREE_CONSTANT (value))
-	warning (OPT_Wint_to_pointer_cast, "cast to pointer from integer "
-		 "of different size");
+	warning_at (loc,
+		    OPT_Wint_to_pointer_cast, "cast to pointer from integer "
+		    "of different size");
 
       if (warn_strict_aliasing <= 2)
         strict_aliasing_warning (otype, type, expr);
@@ -3791,7 +3812,7 @@ build_c_cast (tree type, tree expr)
 	  && TREE_CODE (otype) == POINTER_TYPE
 	  && TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE
 	  && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
-	pedwarn (input_location, OPT_pedantic, "ISO C forbids "
+	pedwarn (loc, OPT_pedantic, "ISO C forbids "
 		 "conversion of function pointer to object pointer type");
 
       if (pedantic
@@ -3800,7 +3821,7 @@ build_c_cast (tree type, tree expr)
 	  && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
 	  && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
 	  && !null_pointer_constant_p (value))
-	pedwarn (input_location, OPT_pedantic, "ISO C forbids "
+	pedwarn (loc, OPT_pedantic, "ISO C forbids "
 		 "conversion of object pointer to function pointer type");
 
       ovalue = value;
@@ -3830,12 +3851,16 @@ build_c_cast (tree type, tree expr)
   if (value == expr)
     value = non_lvalue (value);
 
+  if (CAN_HAVE_LOCATION_P (value))
+    SET_EXPR_LOCATION (value, loc);
   return value;
 }
 
-/* Interpret a cast of expression EXPR to type TYPE.  */
+/* Interpret a cast of expression EXPR to type TYPE.  LOC is the
+   location of the open paren of the cast, or the position of the cast
+   expr.  */
 tree
-c_cast_expr (struct c_type_name *type_name, tree expr)
+c_cast_expr (location_t loc, struct c_type_name *type_name, tree expr)
 {
   tree type;
   int saved_wsp = warn_strict_prototypes;
@@ -3847,7 +3872,7 @@ c_cast_expr (struct c_type_name *type_na
   type = groktypename (type_name);
   warn_strict_prototypes = saved_wsp;
 
-  return build_c_cast (type, expr);
+  return build_c_cast (loc, type, expr);
 }
 
 /* Build an assignment expression of lvalue LHS from value RHS.
@@ -6996,8 +7021,8 @@ build_asm_stmt (tree cv_qualifier, tree 
    string in the asm expression -- asm("blah") and asm("blah" : )
    are subtly different.  We use a ASM_EXPR node to represent this.  */
 tree
-build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
-		bool simple)
+build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
+		tree clobbers, bool simple)
 {
   tree tail;
   tree args;
@@ -7081,7 +7106,7 @@ build_asm_expr (tree string, tree output
       TREE_VALUE (tail) = input;
     }
 
-  args = build_stmt (ASM_EXPR, string, outputs, inputs, clobbers);
+  args = build_stmt (loc, ASM_EXPR, string, outputs, inputs, clobbers);
 
   /* asm statements without outputs, including simple ones, are treated
      as volatile.  */
@@ -7150,16 +7175,18 @@ c_finish_goto_ptr (tree expr)
 }
 
 /* Generate a C `return' statement.  RETVAL is the expression for what
-   to return, or a null pointer for `return;' with no value.  */
+   to return, or a null pointer for `return;' with no value.  LOC is
+   the location of the return statement.  */
 
 tree
-c_finish_return (tree retval)
+c_finish_return (location_t loc, tree retval)
 {
   tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl)), ret_stmt;
   bool no_warning = false;
 
   if (TREE_THIS_VOLATILE (current_function_decl))
-    warning (0, "function declared %<noreturn%> has a %<return%> statement");
+    warning_at (loc, 0,
+		"function declared %<noreturn%> has a %<return%> statement");
 
   if (!retval)
     {
@@ -7167,7 +7194,7 @@ c_finish_return (tree retval)
       if ((warn_return_type || flag_isoc99)
 	  && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
 	{
-	  pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wreturn_type, 
+	  pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wreturn_type, 
 		       "%<return%> with no value, in "
 		       "function returning non-void");
 	  no_warning = true;
@@ -7177,10 +7204,10 @@ c_finish_return (tree retval)
     {
       current_function_returns_null = 1;
       if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
-	pedwarn (input_location, 0, 
+	pedwarn (loc, 0, 
 		 "%<return%> with a value, in function returning void");
       else 
-	pedwarn (input_location, OPT_pedantic, "ISO C forbids "
+	pedwarn (loc, OPT_pedantic, "ISO C forbids "
 		 "%<return%> with expression, in function returning void");
     }
   else
@@ -7237,7 +7264,8 @@ c_finish_return (tree retval)
 		  && !DECL_EXTERNAL (inner)
 		  && !TREE_STATIC (inner)
 		  && DECL_CONTEXT (inner) == current_function_decl)
-		warning (0, "function returns address of local variable");
+		warning_at (loc,
+			    0, "function returns address of local variable");
 	      break;
 
 	    default:
@@ -7248,12 +7276,13 @@ c_finish_return (tree retval)
 	}
 
       retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, t);
+      SET_EXPR_LOCATION (retval, loc);
 
       if (warn_sequence_point)
 	verify_sequence_points (retval);
     }
 
-  ret_stmt = build_stmt (RETURN_EXPR, retval);
+  ret_stmt = build_stmt (loc, RETURN_EXPR, retval);
   TREE_NO_WARNING (ret_stmt) |= no_warning;
   return add_stmt (ret_stmt);
 }
@@ -7618,6 +7647,9 @@ emit_side_effect_warnings (tree expr)
 tree
 c_process_expr_stmt (tree expr)
 {
+  location_t loc = CAN_HAVE_LOCATION_P (expr) ? EXPR_LOCATION (expr)
+    : input_location;
+
   if (!expr)
     return NULL_TREE;
 
@@ -7627,7 +7659,7 @@ c_process_expr_stmt (tree expr)
   if (TREE_TYPE (expr) != error_mark_node
       && !COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (expr))
       && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
-    error ("expression statement has incomplete type");
+    error_at (loc, "expression statement has incomplete type");
 
   /* If we're not processing a statement expression, warn about unused values.
      Warnings for statement expressions will be emitted later, once we figure
@@ -7639,10 +7671,10 @@ c_process_expr_stmt (tree expr)
   /* If the expression is not of a type to which we cannot assign a line
      number, wrap the thing in a no-op NOP_EXPR.  */
   if (DECL_P (expr) || CONSTANT_CLASS_P (expr))
-    expr = build1 (NOP_EXPR, TREE_TYPE (expr), expr);
-
-  if (CAN_HAVE_LOCATION_P (expr))
-    SET_EXPR_LOCATION (expr, input_location);
+    {
+      expr = build1 (NOP_EXPR, TREE_TYPE (expr), expr);
+      SET_EXPR_LOCATION (expr, loc);
+    }
 
   return expr;
 }
@@ -7696,14 +7728,17 @@ c_begin_stmt_expr (void)
   return ret;
 }
 
+/* LOC is the location of the compound statement to which this body
+   belongs.  */
+
 tree
-c_finish_stmt_expr (tree body)
+c_finish_stmt_expr (location_t loc, tree body)
 {
   tree last, type, tmp, val;
   tree *last_p;
   struct c_label_list *dlist, *glist, *glist_prev = NULL;
 
-  body = c_end_compound_stmt (body, true);
+  body = c_end_compound_stmt (loc, body, true);
   if (c_switch_stack)
     {
       gcc_assert (c_switch_stack->blocked_stmt_expr != 0);
@@ -7806,7 +7841,11 @@ c_finish_stmt_expr (tree body)
   *last_p = build2 (MODIFY_EXPR, void_type_node, tmp, val);
   SET_EXPR_LOCUS (*last_p, EXPR_LOCUS (last));
 
-  return build4 (TARGET_EXPR, type, tmp, body, NULL_TREE, NULL_TREE);
+  {
+    tree t = build4 (TARGET_EXPR, type, tmp, body, NULL_TREE, NULL_TREE);
+    SET_EXPR_LOCATION (t, loc);
+    return t;
+  }
 }
 
 /* Begin the scope of an identifier of variably modified type, scope
@@ -7895,8 +7934,12 @@ c_begin_compound_stmt (bool do_scope)
   return stmt;
 }
 
+/* End a compound statement.  STMT is the statement.  LOC is the
+   location of the compound statement-- this is usually the location
+   of the opening brace.  */
+
 tree
-c_end_compound_stmt (tree stmt, bool do_scope)
+c_end_compound_stmt (location_t loc, tree stmt, bool do_scope)
 {
   tree block = NULL;
 
@@ -7908,7 +7951,7 @@ c_end_compound_stmt (tree stmt, bool do_
     }
 
   stmt = pop_stmt_list (stmt);
-  stmt = c_build_bind_expr (block, stmt);
+  stmt = c_build_bind_expr (loc, block, stmt);
 
   /* If this compound statement is nested immediately inside a statement
      expression, then force a BIND_EXPR to be created.  Otherwise we'll
@@ -7921,6 +7964,7 @@ c_end_compound_stmt (tree stmt, bool do_
     {
       stmt = build3 (BIND_EXPR, void_type_node, NULL, stmt, NULL);
       TREE_SIDE_EFFECTS (stmt) = 1;
+      SET_EXPR_LOCATION (stmt, loc);
     }
 
   return stmt;
@@ -7931,14 +7975,14 @@ c_end_compound_stmt (tree stmt, bool do_
    meant to apply to normal control flow transfer.  */
 
 void
-push_cleanup (tree ARG_UNUSED (decl), tree cleanup, bool eh_only)
+push_cleanup (tree decl, tree cleanup, bool eh_only)
 {
   enum tree_code code;
   tree stmt, list;
   bool stmt_expr;
 
   code = eh_only ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR;
-  stmt = build_stmt (code, NULL, cleanup);
+  stmt = build_stmt (DECL_SOURCE_LOCATION (decl), code, NULL, cleanup);
   add_stmt (stmt);
   stmt_expr = STATEMENT_LIST_STMT_EXPR (cur_stmt_list);
   list = push_stmt_list ();
@@ -8601,19 +8645,21 @@ c_begin_omp_parallel (void)
   return block;
 }
 
-/* Generate OMP_PARALLEL, with CLAUSES and BLOCK as its compound statement.  */
+/* Generate OMP_PARALLEL, with CLAUSES and BLOCK as its compound
+   statement.  LOC is the location of the OMP_PARALLEL.  */
 
 tree
-c_finish_omp_parallel (tree clauses, tree block)
+c_finish_omp_parallel (location_t loc, tree clauses, tree block)
 {
   tree stmt;
 
-  block = c_end_compound_stmt (block, true);
+  block = c_end_compound_stmt (loc, block, true);
 
   stmt = make_node (OMP_PARALLEL);
   TREE_TYPE (stmt) = void_type_node;
   OMP_PARALLEL_CLAUSES (stmt) = clauses;
   OMP_PARALLEL_BODY (stmt) = block;
+  SET_EXPR_LOCATION (stmt, loc);
 
   return add_stmt (stmt);
 }
@@ -8631,19 +8677,21 @@ c_begin_omp_task (void)
   return block;
 }
 
-/* Generate OMP_TASK, with CLAUSES and BLOCK as its compound statement.  */
+/* Generate OMP_TASK, with CLAUSES and BLOCK as its compound
+   statement.  LOC is the location of the #pragma.  */
 
 tree
-c_finish_omp_task (tree clauses, tree block)
+c_finish_omp_task (location_t loc, tree clauses, tree block)
 {
   tree stmt;
 
-  block = c_end_compound_stmt (block, true);
+  block = c_end_compound_stmt (loc, block, true);
 
   stmt = make_node (OMP_TASK);
   TREE_TYPE (stmt) = void_type_node;
   OMP_TASK_CLAUSES (stmt) = clauses;
   OMP_TASK_BODY (stmt) = block;
+  SET_EXPR_LOCATION (stmt, loc);
 
   return add_stmt (stmt);
 }
Index: gimplify.c
===================================================================
--- gimplify.c	(revision 142042)
+++ gimplify.c	(working copy)
@@ -2326,13 +2326,13 @@ gimplify_call_expr (tree *expr_p, gimple
 	  if (call_expr_nargs (*expr_p) < 2)
 	    {
 	      error ("too few arguments to function %<va_start%>");
-	      *expr_p = build_empty_stmt ();
+	      *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
 	      return GS_OK;
 	    }
 	  
 	  if (fold_builtin_next_arg (*expr_p, true))
 	    {
-	      *expr_p = build_empty_stmt ();
+	      *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
 	      return GS_OK;
 	    }
 	}
Index: c-omp.c
===================================================================
--- c-omp.c	(revision 141983)
+++ c-omp.c	(working copy)
@@ -35,72 +35,81 @@ along with GCC; see the file COPYING3.  
 
 
 /* Complete a #pragma omp master construct.  STMT is the structured-block
-   that follows the pragma.  */
+   that follows the pragma.  LOC is the l*/
 
 tree
-c_finish_omp_master (tree stmt)
+c_finish_omp_master (location_t loc, tree stmt)
 {
-  return add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
+  tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
+  SET_EXPR_LOCATION (t, loc);
+  return t;
 }
 
 /* Complete a #pragma omp critical construct.  STMT is the structured-block
    that follows the pragma, NAME is the identifier in the pragma, or null
-   if it was omitted.  */
+   if it was omitted.  LOC is the location of the #pragma.  */
 
 tree
-c_finish_omp_critical (tree body, tree name)
+c_finish_omp_critical (location_t loc, tree body, tree name)
 {
   tree stmt = make_node (OMP_CRITICAL);
   TREE_TYPE (stmt) = void_type_node;
   OMP_CRITICAL_BODY (stmt) = body;
   OMP_CRITICAL_NAME (stmt) = name;
+  SET_EXPR_LOCATION (stmt, loc);
   return add_stmt (stmt);
 }
 
 /* Complete a #pragma omp ordered construct.  STMT is the structured-block
-   that follows the pragma.  */
+   that follows the pragma.  LOC is the location of the #pragma.  */
 
 tree
-c_finish_omp_ordered (tree stmt)
+c_finish_omp_ordered (location_t loc, tree stmt)
 {
-  return add_stmt (build1 (OMP_ORDERED, void_type_node, stmt));
+  tree t = build1 (OMP_ORDERED, void_type_node, stmt);
+  SET_EXPR_LOCATION (t, loc);
+  return add_stmt (t);
 }
 
 
-/* Complete a #pragma omp barrier construct.  */
+/* Complete a #pragma omp barrier construct.  LOC is the location of
+   the #pragma.  */
 
 void
-c_finish_omp_barrier (void)
+c_finish_omp_barrier (location_t loc)
 {
   tree x;
 
   x = built_in_decls[BUILT_IN_GOMP_BARRIER];
   x = build_call_expr (x, 0);
+  SET_EXPR_LOCATION (x, loc);
   add_stmt (x);
 }
 
 
-/* Complete a #pragma omp taskwait construct.  */
+/* Complete a #pragma omp taskwait construct.  LOC is the location of the
+   pragma.  */
 
 void
-c_finish_omp_taskwait (void)
+c_finish_omp_taskwait (location_t loc)
 {
   tree x;
 
   x = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
   x = build_call_expr (x, 0);
+  SET_EXPR_LOCATION (x, loc);
   add_stmt (x);
 }
 
 
-/* Complete a #pragma omp atomic construct.  The expression to be 
-   implemented atomically is LHS code= RHS.  The value returned is
-   either error_mark_node (if the construct was erroneous) or an
-   OMP_ATOMIC node which should be added to the current statement tree
-   with add_stmt.  */
+/* Complete a #pragma omp atomic construct.  The expression to be
+   implemented atomically is LHS code= RHS.  LOC is the location of
+   the atomic statement.  The value returned is either error_mark_node
+   (if the construct was erroneous) or an OMP_ATOMIC node which should
+   be added to the current statement tree with add_stmt.*/
 
 tree
-c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
+c_finish_omp_atomic (location_t loc, enum tree_code code, tree lhs, tree rhs)
 {
   tree x, type, addr;
 
@@ -116,7 +125,7 @@ c_finish_omp_atomic (enum tree_code code
       && !POINTER_TYPE_P (type)
       && !SCALAR_FLOAT_TYPE_P (type))
     {
-      error ("invalid expression type for %<#pragma omp atomic%>");
+      error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
       return error_mark_node;
     }
 
@@ -124,7 +133,7 @@ c_finish_omp_atomic (enum tree_code code
 
   /* Take and save the address of the lhs.  From then on we'll reference it
      via indirection.  */
-  addr = build_unary_op (input_location, ADDR_EXPR, lhs, 0);
+  addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
   if (addr == error_mark_node)
     return error_mark_node;
   addr = save_expr (addr);
@@ -137,7 +146,7 @@ c_finish_omp_atomic (enum tree_code code
       tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
       addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
     }
-  lhs = build_indirect_ref (input_location, addr, NULL);
+  lhs = build_indirect_ref (loc, addr, NULL);
 
   /* There are lots of warnings, errors, and conversions that need to happen
      in the course of interpreting a statement.  Use the normal mechanisms
@@ -149,20 +158,24 @@ c_finish_omp_atomic (enum tree_code code
   rhs = TREE_OPERAND (x, 1);
 
   /* Punt the actual generation of atomic operations to common code.  */
-  return build2 (OMP_ATOMIC, void_type_node, addr, rhs);
+  x = build2 (OMP_ATOMIC, void_type_node, addr, rhs);
+  SET_EXPR_LOCATION (x, loc);
+  return x;
 }
 
 
-/* Complete a #pragma omp flush construct.  We don't do anything with the
-   variable list that the syntax allows.  */
+/* Complete a #pragma omp flush construct.  We don't do anything with
+   the variable list that the syntax allows.  LOC is the location of
+   the #pragma.  */
 
 void
-c_finish_omp_flush (void)
+c_finish_omp_flush (location_t loc)
 {
   tree x;
 
   x = built_in_decls[BUILT_IN_SYNCHRONIZE];
   x = build_call_expr (x, 0);
+  SET_EXPR_LOCATION (x, loc);
   add_stmt (x);
 }
 
Index: tree-inline.c
===================================================================
--- tree-inline.c	(revision 142042)
+++ tree-inline.c	(working copy)
@@ -896,7 +896,7 @@ copy_tree_body_r (tree *tp, int *walk_su
 	      STRIP_TYPE_NOPS (value);
 	      if (TREE_CONSTANT (value) || TREE_READONLY (value))
 		{
-		  *tp = build_empty_stmt ();
+		  *tp = build_empty_stmt (input_location);
 		  return copy_tree_body_r (tp, walk_subtrees, data);
 		}
 	    }
Index: c-gimplify.c
===================================================================
--- c-gimplify.c	(revision 141983)
+++ c-gimplify.c	(working copy)
@@ -140,7 +140,7 @@ add_block_to_enclosing (tree block)
      genericized.  */
 
 tree
-c_build_bind_expr (tree block, tree body)
+c_build_bind_expr (location_t loc, tree block, tree body)
 {
   tree decls, bind;
 
@@ -162,11 +162,12 @@ c_build_bind_expr (tree block, tree body
     }
 
   if (!body)
-    body = build_empty_stmt ();
+    body = build_empty_stmt (loc);
   if (decls || block)
     {
       bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
       TREE_SIDE_EFFECTS (bind) = 1;
+      SET_EXPR_LOCATION (bind, loc);
     }
   else
     bind = body;
Index: c-common.c
===================================================================
--- c-common.c	(revision 142042)
+++ c-common.c	(working copy)
@@ -3339,8 +3339,9 @@ c_common_truthvalue_conversion (location
     case ORDERED_EXPR: case UNORDERED_EXPR:
       if (TREE_TYPE (expr) == truthvalue_type_node)
 	return expr;
-      return build2 (TREE_CODE (expr), truthvalue_type_node,
+      expr = build2 (TREE_CODE (expr), truthvalue_type_node,
 		     TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
+      goto ret;
 
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
@@ -3349,18 +3350,20 @@ c_common_truthvalue_conversion (location
     case TRUTH_XOR_EXPR:
       if (TREE_TYPE (expr) == truthvalue_type_node)
 	return expr;
-      return build2 (TREE_CODE (expr), truthvalue_type_node,
-		 c_common_truthvalue_conversion (location, 
-						 TREE_OPERAND (expr, 0)),
-		 c_common_truthvalue_conversion (location,
-						 TREE_OPERAND (expr, 1)));
+      expr = build2 (TREE_CODE (expr), truthvalue_type_node,
+		     c_common_truthvalue_conversion (location, 
+						     TREE_OPERAND (expr, 0)),
+		     c_common_truthvalue_conversion (location,
+						     TREE_OPERAND (expr, 1)));
+      goto ret;
 
     case TRUTH_NOT_EXPR:
       if (TREE_TYPE (expr) == truthvalue_type_node)
 	return expr;
-      return build1 (TREE_CODE (expr), truthvalue_type_node,
-		 c_common_truthvalue_conversion (location,
-						 TREE_OPERAND (expr, 0)));
+      expr = build1 (TREE_CODE (expr), truthvalue_type_node,
+		     c_common_truthvalue_conversion (location,
+						     TREE_OPERAND (expr, 0)));
+      goto ret;
 
     case ERROR_MARK:
       return expr;
@@ -3406,8 +3409,11 @@ c_common_truthvalue_conversion (location
 	  }
 
 	if (TREE_SIDE_EFFECTS (inner))
-	  return build2 (COMPOUND_EXPR, truthvalue_type_node,
-			 inner, truthvalue_true_node);
+	  {
+	    expr = build2 (COMPOUND_EXPR, truthvalue_type_node,
+			   inner, truthvalue_true_node);
+	    goto ret;
+	  }
 	else
 	  return truthvalue_true_node;
       }
@@ -3433,22 +3439,27 @@ c_common_truthvalue_conversion (location
       /* These don't change whether an object is zero or nonzero, but
 	 we can't ignore them if their second arg has side-effects.  */
       if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
-	return build2 (COMPOUND_EXPR, truthvalue_type_node,
-		       TREE_OPERAND (expr, 1),
-		       c_common_truthvalue_conversion 
-		        (location, TREE_OPERAND (expr, 0)));
+	{
+	  expr = build2 (COMPOUND_EXPR, truthvalue_type_node,
+			 TREE_OPERAND (expr, 1),
+			 c_common_truthvalue_conversion 
+			 (location, TREE_OPERAND (expr, 0)));
+	  goto ret;
+	}
       else
 	return c_common_truthvalue_conversion (location,
 					       TREE_OPERAND (expr, 0));
 
     case COND_EXPR:
       /* Distribute the conversion into the arms of a COND_EXPR.  */
-      return fold_build3 (COND_EXPR, truthvalue_type_node,
-		TREE_OPERAND (expr, 0),
-		c_common_truthvalue_conversion (location,
-						TREE_OPERAND (expr, 1)),
-		c_common_truthvalue_conversion (location,
-						TREE_OPERAND (expr, 2)));
+      expr = fold_build3
+	(COND_EXPR, truthvalue_type_node,
+	 TREE_OPERAND (expr, 0),
+	 c_common_truthvalue_conversion (location,
+					 TREE_OPERAND (expr, 1)),
+	 c_common_truthvalue_conversion (location,
+					 TREE_OPERAND (expr, 2)));
+      goto ret;
 
     CASE_CONVERT:
       /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
@@ -3498,12 +3509,14 @@ c_common_truthvalue_conversion (location
       tree fixed_zero_node = build_fixed (TREE_TYPE (expr),
 					  FCONST0 (TYPE_MODE
 						   (TREE_TYPE (expr))));
-      return build_binary_op (EXPR_LOCATION (expr),
-			      NE_EXPR, expr, fixed_zero_node, 1);
+      return build_binary_op (location, NE_EXPR, expr, fixed_zero_node, 1);
     }
+  else
+    return build_binary_op (location, NE_EXPR, expr, integer_zero_node, 1);
 
-  return build_binary_op (EXPR_LOCATION (expr),
-			  NE_EXPR, expr, integer_zero_node, 1);
+    ret:
+  protected_set_expr_location (expr, location);
+  return expr;
 }
 
 static void def_builtin_1  (enum built_in_function fncode,
@@ -3744,13 +3757,15 @@ c_common_get_alias_set (tree t)
   return -1;
 }
 
-/* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where the
-   second parameter indicates which OPERATOR is being applied.  The COMPLAIN
-   flag controls whether we should diagnose possibly ill-formed
-   constructs or not.  */
+/* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where
+   the second parameter indicates which OPERATOR is being applied.
+   The COMPLAIN flag controls whether we should diagnose possibly
+   ill-formed constructs or not.  LOC is the location of the SIZEOF or
+   TYPEOF operator.  */
 
 tree
-c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
+c_sizeof_or_alignof_type (location_t loc,
+			  tree type, bool is_sizeof, int complain)
 {
   const char *op_name;
   tree value = NULL;
@@ -3763,7 +3778,7 @@ c_sizeof_or_alignof_type (tree type, boo
       if (is_sizeof)
 	{
 	  if (complain && (pedantic || warn_pointer_arith))
-	    pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+	    pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
 		     "invalid application of %<sizeof%> to a function type");
           else if (!complain)
             return error_mark_node;
@@ -3776,7 +3791,7 @@ c_sizeof_or_alignof_type (tree type, boo
     {
       if (type_code == VOID_TYPE
 	  && complain && (pedantic || warn_pointer_arith))
-	pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+	pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
 		 "invalid application of %qs to a void type", op_name);
       else if (!complain)
         return error_mark_node;
@@ -3785,8 +3800,8 @@ c_sizeof_or_alignof_type (tree type, boo
   else if (!COMPLETE_TYPE_P (type))
     {
       if (complain)
-	error ("invalid application of %qs to incomplete type %qT ",
-	       op_name, type);
+	error_at (loc, "invalid application of %qs to incomplete type %qT ",
+		  op_name, type);
       value = size_zero_node;
     }
   else
@@ -3813,10 +3828,11 @@ c_sizeof_or_alignof_type (tree type, boo
 /* Implement the __alignof keyword: Return the minimum required
    alignment of EXPR, measured in bytes.  For VAR_DECLs,
    FUNCTION_DECLs and FIELD_DECLs return DECL_ALIGN (which can be set
-   from an "aligned" __attribute__ specification).  */
+   from an "aligned" __attribute__ specification).  LOC is the
+   location of the ALIGNOF operator.  */
 
 tree
-c_alignof_expr (tree expr)
+c_alignof_expr (location_t loc, tree expr)
 {
   tree t;
 
@@ -3826,7 +3842,7 @@ c_alignof_expr (tree expr)
   else if (TREE_CODE (expr) == COMPONENT_REF
 	   && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1)))
     {
-      error ("%<__alignof%> applied to a bit-field");
+      error_at (loc, "%<__alignof%> applied to a bit-field");
       t = size_one_node;
     }
   else if (TREE_CODE (expr) == COMPONENT_REF
@@ -3849,10 +3865,10 @@ c_alignof_expr (tree expr)
 	  if (thisalign > bestalign)
 	    best = t, bestalign = thisalign;
 	}
-      return c_alignof (TREE_TYPE (TREE_TYPE (best)));
+      return c_alignof (loc, TREE_TYPE (TREE_TYPE (best)));
     }
   else
-    return c_alignof (TREE_TYPE (expr));
+    return c_alignof (loc, TREE_TYPE (expr));
 
   return fold_convert (size_type_node, t);
 }
@@ -4441,9 +4457,11 @@ set_compound_literal_name (tree decl)
 }
 
 tree
-build_va_arg (tree expr, tree type)
+build_va_arg (location_t loc, tree expr, tree type)
 {
-  return build1 (VA_ARG_EXPR, type, expr);
+  expr = build1 (VA_ARG_EXPR, type, expr);
+  SET_EXPR_LOCATION (expr, loc);
+  return expr;
 }
 
 
@@ -4769,7 +4787,7 @@ c_add_case_label (location_t loc, splay_
     }
 
   /* Add a CASE_LABEL to the statement-tree.  */
-  case_label = add_stmt (build_case_label (low_value, high_value, label));
+  case_label = add_stmt (build_case_label (loc, low_value, high_value, label));
   /* Register this case label in the splay tree.  */
   splay_tree_insert (cases,
 		     (splay_tree_key) low_value,
@@ -4784,7 +4802,7 @@ c_add_case_label (location_t loc, splay_
   if (!cases->root)
     {
       tree t = create_artificial_label (loc);
-      add_stmt (build_stmt (LABEL_EXPR, t));
+      add_stmt (build_stmt (loc, LABEL_EXPR, t));
     }
   return error_mark_node;
 }
Index: c-common.h
===================================================================
--- c-common.h	(revision 142042)
+++ c-common.h	(working copy)
@@ -716,8 +716,8 @@ extern tree c_build_bitfield_integer_typ
 extern bool decl_with_nonnull_addr_p (const_tree);
 extern tree c_common_truthvalue_conversion (location_t, tree);
 extern void c_apply_type_quals_to_decl (int, tree);
-extern tree c_sizeof_or_alignof_type (tree, bool, int);
-extern tree c_alignof_expr (tree);
+extern tree c_sizeof_or_alignof_type (location_t, tree, bool, int);
+extern tree c_alignof_expr (location_t, tree);
 /* Print an error message for invalid operands to arith operation CODE.
    NOP_EXPR is used as a special case (see truthvalue_conversion).  */
 extern void binary_op_error (location_t, enum tree_code, tree, tree);
@@ -734,8 +734,8 @@ extern void check_main_parameter_types (
 extern bool c_determine_visibility (tree);
 extern bool same_scalar_type_ignoring_signedness (tree, tree);
 
-#define c_sizeof(T)  c_sizeof_or_alignof_type (T, true, 1)
-#define c_alignof(T) c_sizeof_or_alignof_type (T, false, 1)
+#define c_sizeof(LOC, T)  c_sizeof_or_alignof_type (LOC, T, true, 1)
+#define c_alignof(LOC, T) c_sizeof_or_alignof_type (LOC, T, false, 1)
 
 /* Subroutine of build_binary_op, used for certain operations.  */
 extern tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise);
@@ -760,7 +760,7 @@ extern void disable_builtin_function (co
 
 extern void set_compound_literal_name (tree decl);
 
-extern tree build_va_arg (tree, tree);
+extern tree build_va_arg (location_t, tree, tree);
 
 extern unsigned int c_common_init_options (unsigned int, const char **);
 extern bool c_common_post_options (const char **);
@@ -808,8 +808,8 @@ extern void finish_file	(void);
 
 extern void emit_local_var (tree);
 extern tree do_case (location_t, tree, tree);
-extern tree build_stmt (enum tree_code, ...);
-extern tree build_case_label (tree, tree, tree);
+extern tree build_stmt (location_t, enum tree_code, ...);
+extern tree build_case_label (location_t, tree, tree, tree);
 
 /* These functions must be defined by each front-end which implements
    a variant of the C language.  They are used in c-common.c.  */
@@ -925,7 +925,7 @@ extern void warn_for_sign_compare (locat
 /* In c-gimplify.c  */
 extern void c_genericize (tree);
 extern int c_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
-extern tree c_build_bind_expr (tree, tree);
+extern tree c_build_bind_expr (location_t, tree, tree);
 
 /* In c-pch.c  */
 extern void pch_init (void);
@@ -969,7 +969,7 @@ extern void objc_declare_class (tree);
 extern void objc_declare_protocols (tree);
 extern tree objc_build_message_expr (tree);
 extern tree objc_finish_message_expr (tree, tree, tree);
-extern tree objc_build_selector_expr (tree);
+extern tree objc_build_selector_expr (location_t, tree);
 extern tree objc_build_protocol_expr (tree);
 extern tree objc_build_encode_expr (tree);
 extern tree objc_build_string_object (tree);
@@ -993,7 +993,7 @@ extern void objc_start_method_definition
 extern void objc_finish_method_definition (tree);
 extern void objc_add_instance_variable (tree);
 extern tree objc_build_keyword_decl (tree, tree, tree);
-extern tree objc_build_throw_stmt (tree);
+extern tree objc_build_throw_stmt (location_t, tree);
 extern void objc_begin_try_stmt (location_t, tree);
 extern tree objc_finish_try_stmt (void);
 extern void objc_begin_catch_clause (tree);
@@ -1017,13 +1017,13 @@ extern void pp_dir_change (cpp_reader *,
 extern bool check_missing_format_attribute (tree, tree);
 
 /* In c-omp.c  */
-extern tree c_finish_omp_master (tree);
-extern tree c_finish_omp_critical (tree, tree);
-extern tree c_finish_omp_ordered (tree);
-extern void c_finish_omp_barrier (void);
-extern tree c_finish_omp_atomic (enum tree_code, tree, tree);
-extern void c_finish_omp_flush (void);
-extern void c_finish_omp_taskwait (void);
+extern tree c_finish_omp_master (location_t, tree);
+extern tree c_finish_omp_critical (location_t, tree, tree);
+extern tree c_finish_omp_ordered (location_t, tree);
+extern void c_finish_omp_barrier (location_t);
+extern tree c_finish_omp_atomic (location_t, enum tree_code, tree, tree);
+extern void c_finish_omp_flush (location_t);
+extern void c_finish_omp_taskwait (location_t);
 extern tree c_finish_omp_for (location_t, tree, tree, tree, tree, tree, tree);
 extern void c_split_parallel_clauses (tree, tree *, tree *);
 extern enum omp_clause_default_kind c_omp_predetermined_sharing (tree);
Index: stub-objc.c
===================================================================
--- stub-objc.c	(revision 141983)
+++ stub-objc.c	(working copy)
@@ -224,7 +224,7 @@ objc_build_protocol_expr (tree ARG_UNUSE
 }
 
 tree
-objc_build_selector_expr (tree ARG_UNUSED (expr))
+objc_build_selector_expr (location_t ARG_UNUSED (loc), tree ARG_UNUSED (expr))
 {
   return 0;
 }
@@ -279,7 +279,7 @@ objc_get_class_ivars (tree ARG_UNUSED (n
 }
 
 tree
-objc_build_throw_stmt (tree ARG_UNUSED (expr))
+objc_build_throw_stmt (location_t ARG_UNUSED (loc), tree ARG_UNUSED (expr))
 {
   return 0;
 }
Index: c-parser.c
===================================================================
--- c-parser.c	(revision 142042)
+++ c-parser.c	(working copy)
@@ -1311,7 +1311,7 @@ c_parser_declaration_or_fndef (c_parser 
 	  add_stmt (fnbody);
 	  finish_function ();
 	  c_pop_function_context ();
-	  add_stmt (build_stmt (DECL_EXPR, decl));
+	  add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
 	}
       else
 	{
@@ -3153,10 +3153,11 @@ c_parser_initelt (c_parser *parser)
 		  while (c_parser_next_token_is (parser, CPP_COMMA))
 		    {
 		      struct c_expr next;
+		      location_t loc = c_parser_peek_token (parser)->location;
 		      c_parser_consume_token (parser);
 		      next = c_parser_expr_no_commas (parser, NULL);
 		      next = default_function_array_conversion (next);
-		      rec = build_compound_expr (rec, next.value);
+		      rec = build_compound_expr (loc, rec, next.value);
 		    }
 		parse_message_args:
 		  /* Now parse the objc-message-args.  */
@@ -3307,11 +3308,13 @@ static tree
 c_parser_compound_statement (c_parser *parser)
 {
   tree stmt;
+  location_t brace_loc;
   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
     return error_mark_node;
+  brace_loc = c_parser_peek_token (parser)->location;
   stmt = c_begin_compound_stmt (true);
   c_parser_compound_statement_nostart (parser);
-  return c_end_compound_stmt (stmt, true);
+  return c_end_compound_stmt (brace_loc, stmt, true);
 }
 
 /* Parse a compound statement except for the opening brace.  This is
@@ -3331,11 +3334,11 @@ c_parser_compound_statement_nostart (c_p
     }
   if (c_parser_next_token_is_keyword (parser, RID_LABEL))
     {
-      location_t err_loc = c_parser_peek_token (parser)->location;
       /* Read zero or more forward-declarations for labels that nested
 	 functions can jump to.  */
       while (c_parser_next_token_is_keyword (parser, RID_LABEL))
 	{
+	  label_loc = c_parser_peek_token (parser)->location;
 	  c_parser_consume_token (parser);
 	  /* Any identifiers, including those declared as type names,
 	     are OK here.  */
@@ -3350,7 +3353,7 @@ c_parser_compound_statement_nostart (c_p
 	      label
 		= declare_label (c_parser_peek_token (parser)->value);
 	      C_DECLARED_LABEL_FLAG (label) = 1;
-	      add_stmt (build_stmt (DECL_EXPR, label));
+	      add_stmt (build_stmt (label_loc, DECL_EXPR, label));
 	      c_parser_consume_token (parser);
 	      if (c_parser_next_token_is (parser, CPP_COMMA))
 		c_parser_consume_token (parser);
@@ -3359,7 +3362,7 @@ c_parser_compound_statement_nostart (c_p
 	    }
 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
 	}
-      pedwarn (err_loc, OPT_pedantic, "ISO C forbids label declarations");
+      pedwarn (label_loc, OPT_pedantic, "ISO C forbids label declarations");
     }
   /* We must now have at least one statement, label or declaration.  */
   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
@@ -3534,12 +3537,11 @@ c_parser_label (c_parser *parser)
       if (tlab)
 	{
 	  decl_attributes (&tlab, attrs, 0);
-	  label = add_stmt (build_stmt (LABEL_EXPR, tlab));
+	  label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
 	}
     }
   if (label)
     {
-      SET_EXPR_LOCATION (label, loc1);
       if (c_parser_next_token_starts_declspecs (parser)
 	  && !(c_parser_next_token_is (parser, CPP_NAME)
 	       && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
@@ -3721,12 +3723,13 @@ c_parser_statement_after_labels (c_parse
 	  c_parser_consume_token (parser);
 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
 	    {
-	      stmt = c_finish_return (NULL_TREE);
+	      stmt = c_finish_return (loc, NULL_TREE);
 	      c_parser_consume_token (parser);
 	    }
 	  else
 	    {
-	      stmt = c_finish_return (c_parser_expression_conv (parser).value);
+	      stmt = c_finish_return (loc,
+				      c_parser_expression_conv (parser).value);
 	      goto expect_semicolon;
 	    }
 	  break;
@@ -3738,13 +3741,14 @@ c_parser_statement_after_labels (c_parse
 	  c_parser_consume_token (parser);
 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
 	    {
-	      stmt = objc_build_throw_stmt (NULL_TREE);
+	      stmt = objc_build_throw_stmt (loc, NULL_TREE);
 	      c_parser_consume_token (parser);
 	    }
 	  else
 	    {
 	      stmt
-		= objc_build_throw_stmt (c_parser_expression (parser).value);
+		= objc_build_throw_stmt (loc,
+					 c_parser_expression (parser).value);
 	      goto expect_semicolon;
 	    }
 	  break;
@@ -3792,7 +3796,9 @@ c_parser_statement_after_labels (c_parse
      (recursively) all of the component statements should already have
      line numbers assigned.  ??? Can we discard no-op statements
      earlier?  */
-  protected_set_expr_location (stmt, loc);
+  if (CAN_HAVE_LOCATION_P (stmt)
+      && EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
+    SET_EXPR_LOCATION (stmt, loc);
 
   parser->in_if_block = in_if_block;
 }
@@ -3802,12 +3808,10 @@ c_parser_statement_after_labels (c_parse
 static tree
 c_parser_condition (c_parser *parser)
 {
-  location_t loc;
+  location_t loc = c_parser_peek_token (parser)->location;
   tree cond;
-  loc = c_parser_peek_token (parser)->location;
   cond = c_objc_common_truthvalue_conversion 
     (loc, c_parser_expression_conv (parser).value);
-  protected_set_expr_location (cond, loc);
   if (warn_sequence_point)
     verify_sequence_points (cond);
   return cond;
@@ -3835,8 +3839,9 @@ static tree
 c_parser_c99_block_statement (c_parser *parser)
 {
   tree block = c_begin_compound_stmt (flag_isoc99);
+  location_t loc = c_parser_peek_token (parser)->location;
   c_parser_statement (parser);
-  return c_end_compound_stmt (block, flag_isoc99);
+  return c_end_compound_stmt (loc, block, flag_isoc99);
 }
 
 /* Parse the body of an if statement.  This is just parsing a
@@ -3851,6 +3856,7 @@ static tree
 c_parser_if_body (c_parser *parser, bool *if_p)
 {
   tree block = c_begin_compound_stmt (flag_isoc99);
+  location_t body_loc = c_parser_peek_token (parser)->location;
   while (c_parser_next_token_is_keyword (parser, RID_CASE)
 	 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
 	 || (c_parser_next_token_is (parser, CPP_NAME)
@@ -3860,7 +3866,7 @@ c_parser_if_body (c_parser *parser, bool
   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
     {
       location_t loc = c_parser_peek_token (parser)->location;
-      add_stmt (build_empty_stmt ());
+      add_stmt (build_empty_stmt (loc));
       c_parser_consume_token (parser);
       if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
 	warning_at (loc, OPT_Wempty_body,
@@ -3870,7 +3876,7 @@ c_parser_if_body (c_parser *parser, bool
     add_stmt (c_parser_compound_statement (parser));
   else
     c_parser_statement_after_labels (parser);
-  return c_end_compound_stmt (block, flag_isoc99);
+  return c_end_compound_stmt (body_loc, block, flag_isoc99);
 }
 
 /* Parse the else body of an if statement.  This is just parsing a
@@ -3880,6 +3886,7 @@ c_parser_if_body (c_parser *parser, bool
 static tree
 c_parser_else_body (c_parser *parser)
 {
+  location_t else_loc = c_parser_peek_token (parser)->location;
   tree block = c_begin_compound_stmt (flag_isoc99);
   while (c_parser_next_token_is_keyword (parser, RID_CASE)
 	 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
@@ -3888,15 +3895,16 @@ c_parser_else_body (c_parser *parser)
     c_parser_label (parser);
   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
     {
-      warning_at (c_parser_peek_token (parser)->location,
+      location_t loc = c_parser_peek_token (parser)->location;
+      warning_at (loc,
 		  OPT_Wempty_body,
 	         "suggest braces around empty body in an %<else%> statement");
-      add_stmt (build_empty_stmt ());
+      add_stmt (build_empty_stmt (loc));
       c_parser_consume_token (parser);
     }
   else 
     c_parser_statement_after_labels (parser);
-  return c_end_compound_stmt (block, flag_isoc99);
+  return c_end_compound_stmt (else_loc, block, flag_isoc99);
 }
 
 /* Parse an if statement (C90 6.6.4, C99 6.8.4).
@@ -3933,7 +3941,7 @@ c_parser_if_statement (c_parser *parser)
   else
     second_body = NULL_TREE;
   c_finish_if_stmt (loc, cond, first_body, second_body, first_if);
-  add_stmt (c_end_compound_stmt (block, flag_isoc99));
+  add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
 }
 
 /* Parse a switch statement (C90 6.6.4, C99 6.8.4).
@@ -3946,6 +3954,7 @@ static void
 c_parser_switch_statement (c_parser *parser)
 {
   tree block, expr, body, save_break;
+  location_t switch_loc = c_parser_peek_token (parser)->location;
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
   c_parser_consume_token (parser);
   block = c_begin_compound_stmt (flag_isoc99);
@@ -3962,9 +3971,14 @@ c_parser_switch_statement (c_parser *par
   body = c_parser_c99_block_statement (parser);
   c_finish_case (body);
   if (c_break_label)
-    add_stmt (build1 (LABEL_EXPR, void_type_node, c_break_label));
+    {
+      location_t here = c_parser_peek_token (parser)->location;
+      tree t = build1 (LABEL_EXPR, void_type_node, c_break_label);
+      SET_EXPR_LOCATION (t, here);
+      add_stmt (t);
+    }
   c_break_label = save_break;
-  add_stmt (c_end_compound_stmt (block, flag_isoc99));
+  add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
 }
 
 /* Parse a while statement (C90 6.6.5, C99 6.8.5).
@@ -3989,7 +4003,7 @@ c_parser_while_statement (c_parser *pars
   c_cont_label = NULL_TREE;
   body = c_parser_c99_block_statement (parser);
   c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, true);
-  add_stmt (c_end_compound_stmt (block, flag_isoc99));
+  add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
   c_break_label = save_break;
   c_cont_label = save_cont;
 }
@@ -4027,7 +4041,7 @@ c_parser_do_statement (c_parser *parser)
   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
     c_parser_skip_to_end_of_block_or_statement (parser);
   c_finish_loop (loc, cond, NULL, body, new_break, new_cont, false);
-  add_stmt (c_end_compound_stmt (block, flag_isoc99));
+  add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
 }
 
 /* Parse a for statement (C90 6.6.5, C99 6.8.5).
@@ -4050,9 +4064,9 @@ static void
 c_parser_for_statement (c_parser *parser)
 {
   tree block, cond, incr, save_break, save_cont, body;
-  location_t loc;
+  location_t loc = c_parser_peek_token (parser)->location;
+  location_t for_paren_loc = c_parser_peek_token (parser)->location;
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
-  loc = c_parser_peek_token (parser)->location;
   c_parser_consume_token (parser);
   block = c_begin_compound_stmt (flag_isoc99);
   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
@@ -4066,7 +4080,7 @@ c_parser_for_statement (c_parser *parser
       else if (c_parser_next_token_starts_declspecs (parser))
 	{
 	  c_parser_declaration_or_fndef (parser, true, true, true, true);
-	  check_for_loop_decls ();
+	  check_for_loop_decls (for_paren_loc);
 	}
       else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
 	{
@@ -4085,7 +4099,7 @@ c_parser_for_statement (c_parser *parser
 	      c_parser_consume_token (parser);
 	      c_parser_declaration_or_fndef (parser, true, true, true, true);
 	      restore_extension_diagnostics (ext);
-	      check_for_loop_decls ();
+	      check_for_loop_decls (for_paren_loc);
 	    }
 	  else
 	    goto init_expr;
@@ -4125,7 +4139,7 @@ c_parser_for_statement (c_parser *parser
   c_cont_label = NULL_TREE;
   body = c_parser_c99_block_statement (parser);
   c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label, true);
-  add_stmt (c_end_compound_stmt (block, flag_isoc99));
+  add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
   c_break_label = save_break;
   c_cont_label = save_cont;
 }
@@ -4151,6 +4165,7 @@ c_parser_asm_statement (c_parser *parser
 {
   tree quals, str, outputs, inputs, clobbers, ret;
   bool simple;
+  location_t asm_loc = c_parser_peek_token (parser)->location;
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
   c_parser_consume_token (parser);
   if (c_parser_next_token_is_keyword (parser, RID_VOLATILE))
@@ -4240,7 +4255,7 @@ c_parser_asm_statement (c_parser *parser
     }
   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
     c_parser_skip_to_end_of_block_or_statement (parser);
-  ret = build_asm_stmt (quals, build_asm_expr (str, outputs, inputs,
+  ret = build_asm_stmt (quals, build_asm_expr (asm_loc, str, outputs, inputs,
 					       clobbers, simple));
   return ret;
 }
@@ -4477,7 +4492,8 @@ c_parser_conditional_expression (c_parse
   exp2 = c_parser_conditional_expression (parser, NULL);
   exp2 = default_function_array_conversion (exp2);
   skip_evaluation -= cond.value == truthvalue_true_node;
-  ret.value = build_conditional_expr (cond.value, exp1.value, exp2.value);
+  ret.value = build_conditional_expr (cond_loc,
+				      cond.value, exp1.value, exp2.value);
   ret.original_code = ERROR_MARK;
   return ret;
 }
@@ -4747,6 +4763,7 @@ c_parser_binary_expression (c_parser *pa
 static struct c_expr
 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
 {
+  location_t cast_loc = c_parser_peek_token (parser)->location;
   gcc_assert (!after || c_dialect_objc ());
   if (after)
     return c_parser_postfix_expression_after_primary (parser, *after);
@@ -4778,7 +4795,7 @@ c_parser_cast_expression (c_parser *pars
 							     type_name);
       expr = c_parser_cast_expression (parser, NULL);
       expr = default_function_array_conversion (expr);
-      ret.value = c_cast_expr (type_name, expr.value);
+      ret.value = c_cast_expr (cast_loc, type_name, expr.value);
       ret.original_code = ERROR_MARK;
       return ret;
     }
@@ -4825,17 +4842,16 @@ c_parser_unary_expression (c_parser *par
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
       op = default_function_array_conversion (op);
-      return parser_build_unary_op (PREINCREMENT_EXPR, op, loc);
+      return parser_build_unary_op (loc, PREINCREMENT_EXPR, op);
     case CPP_MINUS_MINUS:
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
       op = default_function_array_conversion (op);
-      return parser_build_unary_op (PREDECREMENT_EXPR, op, loc);
+      return parser_build_unary_op (loc, PREDECREMENT_EXPR, op);
     case CPP_AND:
       c_parser_consume_token (parser);
-      return parser_build_unary_op (ADDR_EXPR,
-				    c_parser_cast_expression (parser, NULL),
-				    loc);
+      return parser_build_unary_op (loc, ADDR_EXPR,
+				    c_parser_cast_expression (parser, NULL));
     case CPP_MULT:
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
@@ -4851,22 +4867,22 @@ c_parser_unary_expression (c_parser *par
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
       op = default_function_array_conversion (op);
-      return parser_build_unary_op (CONVERT_EXPR, op, loc);
+      return parser_build_unary_op (loc, CONVERT_EXPR, op);
     case CPP_MINUS:
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
       op = default_function_array_conversion (op);
-      return parser_build_unary_op (NEGATE_EXPR, op, loc);
+      return parser_build_unary_op (loc, NEGATE_EXPR, op);
     case CPP_COMPL:
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
       op = default_function_array_conversion (op);
-      return parser_build_unary_op (BIT_NOT_EXPR, op, loc);
+      return parser_build_unary_op (loc, BIT_NOT_EXPR, op);
     case CPP_NOT:
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
       op = default_function_array_conversion (op);
-      return parser_build_unary_op (TRUTH_NOT_EXPR, op, loc);
+      return parser_build_unary_op (loc, TRUTH_NOT_EXPR, op);
     case CPP_AND_AND:
       /* Refer to the address of a label as a pointer.  */
       c_parser_consume_token (parser);
@@ -4900,12 +4916,12 @@ c_parser_unary_expression (c_parser *par
 	  c_parser_consume_token (parser);
 	  op = c_parser_cast_expression (parser, NULL);
 	  op = default_function_array_conversion (op);
-	  return parser_build_unary_op (REALPART_EXPR, op, loc);
+	  return parser_build_unary_op (loc, REALPART_EXPR, op);
 	case RID_IMAGPART:
 	  c_parser_consume_token (parser);
 	  op = c_parser_cast_expression (parser, NULL);
 	  op = default_function_array_conversion (op);
-	  return parser_build_unary_op (IMAGPART_EXPR, op, loc);
+	  return parser_build_unary_op (loc, IMAGPART_EXPR, op);
 	default:
 	  return c_parser_postfix_expression (parser);
 	}
@@ -4960,7 +4976,7 @@ c_parser_sizeof_expression (c_parser *pa
 	  error_at (expr_loc,
 		    "%<[*]%> not allowed in other than a declaration");
 	}
-      return c_expr_sizeof_type (type_name);
+      return c_expr_sizeof_type (expr_loc, type_name);
     }
   else
     {
@@ -4972,7 +4988,7 @@ c_parser_sizeof_expression (c_parser *pa
       if (TREE_CODE (expr.value) == COMPONENT_REF
 	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
 	error_at (expr_loc, "%<sizeof%> applied to a bit-field");
-      return c_expr_sizeof_expr (expr);
+      return c_expr_sizeof_expr (expr_loc, expr);
     }
 }
 
@@ -4982,6 +4998,7 @@ static struct c_expr
 c_parser_alignof_expression (c_parser *parser)
 {
   struct c_expr expr;
+  location_t loc = c_parser_peek_token (parser)->location;
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
   c_parser_consume_token (parser);
   skip_evaluation++;
@@ -5014,7 +5031,7 @@ c_parser_alignof_expression (c_parser *p
       /* alignof ( type-name ).  */
       skip_evaluation--;
       in_alignof--;
-      ret.value = c_alignof (groktypename (type_name));
+      ret.value = c_alignof (loc, groktypename (type_name));
       ret.original_code = ERROR_MARK;
       return ret;
     }
@@ -5025,7 +5042,7 @@ c_parser_alignof_expression (c_parser *p
     alignof_expr:
       skip_evaluation--;
       in_alignof--;
-      ret.value = c_alignof_expr (expr.value);
+      ret.value = c_alignof_expr (loc, expr.value);
       ret.original_code = ERROR_MARK;
       return ret;
     }
@@ -5089,7 +5106,7 @@ c_parser_postfix_expression (c_parser *p
 {
   struct c_expr expr, e1, e2, e3;
   struct c_type_name *t1, *t2;
-  location_t loc;
+  location_t loc = c_parser_peek_token (parser)->location;;
   switch (c_parser_peek_token (parser)->type)
     {
     case CPP_NUMBER:
@@ -5126,11 +5143,10 @@ c_parser_postfix_expression (c_parser *p
 	}
       {
 	tree id = c_parser_peek_token (parser)->value;
-	location_t loc = c_parser_peek_token (parser)->location;
 	c_parser_consume_token (parser);
-	expr.value = build_external_ref (id,
+	expr.value = build_external_ref (loc, id,
 					 (c_parser_peek_token (parser)->type
-					  == CPP_OPEN_PAREN), loc);
+					  == CPP_OPEN_PAREN));
 	expr.original_code = ERROR_MARK;
       }
       break;
@@ -5141,12 +5157,13 @@ c_parser_postfix_expression (c_parser *p
 	{
 	  /* A statement expression.  */
 	  tree stmt;
-	  location_t here = c_parser_peek_token (parser)->location;
+	  location_t brace_loc;
 	  c_parser_consume_token (parser);
+	  brace_loc = c_parser_peek_token (parser)->location;
 	  c_parser_consume_token (parser);
 	  if (cur_stmt_list == NULL)
 	    {
-	      error_at (here, "braced-group within expression allowed "
+	      error_at (loc, "braced-group within expression allowed "
 			"only inside a function");
 	      parser->error = true;
 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
@@ -5159,9 +5176,9 @@ c_parser_postfix_expression (c_parser *p
 	  c_parser_compound_statement_nostart (parser);
 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
 				     "expected %<)%>");
-	  pedwarn (here, OPT_pedantic, 
+	  pedwarn (loc, OPT_pedantic, 
 		   "ISO C forbids braced-groups within expressions");
-	  expr.value = c_finish_stmt_expr (stmt);
+	  expr.value = c_finish_stmt_expr (brace_loc, stmt);
 	  expr.original_code = ERROR_MARK;
 	}
       else if (c_token_starts_typename (c_parser_peek_2nd_token (parser)))
@@ -5202,7 +5219,7 @@ c_parser_postfix_expression (c_parser *p
 	case RID_FUNCTION_NAME:
 	case RID_PRETTY_FUNCTION_NAME:
 	case RID_C99_FUNCTION_NAME:
-	  expr.value = fname_decl (c_parser_peek_token (parser)->location,
+	  expr.value = fname_decl (loc,
 				   c_parser_peek_token (parser)->keyword,
 				   c_parser_peek_token (parser)->value);
 	  expr.original_code = ERROR_MARK;
@@ -5234,7 +5251,7 @@ c_parser_postfix_expression (c_parser *p
 	    }
 	  else
 	    {
-	      expr.value = build_va_arg (e1.value, groktypename (t1));
+	      expr.value = build_va_arg (loc, e1.value, groktypename (t1));
 	      expr.original_code = ERROR_MARK;
 	    }
 	  break;
@@ -5266,14 +5283,17 @@ c_parser_postfix_expression (c_parser *p
 	    if (type == error_mark_node)
 	      offsetof_ref = error_mark_node;
 	    else
-	      offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
+	      {
+		offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
+		SET_EXPR_LOCATION (offsetof_ref, loc);
+	      }
 	    /* Parse the second argument to __builtin_offsetof.  We
 	       must have one identifier, and beyond that we want to
 	       accept sub structure and sub array references.  */
 	    if (c_parser_next_token_is (parser, CPP_NAME))
 	      {
 		offsetof_ref = build_component_ref
-		  (offsetof_ref, c_parser_peek_token (parser)->value);
+		  (loc, offsetof_ref, c_parser_peek_token (parser)->value);
 		c_parser_consume_token (parser);
 		while (c_parser_next_token_is (parser, CPP_DOT)
 		       || c_parser_next_token_is (parser,
@@ -5289,7 +5309,7 @@ c_parser_postfix_expression (c_parser *p
 			    break;
 			  }
 			offsetof_ref = build_component_ref
-			  (offsetof_ref,
+			  (loc, offsetof_ref,
 			   c_parser_peek_token (parser)->value);
 			c_parser_consume_token (parser);
 		      }
@@ -5301,7 +5321,7 @@ c_parser_postfix_expression (c_parser *p
 			idx = c_parser_expression (parser).value;
 			c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
 						   "expected %<]%>");
-			offsetof_ref = build_array_ref (offsetof_ref, idx, loc);
+			offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
 		      }
 		  }
 	      }
@@ -5408,7 +5428,7 @@ c_parser_postfix_expression (c_parser *p
 	    tree sel = c_parser_objc_selector_arg (parser);
 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
 				       "expected %<)%>");
-	    expr.value = objc_build_selector_expr (sel);
+	    expr.value = objc_build_selector_expr (loc, sel);
 	    expr.original_code = ERROR_MARK;
 	  }
 	  break;
@@ -5545,12 +5565,11 @@ c_parser_postfix_expression_after_primar
 	{
 	case CPP_OPEN_SQUARE:
 	  /* Array reference.  */
-	  loc = c_parser_peek_token (parser)->location;
 	  c_parser_consume_token (parser);
 	  idx = c_parser_expression (parser).value;
 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
 				     "expected %<]%>");
-	  expr.value = build_array_ref (expr.value, idx, loc);
+	  expr.value = build_array_ref (loc, expr.value, idx);
 	  expr.original_code = ERROR_MARK;
 	  break;
 	case CPP_OPEN_PAREN:
@@ -5562,6 +5581,8 @@ c_parser_postfix_expression_after_primar
 	    exprlist = c_parser_expr_list (parser, true);
 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
 				     "expected %<)%>");
+	  /* FIXME diagnostics: Ideally we want the FUNCNAME, not the
+	     "(" after the FUNCNAME, which is what we have now.    */
 	  expr.value = build_function_call (loc, expr.value, exprlist);
 	  expr.original_code = ERROR_MARK;
           if (warn_disallowed_functions)
@@ -5581,7 +5602,7 @@ c_parser_postfix_expression_after_primar
 	      return expr;
 	    }
 	  c_parser_consume_token (parser);
-	  expr.value = build_component_ref (expr.value, ident);
+	  expr.value = build_component_ref (loc, expr.value, ident);
 	  expr.original_code = ERROR_MARK;
 	  break;
 	case CPP_DEREF:
@@ -5598,7 +5619,8 @@ c_parser_postfix_expression_after_primar
 	      return expr;
 	    }
 	  c_parser_consume_token (parser);
-	  expr.value = build_component_ref (build_indirect_ref (loc,
+	  expr.value = build_component_ref (loc,
+					    build_indirect_ref (loc,
 								expr.value,
 								"->"),
 					    ident);
@@ -5641,10 +5663,11 @@ c_parser_expression (c_parser *parser)
   while (c_parser_next_token_is (parser, CPP_COMMA))
     {
       struct c_expr next;
+      location_t loc = c_parser_peek_token (parser)->location;
       c_parser_consume_token (parser);
       next = c_parser_expr_no_commas (parser, NULL);
       next = default_function_array_conversion (next);
-      expr.value = build_compound_expr (expr.value, next.value);
+      expr.value = build_compound_expr (loc, expr.value, next.value);
       expr.original_code = COMPOUND_EXPR;
     }
   return expr;
@@ -6822,8 +6845,8 @@ c_parser_omp_variable_list (c_parser *pa
       tree t = lookup_name (c_parser_peek_token (parser)->value);
 
       if (t == NULL_TREE)
-	undeclared_variable (c_parser_peek_token (parser)->value,
-			     c_parser_peek_token (parser)->location);
+	undeclared_variable (c_parser_peek_token (parser)->location,
+			     c_parser_peek_token (parser)->value);
       else if (t == error_mark_node)
 	;
       else if (kind != 0)
@@ -7399,10 +7422,12 @@ c_parser_omp_structured_block (c_parser 
    binop:
      +, *, -, /, &, ^, |, <<, >>
 
-  where x is an lvalue expression with scalar type.  */
+  where x is an lvalue expression with scalar type.  
+
+  LOC is the location of the #pragma token.  */
 
 static void
-c_parser_omp_atomic (c_parser *parser)
+c_parser_omp_atomic (location_t loc, c_parser *parser)
 {
   tree lhs, rhs;
   tree stmt;
@@ -7475,7 +7500,7 @@ c_parser_omp_atomic (c_parser *parser)
       rhs = rhs_expr.value;
       break;
     }
-  stmt = c_finish_omp_atomic (code, lhs, rhs);
+  stmt = c_finish_omp_atomic (loc, code, lhs, rhs);
   if (stmt != error_mark_node)
     add_stmt (stmt);
   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
@@ -7489,19 +7514,21 @@ c_parser_omp_atomic (c_parser *parser)
 static void
 c_parser_omp_barrier (c_parser *parser)
 {
+  location_t loc = c_parser_peek_token (parser)->location;
   c_parser_consume_pragma (parser);
   c_parser_skip_to_pragma_eol (parser);
 
-  c_finish_omp_barrier ();
+  c_finish_omp_barrier (loc);
 }
 
 /* OpenMP 2.5:
    # pragma omp critical [(name)] new-line
      structured-block
-*/
+
+  LOC is the location of the #pragma itself.  */
 
 static tree
-c_parser_omp_critical (c_parser *parser)
+c_parser_omp_critical (location_t loc, c_parser *parser)
 {
   tree stmt, name = NULL;
 
@@ -7522,7 +7549,7 @@ c_parser_omp_critical (c_parser *parser)
   c_parser_skip_to_pragma_eol (parser);
 
   stmt = c_parser_omp_structured_block (parser);
-  return c_finish_omp_critical (stmt, name);
+  return c_finish_omp_critical (loc, stmt, name);
 }
 
 /* OpenMP 2.5:
@@ -7534,6 +7561,7 @@ c_parser_omp_critical (c_parser *parser)
 static void
 c_parser_omp_flush (c_parser *parser)
 {
+  location_t loc = c_parser_peek_token (parser)->location;
   c_parser_consume_pragma (parser);
   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
     c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
@@ -7541,19 +7569,20 @@ c_parser_omp_flush (c_parser *parser)
     c_parser_error (parser, "expected %<(%> or end of line");
   c_parser_skip_to_pragma_eol (parser);
 
-  c_finish_omp_flush ();
+  c_finish_omp_flush (loc);
 }
 
 /* Parse the restricted form of the for statement allowed by OpenMP.
    The real trick here is to determine the loop control variable early
-   so that we can push a new decl if necessary to make it private.  */
+   so that we can push a new decl if necessary to make it private.
+   LOC is the location of the OMP in "#pragma omp".  */
 
 static tree
-c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
+c_parser_omp_for_loop (location_t loc,
+		       c_parser *parser, tree clauses, tree *par_clauses)
 {
   tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
   tree declv, condv, incrv, initv, for_block = NULL, ret = NULL;
-  location_t loc;
   bool fail = false, open_brace_parsed = false;
   int i, collapse = 1, nbraces = 0;
 
@@ -7573,12 +7602,12 @@ c_parser_omp_for_loop (c_parser *parser,
       c_parser_error (parser, "for statement expected");
       return NULL;
     }
-  loc = c_parser_peek_token (parser)->location;
   c_parser_consume_token (parser);
 
   for (i = 0; i < collapse; i++)
     {
       int bracecount = 0;
+      location_t for_paren_loc = c_parser_peek_token (parser)->location;
 
       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
 	goto pop_scopes;
@@ -7590,7 +7619,7 @@ c_parser_omp_for_loop (c_parser *parser,
 	    for_block
 	      = tree_cons (NULL, c_begin_compound_stmt (true), for_block);
 	  c_parser_declaration_or_fndef (parser, true, true, true, true);
-	  decl = check_for_loop_decls ();
+	  decl = check_for_loop_decls (for_paren_loc);
 	  if (decl == NULL)
 	    goto error_init;
 	  if (DECL_INITIAL (decl) == error_mark_node)
@@ -7635,7 +7664,6 @@ c_parser_omp_for_loop (c_parser *parser,
 
 	  cond = c_parser_expression_conv (parser).value;
 	  cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
-	  protected_set_expr_location (cond, cond_loc);
 	}
       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
 
@@ -7709,14 +7737,19 @@ c_parser_omp_for_loop (c_parser *parser,
 
   if (open_brace_parsed)
     {
+      location_t here = c_parser_peek_token (parser)->location;
       stmt = c_begin_compound_stmt (true);
       c_parser_compound_statement_nostart (parser);
-      add_stmt (c_end_compound_stmt (stmt, true));
+      add_stmt (c_end_compound_stmt (here, stmt, true));
     }
   else
     add_stmt (c_parser_c99_block_statement (parser));
   if (c_cont_label)
-    add_stmt (build1 (LABEL_EXPR, void_type_node, c_cont_label));
+    {
+      tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label);
+      SET_EXPR_LOCATION (t, loc);
+      add_stmt (t);
+    }
 
   body = pop_stmt_list (body);
   c_break_label = save_break;
@@ -7736,10 +7769,11 @@ c_parser_omp_for_loop (c_parser *parser,
 	  c_parser_error (parser, "collapsed loops not perfectly nested");
 	  while (nbraces)
 	    {
+	      location_t here = c_parser_peek_token (parser)->location;
 	      stmt = c_begin_compound_stmt (true);
 	      add_stmt (body);
 	      c_parser_compound_statement_nostart (parser);
-	      body = c_end_compound_stmt (stmt, true);
+	      body = c_end_compound_stmt (here, stmt, true);
 	      nbraces--;
 	    }
 	  goto pop_scopes;
@@ -7794,7 +7828,10 @@ c_parser_omp_for_loop (c_parser *parser,
 pop_scopes:
   while (for_block)
     {
-      stmt = c_end_compound_stmt (TREE_VALUE (for_block), true);
+      /* FIXME diagnostics: LOC below should be the actual location of
+	 this particular for block.  We need to build a list of
+	 locations to go along with FOR_BLOCK.  */
+      stmt = c_end_compound_stmt (loc, TREE_VALUE (for_block), true);
       add_stmt (stmt);
       for_block = TREE_CHAIN (for_block);
     }
@@ -7804,6 +7841,8 @@ pop_scopes:
 /* OpenMP 2.5:
    #pragma omp for for-clause[optseq] new-line
      for-loop
+
+   LOC is the location of the #pragma token.
 */
 
 #define OMP_FOR_CLAUSE_MASK				\
@@ -7817,7 +7856,7 @@ pop_scopes:
 	| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
 
 static tree
-c_parser_omp_for (c_parser *parser)
+c_parser_omp_for (location_t loc, c_parser *parser)
 {
   tree block, clauses, ret;
 
@@ -7825,8 +7864,8 @@ c_parser_omp_for (c_parser *parser)
 				      "#pragma omp for");
 
   block = c_begin_compound_stmt (true);
-  ret = c_parser_omp_for_loop (parser, clauses, NULL);
-  block = c_end_compound_stmt (block, true);
+  ret = c_parser_omp_for_loop (loc, parser, clauses, NULL);
+  block = c_end_compound_stmt (loc, block, true);
   add_stmt (block);
 
   return ret;
@@ -7835,25 +7874,29 @@ c_parser_omp_for (c_parser *parser)
 /* OpenMP 2.5:
    # pragma omp master new-line
      structured-block
+
+   LOC is the location of the #pragma token.
 */
 
 static tree
-c_parser_omp_master (c_parser *parser)
+c_parser_omp_master (location_t loc, c_parser *parser)
 {
   c_parser_skip_to_pragma_eol (parser);
-  return c_finish_omp_master (c_parser_omp_structured_block (parser));
+  return c_finish_omp_master (loc, c_parser_omp_structured_block (parser));
 }
 
 /* OpenMP 2.5:
    # pragma omp ordered new-line
      structured-block
+
+   LOC is the location of the #pragma itself.
 */
 
 static tree
-c_parser_omp_ordered (c_parser *parser)
+c_parser_omp_ordered (location_t loc, c_parser *parser)
 {
   c_parser_skip_to_pragma_eol (parser);
-  return c_finish_omp_ordered (c_parser_omp_structured_block (parser));
+  return c_finish_omp_ordered (loc, c_parser_omp_structured_block (parser));
 }
 
 /* OpenMP 2.5:
@@ -7863,15 +7906,18 @@ c_parser_omp_ordered (c_parser *parser)
 
    section-sequence:
      section-directive[opt] structured-block
-     section-sequence section-directive structured-block  */
+     section-sequence section-directive structured-block  
+
+    SECTIONS_LOC is the location of the #pragma omp sections.  */
 
 static tree
-c_parser_omp_sections_scope (c_parser *parser)
+c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
 {
   tree stmt, substmt;
   bool error_suppress = false;
   location_t loc;
 
+  loc = c_parser_peek_token (parser)->location;
   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
     {
       /* Avoid skipping until the end of the block.  */
@@ -7881,7 +7927,6 @@ c_parser_omp_sections_scope (c_parser *p
 
   stmt = push_stmt_list ();
 
-  loc = c_parser_peek_token (parser)->location;
   if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
     {
       substmt = push_stmt_list ();
@@ -7935,6 +7980,7 @@ c_parser_omp_sections_scope (c_parser *p
   substmt = pop_stmt_list (stmt);
 
   stmt = make_node (OMP_SECTIONS);
+  SET_EXPR_LOCATION (stmt, sections_loc);
   TREE_TYPE (stmt) = void_type_node;
   OMP_SECTIONS_BODY (stmt) = substmt;
 
@@ -7944,6 +7990,8 @@ c_parser_omp_sections_scope (c_parser *p
 /* OpenMP 2.5:
    # pragma omp sections sections-clause[optseq] newline
      sections-scope
+
+   LOC is the location of the #pragma token.
 */
 
 #define OMP_SECTIONS_CLAUSE_MASK			\
@@ -7954,7 +8002,7 @@ c_parser_omp_sections_scope (c_parser *p
 	| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
 
 static tree
-c_parser_omp_sections (c_parser *parser)
+c_parser_omp_sections (location_t loc, c_parser *parser)
 {
   tree block, clauses, ret;
 
@@ -7962,10 +8010,10 @@ c_parser_omp_sections (c_parser *parser)
 				      "#pragma omp sections");
 
   block = c_begin_compound_stmt (true);
-  ret = c_parser_omp_sections_scope (parser);
+  ret = c_parser_omp_sections_scope (loc, parser);
   if (ret)
     OMP_SECTIONS_CLAUSES (ret) = clauses;
-  block = c_end_compound_stmt (block, true);
+  block = c_end_compound_stmt (loc, block, true);
   add_stmt (block);
 
   return ret;
@@ -7975,6 +8023,8 @@ c_parser_omp_sections (c_parser *parser)
    # pragma parallel parallel-clause new-line
    # pragma parallel for parallel-for-clause new-line
    # pragma parallel sections parallel-sections-clause new-line
+
+   LOC is the location of the #pragma token.
 */
 
 #define OMP_PARALLEL_CLAUSE_MASK			\
@@ -7988,7 +8038,7 @@ c_parser_omp_sections (c_parser *parser)
 	| (1u << PRAGMA_OMP_CLAUSE_NUM_THREADS))
 
 static tree
-c_parser_omp_parallel (c_parser *parser)
+c_parser_omp_parallel (location_t loc, c_parser *parser)
 {
   enum pragma_kind p_kind = PRAGMA_OMP_PARALLEL;
   const char *p_name = "#pragma omp parallel";
@@ -8023,24 +8073,24 @@ c_parser_omp_parallel (c_parser *parser)
     case PRAGMA_OMP_PARALLEL:
       block = c_begin_omp_parallel ();
       c_parser_statement (parser);
-      stmt = c_finish_omp_parallel (clauses, block);
+      stmt = c_finish_omp_parallel (loc, clauses, block);
       break;
 
     case PRAGMA_OMP_PARALLEL_FOR:
       block = c_begin_omp_parallel ();
       c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
-      c_parser_omp_for_loop (parser, ws_clause, &par_clause);
-      stmt = c_finish_omp_parallel (par_clause, block);
+      c_parser_omp_for_loop (loc, parser, ws_clause, &par_clause);
+      stmt = c_finish_omp_parallel (loc, par_clause, block);
       OMP_PARALLEL_COMBINED (stmt) = 1;
       break;
 
     case PRAGMA_OMP_PARALLEL_SECTIONS:
       block = c_begin_omp_parallel ();
       c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
-      stmt = c_parser_omp_sections_scope (parser);
+      stmt = c_parser_omp_sections_scope (loc, parser);
       if (stmt)
 	OMP_SECTIONS_CLAUSES (stmt) = ws_clause;
-      stmt = c_finish_omp_parallel (par_clause, block);
+      stmt = c_finish_omp_parallel (loc, par_clause, block);
       OMP_PARALLEL_COMBINED (stmt) = 1;
       break;
 
@@ -8054,6 +8104,8 @@ c_parser_omp_parallel (c_parser *parser)
 /* OpenMP 2.5:
    # pragma omp single single-clause[optseq] new-line
      structured-block
+
+   LOC is the location of the #pragma.
 */
 
 #define OMP_SINGLE_CLAUSE_MASK				\
@@ -8063,9 +8115,10 @@ c_parser_omp_parallel (c_parser *parser)
 	| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
 
 static tree
-c_parser_omp_single (c_parser *parser)
+c_parser_omp_single (location_t loc, c_parser *parser)
 {
   tree stmt = make_node (OMP_SINGLE);
+  SET_EXPR_LOCATION (stmt, loc);
   TREE_TYPE (stmt) = void_type_node;
 
   OMP_SINGLE_CLAUSES (stmt)
@@ -8078,6 +8131,8 @@ c_parser_omp_single (c_parser *parser)
 
 /* OpenMP 3.0:
    # pragma omp task task-clause[optseq] new-line
+
+   LOC is the location of the #pragma.
 */
 
 #define OMP_TASK_CLAUSE_MASK				\
@@ -8089,7 +8144,7 @@ c_parser_omp_single (c_parser *parser)
 	| (1u << PRAGMA_OMP_CLAUSE_SHARED))
 
 static tree
-c_parser_omp_task (c_parser *parser)
+c_parser_omp_task (location_t loc, c_parser *parser)
 {
   tree clauses, block;
 
@@ -8098,7 +8153,7 @@ c_parser_omp_task (c_parser *parser)
 
   block = c_begin_omp_task ();
   c_parser_statement (parser);
-  return c_finish_omp_task (clauses, block);
+  return c_finish_omp_task (loc, clauses, block);
 }
 
 /* OpenMP 3.0:
@@ -8108,10 +8163,11 @@ c_parser_omp_task (c_parser *parser)
 static void
 c_parser_omp_taskwait (c_parser *parser)
 {
+  location_t loc = c_parser_peek_token (parser)->location;
   c_parser_consume_pragma (parser);
   c_parser_skip_to_pragma_eol (parser);
 
-  c_finish_omp_taskwait ();
+  c_finish_omp_taskwait (loc);
 }
 
 /* Main entry point to parsing most OpenMP pragmas.  */
@@ -8136,38 +8192,38 @@ c_parser_omp_construct (c_parser *parser
   switch (p_kind)
     {
     case PRAGMA_OMP_ATOMIC:
-      c_parser_omp_atomic (parser);
+      c_parser_omp_atomic (loc, parser);
       return;
     case PRAGMA_OMP_CRITICAL:
-      stmt = c_parser_omp_critical (parser);
+      stmt = c_parser_omp_critical (loc, parser);
       break;
     case PRAGMA_OMP_FOR:
-      stmt = c_parser_omp_for (parser);
+      stmt = c_parser_omp_for (loc, parser);
       break;
     case PRAGMA_OMP_MASTER:
-      stmt = c_parser_omp_master (parser);
+      stmt = c_parser_omp_master (loc, parser);
       break;
     case PRAGMA_OMP_ORDERED:
-      stmt = c_parser_omp_ordered (parser);
+      stmt = c_parser_omp_ordered (loc, parser);
       break;
     case PRAGMA_OMP_PARALLEL:
-      stmt = c_parser_omp_parallel (parser);
+      stmt = c_parser_omp_parallel (loc, parser);
       break;
     case PRAGMA_OMP_SECTIONS:
-      stmt = c_parser_omp_sections (parser);
+      stmt = c_parser_omp_sections (loc, parser);
       break;
     case PRAGMA_OMP_SINGLE:
-      stmt = c_parser_omp_single (parser);
+      stmt = c_parser_omp_single (loc, parser);
       break;
     case PRAGMA_OMP_TASK:
-      stmt = c_parser_omp_task (parser);
+      stmt = c_parser_omp_task (loc, parser);
       break;
     default:
       gcc_unreachable ();
     }
 
   if (stmt)
-    SET_EXPR_LOCATION (stmt, loc);
+    gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
 }
 
 
@@ -8178,8 +8234,10 @@ static void
 c_parser_omp_threadprivate (c_parser *parser)
 {
   tree vars, t;
+  location_t loc;
 
   c_parser_consume_pragma (parser);
+  loc = c_parser_peek_token (parser)->location;
   vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
 
   /* Mark every variable in VARS to be assigned thread local storage.  */
@@ -8187,18 +8245,24 @@ c_parser_omp_threadprivate (c_parser *pa
     {
       tree v = TREE_PURPOSE (t);
 
+      /* FIXME diagnostics: Ideally we should keep individual
+	 locations for all the variables in the var list to make the
+	 following errors more precise.  Perhaps
+	 c_parser_omp_var_list_parens() should construct a list of
+	 locations to go along with the var list.  */
+
       /* If V had already been marked threadprivate, it doesn't matter
 	 whether it had been used prior to this point.  */
       if (TREE_CODE (v) != VAR_DECL)
-	error ("%qD is not a variable", v);
+	error_at (loc, "%qD is not a variable", v);
       else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
-	error ("%qE declared %<threadprivate%> after first use", v);
+	error_at (loc, "%qE declared %<threadprivate%> after first use", v);
       else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
-	error ("automatic variable %qE cannot be %<threadprivate%>", v);
+	error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
       else if (TREE_TYPE (v) == error_mark_node)
 	;
       else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
-	error ("%<threadprivate%> %qE has incomplete type", v);
+	error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
       else
 	{
 	  if (! DECL_THREAD_LOCAL_P (v))



More information about the Gcc-patches mailing list