diff mbox

[1/2] RFC: C++: attempt to provide location_t in more places

Message ID 1448484660-7094-2-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm Nov. 25, 2015, 8:50 p.m. UTC
This patch avoids the need for calls to protected_set_expr_location
in the followup patch by adding location_t params to the following
functions:
  - build_new
  - cp_build_indirect_ref
  - cp_build_unary_op
  - cp_build_c_cast
  - cp_build_modify_expr

It's not clear to me whether I should be passing in UNKNOWN_LOCATION
or input_location to the various functions.

cp_build_unary_op used input_location in various places internally,
so I've passed that in wherever there isn't a better value.

Bootstraps (on x86_64-pc-linux-gnu), but regresses some tests, due to
changes in locations at which diagnostics are emitted:

  c-c++-common/cilk-plus/CK/cilk_for_errors.c
  c-c++-common/cilk-plus/PS/for1.c
  c-c++-common/gomp/pr59073.c
  g++.dg/cpp0x/nsdmi-template14.C
  g++.dg/gomp/for-1.C
  g++.dg/gomp/pr39495-2.C
  g++.dg/init/new38.C
  g++.dg/warn/Wconversion-real-integer2.C
  g++.dg/warn/pr35635.C

Is the overall idea sound?
Would this be better split up into separate patches by function?

Partial ChangeLog follows

gcc/cp/ChangeLog:
	* call.c (build_new_op_1): Pass "loc" to calls to
	cp_build_modify_expr, cp_build_indirect_ref, cp_build_unary_op.
	(build_over_call): Pass UNKNOWN_LOCATION to calls to
	cp_build_indirect_ref.
	(build_java_interface_fn_ref): Likewise.
	* class.c (build_base_path): Likewise, though it appears I used
	input_location in one place.
	(build_simple_base_path): Likewise.
	(build_vfn_ref): Likewise.
	* cp-tree.h (build_new): Add location_t param.
	(cp_build_indirect_ref): Likewise.
	(cp_build_unary_op): Likewise.
	(cp_build_c_cast): Likewise.
	(cp_build_modify_expr): Likewise.
	(build_address_loc): New decl.
	(build_nop_loc): New decl.
	* decl.c (start_preparsed_function): Pass UNKNOWN_LOCATION to call
	to cp_build_indirect_ref.
	* decl2.c (set_guard): Pass input_location to call to
	cp_build_modify_expr.
	(one_static_initialization_or_destruction): Likewise for calls to
	cp_build_unary_op.
	(handle_tls_init): Likewise for calls to cp_build_unary_op and
	cp_build_modify_expr.
	* except.c (expand_start_catch_block): Likewise for call to
	build_indirect_ref.
	(build_throw): Likewise.
	* init.c (perform_member_init): Likewise for call to
	cp_build_modify_expr.
	(emit_mem_initializers): Pass UNKNOWN_LOCATION to call to
	cp_build_indirect_ref.
	(expand_virtual_init): Likewise for two calls; pass input_location
	to call to cp_build_modify_expr.
	(build_raw_new_expr): Add location_t param "loc", use it to change
	a build4 to a build4_loc.
	(build_new_1): Pass input_location to three calls to
	cp_build_indirect_ref, UNKNOWN_LOCATION to two others.
	(build_new): Add location_t param "loc"; pass it to calls to
	build_raw_new_expr, and to change a build1 to a build1_loc.
	[...etc...]
---
 gcc/cp/call.c      |  28 ++++---
 gcc/cp/class.c     |  19 +++--
 gcc/cp/cp-tree.h   |  19 +++--
 gcc/cp/decl.c      |   3 +-
 gcc/cp/decl2.c     |  13 +--
 gcc/cp/except.c    |   6 +-
 gcc/cp/init.c      |  99 ++++++++++++----------
 gcc/cp/method.c    |   4 +-
 gcc/cp/parser.c    |  17 ++--
 gcc/cp/pt.c        |   5 +-
 gcc/cp/rtti.c      |  11 +--
 gcc/cp/semantics.c |  11 ++-
 gcc/cp/tree.c      |   6 +-
 gcc/cp/typeck.c    | 238 +++++++++++++++++++++++++++++++----------------------
 gcc/cp/typeck2.c   |  10 ++-
 15 files changed, 287 insertions(+), 202 deletions(-)

Comments

Jason Merrill Nov. 25, 2015, 9:26 p.m. UTC | #1
> It's not clear to me whether I should be passing in UNKNOWN_LOCATION
> or input_location to the various functions.
>
> cp_build_unary_op used input_location in various places internally,
> so I've passed that in wherever there isn't a better value.

Rather than try to get this right now I'm inclined to save it for the 
next stage 1 and go back to protected_set_expr_location for GCC 6.

> Bootstraps (on x86_64-pc-linux-gnu), but regresses some tests, due to
> changes in locations at which diagnostics are emitted:
>
>   c-c++-common/cilk-plus/CK/cilk_for_errors.c
>   c-c++-common/cilk-plus/PS/for1.c
>   c-c++-common/gomp/pr59073.c
>   g++.dg/cpp0x/nsdmi-template14.C
>   g++.dg/gomp/for-1.C
>   g++.dg/gomp/pr39495-2.C
>   g++.dg/init/new38.C
>   g++.dg/warn/Wconversion-real-integer2.C
>   g++.dg/warn/pr35635.C

Are the changes good or bad?

Jason
David Malcolm Dec. 3, 2015, 2:55 p.m. UTC | #2
On Wed, 2015-11-25 at 16:26 -0500, Jason Merrill wrote:
> > It's not clear to me whether I should be passing in UNKNOWN_LOCATION
> > or input_location to the various functions.
> >
> > cp_build_unary_op used input_location in various places internally,
> > so I've passed that in wherever there isn't a better value.
> 
> Rather than try to get this right now I'm inclined to save it for the 
> next stage 1 and go back to protected_set_expr_location for GCC 6.

Thanks; I've reworked the patch based on that idea.  I found whilst
bugfixing that in general it was better to use
cp_expr::set_location, which calls protected_set_expr_location,
since the former sets both the location in the tree node (if any)
*and* the shadow copy in the cp_expr (thus ensuring that compound
expressions use the correct location_t).

I've also done a lot of bugfixing, and rebased
from r230562 (Nov 18th) to r231208 (Dec 2nd).

> > Bootstraps (on x86_64-pc-linux-gnu), but regresses some tests, due to
> > changes in locations at which diagnostics are emitted:
> >
> >   c-c++-common/cilk-plus/CK/cilk_for_errors.c
> >   c-c++-common/cilk-plus/PS/for1.c
> >   c-c++-common/gomp/pr59073.c
> >   g++.dg/cpp0x/nsdmi-template14.C
> >   g++.dg/gomp/for-1.C
> >   g++.dg/gomp/pr39495-2.C
> >   g++.dg/init/new38.C
> >   g++.dg/warn/Wconversion-real-integer2.C
> >   g++.dg/warn/pr35635.C
> 
> Are the changes good or bad?

Some were bad, which I've fixed in the code.  Others were
improvements, requiring tweaks/movement of dg- directives.
I've broken out any such changes I needed to make to
specific test cases as separate patches in the kit, with notes
on each, in the hope it will make review easier.  (The kit would be
applied as a single commit; I've been testing it as one).

The following 10-patch kit bootstraps&regrtests successfully on
x86_64-pc-linux-gnu.

It adds 213 new PASS results to g++.sum, and changes the location
of 154 PASS results there.

It adds 16 new PASS results to obj-c++.sum.

OK for trunk for gcc 6?


David Malcolm (10):
  C++ FE: expression ranges v4
  Fix g++.dg/cpp0x/nsdmi-template14.C
  Fix g++.dg/gomp/loop-1.C
  Fix g++.dg/template/crash55.C
  Fix location of dg-error within g++.dg/template/pr64100.C
  Fix g++.dg/template/pseudodtor3.C
  Fix g++.dg/template/ref3.C
  Fix g++.dg/ubsan/pr63956.C
  Fix g++.dg/warn/pr35635.C
  Fix g++.dg/warn/Wconversion-real-integer2.C

 gcc/convert.c                                      |   9 +-
 gcc/cp/cp-tree.h                                   |  86 ++-
 gcc/cp/cvt.c                                       |   4 +-
 gcc/cp/name-lookup.c                               |   6 +-
 gcc/cp/name-lookup.h                               |   2 +-
 gcc/cp/parser.c                                    | 576 +++++++++++----
 gcc/cp/semantics.c                                 |  53 +-
 gcc/cp/typeck.c                                    |  42 +-
 gcc/testsuite/g++.dg/cpp0x/nsdmi-template14.C      |   4 +-
 gcc/testsuite/g++.dg/gomp/loop-1.C                 |  32 +-
 .../g++.dg/plugin/diagnostic-test-expressions-1.C  | 775 +++++++++++++++++++++
 gcc/testsuite/g++.dg/plugin/plugin.exp             |   5 +-
 gcc/testsuite/g++.dg/template/crash55.C            |   3 +-
 gcc/testsuite/g++.dg/template/pr64100.C            |   4 +-
 gcc/testsuite/g++.dg/template/pseudodtor3.C        |   4 +-
 gcc/testsuite/g++.dg/template/ref3.C               |   6 +-
 gcc/testsuite/g++.dg/ubsan/pr63956.C               |  28 +-
 .../g++.dg/warn/Wconversion-real-integer2.C        |   4 +-
 gcc/testsuite/g++.dg/warn/pr35635.C                |   6 +-
 .../plugin/diagnostic-test-expressions-1.mm        |  94 +++
 gcc/testsuite/obj-c++.dg/plugin/plugin.exp         |  90 +++
 gcc/tree.c                                         |  25 +-
 gcc/tree.h                                         |  17 +-
 23 files changed, 1632 insertions(+), 243 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C
 create mode 100644 gcc/testsuite/obj-c++.dg/plugin/diagnostic-test-expressions-1.mm
 create mode 100644 gcc/testsuite/obj-c++.dg/plugin/plugin.exp
diff mbox

Patch

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 8cdda62..435ac7a 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5715,10 +5715,10 @@  build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
   switch (code)
     {
     case MODIFY_EXPR:
-      return cp_build_modify_expr (arg1, code2, arg2, complain);
+      return cp_build_modify_expr (loc, arg1, code2, arg2, complain);
 
     case INDIRECT_REF:
-      return cp_build_indirect_ref (arg1, RO_UNARY_STAR, complain);
+      return cp_build_indirect_ref (loc, arg1, RO_UNARY_STAR, complain);
 
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
@@ -5768,14 +5768,15 @@  build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
     case REALPART_EXPR:
     case IMAGPART_EXPR:
     case ABS_EXPR:
-      return cp_build_unary_op (code, arg1, candidates != 0, complain);
+      return cp_build_unary_op (loc, code, arg1, candidates != 0, complain);
 
     case ARRAY_REF:
       return cp_build_array_ref (input_location, arg1, arg2, complain);
 
     case MEMBER_REF:
-      return build_m_component_ref (cp_build_indirect_ref (arg1, RO_ARROW_STAR, 
-                                                           complain), 
+      return build_m_component_ref (cp_build_indirect_ref (loc, arg1,
+							   RO_ARROW_STAR,
+                                                           complain),
                                     arg2, complain);
 
       /* The caller will deal with these.  */
@@ -7551,7 +7552,7 @@  build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       if (targ)
 	arg = targ;
       else
-	arg = cp_build_indirect_ref (arg, RO_NULL, complain);
+	arg = cp_build_indirect_ref (UNKNOWN_LOCATION, arg, RO_NULL, complain);
 
       /* [class.copy]: the copy constructor is implicitly defined even if
 	 the implementation elided its use.  */
@@ -7579,8 +7580,10 @@  build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 	       || (TREE_CODE (arg) == TARGET_EXPR
 		   && !unsafe_copy_elision_p (fa, arg)))
 	{
-	  tree to = stabilize_reference (cp_build_indirect_ref (fa, RO_NULL,
-								complain));
+	  tree to
+	    = stabilize_reference (cp_build_indirect_ref (UNKNOWN_LOCATION,
+							  fa, RO_NULL,
+							  complain));
 
 	  val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
 	  return val;
@@ -7591,7 +7594,8 @@  build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 	   && !DECL_DELETED_FN (fn))
     {
       tree to = stabilize_reference
-	(cp_build_indirect_ref (argarray[0], RO_NULL, complain));
+	(cp_build_indirect_ref (UNKNOWN_LOCATION, argarray[0], RO_NULL,
+				complain));
       tree type = TREE_TYPE (to);
       tree as_base = CLASSTYPE_AS_BASE (type);
       tree arg = argarray[1];
@@ -7606,7 +7610,8 @@  build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 	}
       else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
 	{
-	  arg = cp_build_indirect_ref (arg, RO_NULL, complain);
+	  arg = cp_build_indirect_ref (UNKNOWN_LOCATION, arg, RO_NULL,
+				       complain);
 	  val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
 	}
       else
@@ -7805,7 +7810,8 @@  build_java_interface_fn_ref (tree fn, tree instance)
 
   /* Look up the pointer to the runtime java.lang.Class object for `instance'.
      This is the first entry in the vtable.  */
-  klass_ref = build_vtbl_ref (cp_build_indirect_ref (instance, RO_NULL, 
+  klass_ref = build_vtbl_ref (cp_build_indirect_ref (UNKNOWN_LOCATION,
+						     instance, RO_NULL,
                                                      tf_warning_or_error),
 			      integer_zero_node);
 
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 216a301..b9728e5 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -395,7 +395,7 @@  build_base_path (enum tree_code code,
 	 interesting to the optimizers anyway.  */
       && !has_empty)
     {
-      expr = cp_build_indirect_ref (expr, RO_NULL, complain);
+      expr = cp_build_indirect_ref (UNKNOWN_LOCATION, expr, RO_NULL, complain);
       expr = build_simple_base_path (expr, binfo);
       if (rvalue)
 	expr = move (expr);
@@ -422,7 +422,8 @@  build_base_path (enum tree_code code,
 	  t = TREE_TYPE (TYPE_VFIELD (current_class_type));
 	  t = build_pointer_type (t);
 	  v_offset = fold_convert (t, current_vtt_parm);
-	  v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
+	  v_offset = cp_build_indirect_ref (UNKNOWN_LOCATION, v_offset, RO_NULL,
+					    complain);
 	}
       else
 	{
@@ -434,7 +435,8 @@  build_base_path (enum tree_code code,
 	      if (t == NULL_TREE)
 		t = expr;
 	    }
-	  v_offset = build_vfield_ref (cp_build_indirect_ref (t, RO_NULL,
+	  v_offset = build_vfield_ref (cp_build_indirect_ref (input_location,
+							      t, RO_NULL,
 							      complain),
 	  TREE_TYPE (TREE_TYPE (expr)));
 	}
@@ -446,7 +448,8 @@  build_base_path (enum tree_code code,
       v_offset = build1 (NOP_EXPR,
 			 build_pointer_type (ptrdiff_type_node),
 			 v_offset);
-      v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
+      v_offset = cp_build_indirect_ref (UNKNOWN_LOCATION, v_offset, RO_NULL,
+					complain);
       TREE_CONSTANT (v_offset) = 1;
 
       offset = convert_to_integer (ptrdiff_type_node,
@@ -488,7 +491,7 @@  build_base_path (enum tree_code code,
  indout:
   if (!want_pointer)
     {
-      expr = cp_build_indirect_ref (expr, RO_NULL, complain);
+      expr = cp_build_indirect_ref (UNKNOWN_LOCATION, expr, RO_NULL, complain);
       if (rvalue)
 	expr = move (expr);
     }
@@ -524,7 +527,8 @@  build_simple_base_path (tree expr, tree binfo)
 	 in the back end.  */
       temp = unary_complex_lvalue (ADDR_EXPR, expr);
       if (temp)
-	expr = cp_build_indirect_ref (temp, RO_NULL, tf_warning_or_error);
+	expr = cp_build_indirect_ref (UNKNOWN_LOCATION, temp, RO_NULL,
+				      tf_warning_or_error);
 
       return expr;
     }
@@ -717,7 +721,8 @@  build_vfn_ref (tree instance_ptr, tree idx)
 {
   tree aref;
 
-  aref = build_vtbl_ref_1 (cp_build_indirect_ref (instance_ptr, RO_NULL,
+  aref = build_vtbl_ref_1 (cp_build_indirect_ref (UNKNOWN_LOCATION,
+						  instance_ptr, RO_NULL,
                                                   tf_warning_or_error), 
                            idx);
 
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 160bf1e..4878161 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5895,8 +5895,9 @@  extern tree get_nsdmi				(tree, bool);
 extern tree build_offset_ref			(tree, tree, bool,
 						 tsubst_flags_t);
 extern tree throw_bad_array_new_length		(void);
-extern tree build_new				(vec<tree, va_gc> **, tree, tree,
-						 vec<tree, va_gc> **, int,
+extern tree build_new				(location_t,
+						 vec<tree, va_gc> **, tree,
+						 tree, vec<tree, va_gc> **, int,
                                                  tsubst_flags_t);
 extern tree get_temp_regvar			(tree, tree);
 extern tree build_vec_init			(tree, tree, tree, bool, int,
@@ -6558,7 +6559,7 @@  extern tree finish_class_member_access_expr     (tree, tree, bool,
 						 tsubst_flags_t);
 extern tree build_x_indirect_ref		(location_t, tree,
 						 ref_operator, tsubst_flags_t);
-extern tree cp_build_indirect_ref		(tree, ref_operator,
+extern tree cp_build_indirect_ref		(location_t, tree, ref_operator,
                                                  tsubst_flags_t);
 extern tree build_array_ref			(location_t, tree, tree);
 extern tree cp_build_array_ref			(location_t, tree, tree,
@@ -6579,8 +6580,8 @@  extern tree build_x_unary_op			(location_t,
 						 enum tree_code, tree,
                                                  tsubst_flags_t);
 extern tree cp_build_addr_expr			(tree, tsubst_flags_t);
-extern tree cp_build_unary_op                   (enum tree_code, tree, int, 
-                                                 tsubst_flags_t);
+extern tree cp_build_unary_op                   (location_t, enum tree_code,
+						 tree, int,  tsubst_flags_t);
 extern tree unary_complex_lvalue		(enum tree_code, tree);
 extern tree build_x_conditional_expr		(location_t, tree, tree, tree, 
                                                  tsubst_flags_t);
@@ -6596,11 +6597,13 @@  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			(location_t, tree, tree);
-extern tree cp_build_c_cast			(tree, tree, tsubst_flags_t);
+extern tree cp_build_c_cast			(location_t, tree, tree,
+						 tsubst_flags_t);
 extern tree build_x_modify_expr			(location_t, tree,
 						 enum tree_code, tree,
 						 tsubst_flags_t);
-extern tree cp_build_modify_expr		(tree, enum tree_code, tree,
+extern tree cp_build_modify_expr		(location_t, tree,
+						 enum tree_code, tree,
 						 tsubst_flags_t);
 extern tree convert_for_initialization		(tree, tree, tree, int,
 						 impl_conv_rhs, tree, int,
@@ -6638,7 +6641,9 @@  extern tree build_x_vec_perm_expr               (location_t,
 extern tree build_simple_component_ref		(tree, tree);
 extern tree build_ptrmemfunc_access_expr	(tree, tree);
 extern tree build_address			(tree);
+extern tree build_address_loc			(location_t, tree);
 extern tree build_nop				(tree, tree);
+extern tree build_nop_loc			(location_t, tree, tree);
 extern tree non_reference			(tree);
 extern tree lookup_anon_field			(tree, tree);
 extern bool invalid_nonstatic_memfn_p		(location_t, tree,
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 675342e..022300b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -13908,7 +13908,8 @@  start_preparsed_function (tree decl1, tree attrs, int flags)
       gcc_assert (TYPE_PTR_P (TREE_TYPE (t)));
 
       cp_function_chain->x_current_class_ref
-	= cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error);
+	= cp_build_indirect_ref (UNKNOWN_LOCATION, t, RO_NULL,
+				 tf_warning_or_error);
       /* Set this second to avoid shortcut in cp_build_indirect_ref.  */
       cp_function_chain->x_current_class_ptr = t;
 
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 47c9ec9..86143b8 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3139,7 +3139,7 @@  set_guard (tree guard)
   guard_init = integer_one_node;
   if (!same_type_p (TREE_TYPE (guard_init), TREE_TYPE (guard)))
     guard_init = fold_convert (TREE_TYPE (guard), guard_init);
-  return cp_build_modify_expr (guard, NOP_EXPR, guard_init, 
+  return cp_build_modify_expr (input_location, guard, NOP_EXPR, guard_init,
 			       tf_warning_or_error);
 }
 
@@ -3734,7 +3734,8 @@  one_static_initialization_or_destruction (tree decl, tree init, bool initp)
 	guard_cond
 	  = cp_build_binary_op (input_location,
 				EQ_EXPR,
-				cp_build_unary_op (PREINCREMENT_EXPR,
+				cp_build_unary_op (input_location,
+						   PREINCREMENT_EXPR,
 						   guard,
 						   /*noconvert=*/1,
 						   tf_warning_or_error),
@@ -3744,7 +3745,8 @@  one_static_initialization_or_destruction (tree decl, tree init, bool initp)
 	guard_cond
 	  = cp_build_binary_op (input_location,
 				EQ_EXPR,
-				cp_build_unary_op (PREDECREMENT_EXPR,
+				cp_build_unary_op (input_location,
+						   PREDECREMENT_EXPR,
 						   guard,
 						   /*noconvert=*/1,
 						   tf_warning_or_error),
@@ -4318,10 +4320,11 @@  handle_tls_init (void)
   start_preparsed_function (fn, NULL_TREE, SF_PRE_PARSED);
   tree body = begin_function_body ();
   tree if_stmt = begin_if_stmt ();
-  tree cond = cp_build_unary_op (TRUTH_NOT_EXPR, guard, false,
+  tree cond = cp_build_unary_op (input_location, TRUTH_NOT_EXPR, guard, false,
 				 tf_warning_or_error);
   finish_if_stmt_cond (cond, if_stmt);
-  finish_expr_stmt (cp_build_modify_expr (guard, NOP_EXPR, boolean_true_node,
+  finish_expr_stmt (cp_build_modify_expr (input_location, guard, NOP_EXPR,
+					  boolean_true_node,
 					  tf_warning_or_error));
   for (; vars; vars = TREE_CHAIN (vars))
     {
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 9b2450d..a581c3c 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -501,7 +501,8 @@  expand_start_catch_block (tree decl)
 		    fold_build1_loc (input_location,
 				     NEGATE_EXPR, sizetype,
 				     TYPE_SIZE_UNIT (TREE_TYPE (exp))));
-      exp = cp_build_indirect_ref (exp, RO_NULL, tf_warning_or_error);
+      exp = cp_build_indirect_ref (input_location, exp, RO_NULL,
+				   tf_warning_or_error);
       initialize_handler_parm (decl, exp);
       return type;
     }
@@ -818,7 +819,8 @@  build_throw (tree exp)
       CLEANUP_EH_ONLY (allocate_expr) = 1;
 
       object = build_nop (build_pointer_type (temp_type), ptr);
-      object = cp_build_indirect_ref (object, RO_NULL, tf_warning_or_error);
+      object = cp_build_indirect_ref (UNKNOWN_LOCATION, object, RO_NULL,
+				      tf_warning_or_error);
 
       /* And initialize the exception object.  */
       if (CLASS_TYPE_P (temp_type))
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 5ecf9fb..fffd203 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -793,7 +793,8 @@  perform_member_init (tree member, tree init)
 						tf_warning_or_error);
 
       if (init)
-	finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
+	finish_expr_stmt (cp_build_modify_expr (input_location, decl,
+						INIT_EXPR, init,
 						tf_warning_or_error));
     }
 
@@ -1153,7 +1154,8 @@  emit_mem_initializers (tree mem_inits)
 	  base_addr = build_base_path (PLUS_EXPR, current_class_ptr,
 				       subobject, 1, tf_warning_or_error);
 	  expand_aggr_init_1 (subobject, NULL_TREE,
-			      cp_build_indirect_ref (base_addr, RO_NULL,
+			      cp_build_indirect_ref (UNKNOWN_LOCATION,
+						     base_addr, RO_NULL,
                                                      tf_warning_or_error),
 			      arguments,
 			      flags,
@@ -1232,7 +1234,8 @@  expand_virtual_init (tree binfo, tree decl)
       /* Compute the value to use, when there's a VTT.  */
       vtt_parm = current_vtt_parm;
       vtbl2 = fold_build_pointer_plus (vtt_parm, vtt_index);
-      vtbl2 = cp_build_indirect_ref (vtbl2, RO_NULL, tf_warning_or_error);
+      vtbl2 = cp_build_indirect_ref (UNKNOWN_LOCATION, vtbl2, RO_NULL,
+				     tf_warning_or_error);
       vtbl2 = convert (TREE_TYPE (vtbl), vtbl2);
 
       /* The actual initializer is the VTT value only in the subobject
@@ -1247,15 +1250,16 @@  expand_virtual_init (tree binfo, tree decl)
     }
 
   /* Compute the location of the vtpr.  */
-  vtbl_ptr = build_vfield_ref (cp_build_indirect_ref (decl, RO_NULL, 
+  vtbl_ptr = build_vfield_ref (cp_build_indirect_ref (UNKNOWN_LOCATION, decl,
+						      RO_NULL,
                                                       tf_warning_or_error),
 			       TREE_TYPE (binfo));
   gcc_assert (vtbl_ptr != error_mark_node);
 
   /* Assign the vtable to the vptr.  */
   vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0, tf_warning_or_error);
-  finish_expr_stmt (cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl,
-					  tf_warning_or_error));
+  finish_expr_stmt (cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR,
+					  vtbl, tf_warning_or_error));
 }
 
 /* If an exception is thrown in a constructor, those base classes already
@@ -2135,8 +2139,8 @@  decl_constant_value (tree decl)
    creates and returns a NEW_EXPR.  */
 
 static tree
-build_raw_new_expr (vec<tree, va_gc> *placement, tree type, tree nelts,
-		    vec<tree, va_gc> *init, int use_global_new)
+build_raw_new_expr (location_t loc, vec<tree, va_gc> *placement, tree type,
+		    tree nelts, vec<tree, va_gc> *init, int use_global_new)
 {
   tree init_list;
   tree new_expr;
@@ -2152,9 +2156,9 @@  build_raw_new_expr (vec<tree, va_gc> *placement, tree type, tree nelts,
   else
     init_list = build_tree_list_vec (init);
 
-  new_expr = build4 (NEW_EXPR, build_pointer_type (type),
-		     build_tree_list_vec (placement), type, nelts,
-		     init_list);
+  new_expr = build4_loc (loc, NEW_EXPR, build_pointer_type (type),
+			 build_tree_list_vec (placement), type, nelts,
+			 init_list);
   NEW_EXPR_USE_GLOBAL (new_expr) = use_global_new;
   TREE_SIDE_EFFECTS (new_expr) = 1;
 
@@ -2985,7 +2989,8 @@  build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 						alloc_node, cookie_ptr);
       size_ptr_type = build_pointer_type (sizetype);
       cookie_ptr = fold_convert (size_ptr_type, cookie_ptr);
-      cookie = cp_build_indirect_ref (cookie_ptr, RO_NULL, complain);
+      cookie = cp_build_indirect_ref (input_location, cookie_ptr, RO_NULL,
+				      complain);
 
       cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
 
@@ -2997,7 +3002,8 @@  build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 						NEGATE_EXPR, sizetype,
 						size_in_bytes (sizetype)));
 
-	  cookie = cp_build_indirect_ref (cookie_ptr, RO_NULL, complain);
+	  cookie = cp_build_indirect_ref (input_location, cookie_ptr, RO_NULL,
+					  complain);
 	  cookie = build2 (MODIFY_EXPR, sizetype, cookie,
 			   size_in_bytes (elt_type));
 	  cookie_expr = build2 (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
@@ -3043,7 +3049,8 @@  build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 	     the initializer anyway since we're going to throw it away and
 	     rebuild it at instantiation time, so just build up a single
 	     constructor call to get any appropriate diagnostics.  */
-	  init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain);
+	  init_expr = cp_build_indirect_ref (UNKNOWN_LOCATION, data_addr,
+					     RO_NULL, complain);
 	  if (type_build_ctor_call (elt_type))
 	    init_expr = build_special_member_call (init_expr,
 						   complete_ctor_identifier,
@@ -3101,7 +3108,8 @@  build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 	}
       else
 	{
-	  init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain);
+	  init_expr = cp_build_indirect_ref (UNKNOWN_LOCATION, data_addr,
+					     RO_NULL, complain);
 
 	  if (type_build_ctor_call (type) && !explicit_value_init_p)
 	    {
@@ -3128,8 +3136,8 @@  build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 
 	      ie = build_x_compound_expr_from_vec (*init, "new initializer",
 						   complain);
-	      init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, ie,
-						complain);
+	      init_expr = cp_build_modify_expr (input_location, init_expr,
+						INIT_EXPR, ie, complain);
 	    }
 	  stable = stabilize_init (init_expr, &init_preeval_expr);
 	}
@@ -3266,7 +3274,7 @@  build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
    rather than just "new".  This may change PLACEMENT and INIT.  */
 
 tree
-build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
+build_new (location_t loc, vec<tree, va_gc> **placement, tree type, tree nelts,
 	   vec<tree, va_gc> **init, int use_global_new, tsubst_flags_t complain)
 {
   tree rval;
@@ -3297,7 +3305,7 @@  build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
 	  || (nelts && type_dependent_expression_p (nelts))
 	  || (nelts && *init)
 	  || any_type_dependent_arguments_p (*init))
-	return build_raw_new_expr (*placement, type, nelts, *init,
+	return build_raw_new_expr (loc, *placement, type, nelts, *init,
 				   use_global_new);
 
       orig_placement = make_tree_vector_copy (*placement);
@@ -3373,7 +3381,7 @@  build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
 
   if (processing_template_decl)
     {
-      tree ret = build_raw_new_expr (orig_placement, type, orig_nelts,
+      tree ret = build_raw_new_expr (loc, orig_placement, type, orig_nelts,
 				     orig_init, use_global_new);
       release_tree_vector (orig_placement);
       release_tree_vector (orig_init);
@@ -3381,7 +3389,7 @@  build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
     }
 
   /* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain.  */
-  rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval);
+  rval = build1_loc (loc, NOP_EXPR, TREE_TYPE (rval), rval);
   TREE_NO_WARNING (rval) = 1;
 
   return rval;
@@ -3516,7 +3524,7 @@  build_vec_delete_1 (tree base, tree maxindex, tree type,
 
   tbase = create_temporary_var (ptype);
   tbase_init
-    = cp_build_modify_expr (tbase, NOP_EXPR,
+    = cp_build_modify_expr (input_location, tbase, NOP_EXPR,
 			    fold_build_pointer_plus_loc (input_location,
 							 fold_convert (ptype,
 								       base),
@@ -3533,7 +3541,7 @@  build_vec_delete_1 (tree base, tree maxindex, tree type,
 			 fold_convert (ptype, base)));
   tmp = fold_build1_loc (input_location, NEGATE_EXPR, sizetype, size_exp);
   tmp = fold_build_pointer_plus (tbase, tmp);
-  tmp = cp_build_modify_expr (tbase, NOP_EXPR, tmp, complain);
+  tmp = cp_build_modify_expr (input_location, tbase, NOP_EXPR, tmp, complain);
   if (tmp == error_mark_node)
     return error_mark_node;
   body = build_compound_expr (input_location, body, tmp);
@@ -3651,8 +3659,8 @@  get_temp_regvar (tree type, tree init)
   decl = create_temporary_var (type);
   add_decl_expr (decl);
 
-  finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init, 
-					  tf_warning_or_error));
+  finish_expr_stmt (cp_build_modify_expr (input_location, decl, INIT_EXPR,
+					  init, tf_warning_or_error));
 
   return decl;
 }
@@ -3916,7 +3924,7 @@  build_vec_init (tree base, tree maxindex, tree init,
 	  else if (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
 	    one_init = build_aggr_init (baseref, elt, 0, complain);
 	  else
-	    one_init = cp_build_modify_expr (baseref, NOP_EXPR,
+	    one_init = cp_build_modify_expr (input_location, baseref, NOP_EXPR,
 					     elt, complain);
 	  if (one_init == error_mark_node)
 	    errors = true;
@@ -3948,14 +3956,15 @@  build_vec_init (tree base, tree maxindex, tree init,
 	    finish_expr_stmt (one_init);
 	  current_stmt_tree ()->stmts_are_full_exprs_p = 0;
 
-	  one_init = cp_build_unary_op (PREINCREMENT_EXPR, base, 0, complain);
+	  one_init = cp_build_unary_op (input_location, PREINCREMENT_EXPR,
+					base, 0, complain);
 	  if (one_init == error_mark_node)
 	    errors = true;
 	  else
 	    finish_expr_stmt (one_init);
 
-	  one_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, 0,
-					complain);
+	  one_init = cp_build_unary_op (input_location, PREDECREMENT_EXPR,
+					iterator, 0, complain);
 	  if (one_init == error_mark_node)
 	    errors = true;
 	  else
@@ -4007,8 +4016,8 @@  build_vec_init (tree base, tree maxindex, tree init,
       finish_for_cond (build2 (NE_EXPR, boolean_type_node, iterator,
 			       build_int_cst (TREE_TYPE (iterator), -1)),
 		       for_stmt, false);
-      elt_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, 0,
-				    complain);
+      elt_init = cp_build_unary_op (input_location, PREDECREMENT_EXPR,
+				    iterator, 0, complain);
       if (elt_init == error_mark_node)
 	errors = true;
       finish_for_expr (elt_init, for_stmt);
@@ -4044,13 +4053,13 @@  build_vec_init (tree base, tree maxindex, tree init,
 	    from = NULL_TREE;
 
 	  if (from_array == 2)
-	    elt_init = cp_build_modify_expr (to, NOP_EXPR, from, 
-					     complain);
+	    elt_init = cp_build_modify_expr (input_location, to, NOP_EXPR,
+					     from, complain);
 	  else if (type_build_ctor_call (type))
 	    elt_init = build_aggr_init (to, from, 0, complain);
 	  else if (from)
-	    elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
-					     complain);
+	    elt_init = cp_build_modify_expr (input_location, to, NOP_EXPR,
+					     from, complain);
 	  else
 	    gcc_unreachable ();
 	}
@@ -4124,11 +4133,11 @@  build_vec_init (tree base, tree maxindex, tree init,
 	finish_expr_stmt (elt_init);
       current_stmt_tree ()->stmts_are_full_exprs_p = 0;
 
-      finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base, 0,
-                                           complain));
+      finish_expr_stmt (cp_build_unary_op (input_location, PREINCREMENT_EXPR,
+					   base, 0, complain));
       if (base2)
-	finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base2, 0,
-                                             complain));
+	finish_expr_stmt (cp_build_unary_op (input_location, PREINCREMENT_EXPR,
+					     base2, 0, complain));
 
       finish_for_stmt (for_stmt);
     }
@@ -4190,7 +4199,8 @@  build_vec_init (tree base, tree maxindex, tree init,
     {
       atype = build_pointer_type (atype);
       stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
-      stmt_expr = cp_build_indirect_ref (stmt_expr, RO_NULL, complain);
+      stmt_expr = cp_build_indirect_ref (UNKNOWN_LOCATION, stmt_expr,
+					 RO_NULL, complain);
       TREE_NO_WARNING (stmt_expr) = 1;
     }
 
@@ -4345,7 +4355,8 @@  build_delete (tree otype, tree addr, special_function_kind auto_delete,
       /* Make sure the destructor is callable.  */
       if (type_build_dtor_call (type))
 	{
-	  expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL,
+	  expr = build_dtor_call (cp_build_indirect_ref (UNKNOWN_LOCATION,
+							 addr, RO_NULL,
 							 complain),
 				  sfk_complete_destructor, flags, complain);
 	  if (expr == error_mark_node)
@@ -4422,7 +4433,8 @@  build_delete (tree otype, tree addr, special_function_kind auto_delete,
 				complain);
 	}
 
-      expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL, complain),
+      expr = build_dtor_call (cp_build_indirect_ref (UNKNOWN_LOCATION, addr,
+						     RO_NULL, complain),
 			      auto_delete, flags, complain);
       if (expr == error_mark_node)
 	return error_mark_node;
@@ -4591,7 +4603,8 @@  build_vec_delete (tree base, tree maxindex,
 				 sizetype, TYPE_SIZE_UNIT (sizetype));
       cookie_addr = fold_build_pointer_plus (fold_convert (size_ptr_type, base),
 					     cookie_addr);
-      maxindex = cp_build_indirect_ref (cookie_addr, RO_NULL, complain);
+      maxindex = cp_build_indirect_ref (input_location, cookie_addr, RO_NULL,
+					complain);
     }
   else if (TREE_CODE (type) == ARRAY_TYPE)
     {
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 533ae0e..cf9ac31 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -728,7 +728,7 @@  do_build_copy_assign (tree fndecl)
 	    init = move (init);
 
 	  if (DECL_NAME (field))
-	    init = cp_build_modify_expr (comp, NOP_EXPR, init, 
+	    init = cp_build_modify_expr (input_location, comp, NOP_EXPR, init,
 					 tf_warning_or_error);
 	  else
 	    init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
@@ -1014,7 +1014,7 @@  assignable_expr (tree to, tree from)
   ++cp_unevaluated_operand;
   to = build_stub_object (to);
   from = build_stub_object (from);
-  tree r = cp_build_modify_expr (to, NOP_EXPR, from, tf_none);
+  tree r = cp_build_modify_expr (input_location, to, NOP_EXPR, from, tf_none);
   --cp_unevaluated_operand;
   return r;
 }
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 0e1116b..88786b1 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7643,9 +7643,9 @@  cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
 	      && !integer_zerop (cast_expression)
 	      && !TREE_OVERFLOW (cast_expression))
 	    {
-	      tree folded = fold_build1 (unary_operator,
-					 TREE_TYPE (cast_expression),
-					 cast_expression);
+	      tree folded = fold_build1_loc (loc, unary_operator,
+                                             TREE_TYPE (cast_expression),
+                                             cast_expression);
 	      if (CONSTANT_CLASS_P (folded) && !TREE_OVERFLOW (folded))
 		{
 		  expression = folded;
@@ -7811,8 +7811,8 @@  cp_parser_new_expression (cp_parser* parser)
   else
     {
       /* Create a representation of the new-expression.  */
-      ret = build_new (&placement, type, nelts, &initializer, global_scope_p,
-		       tf_warning_or_error);
+      ret = build_new (input_location, &placement, type, nelts, &initializer,
+                       global_scope_p, tf_warning_or_error);
     }
 
   if (placement != NULL)
@@ -8714,7 +8714,6 @@  cp_parser_assignment_expression (cp_parser* parser, cp_id_kind * pidk,
 	  if (assignment_operator != ERROR_MARK)
 	    {
 	      bool non_constant_p;
-	      location_t saved_input_location;
 
 	      /* Parse the right-hand side of the assignment.  */
 	      tree rhs = cp_parser_initializer_clause (parser, &non_constant_p);
@@ -8729,13 +8728,10 @@  cp_parser_assignment_expression (cp_parser* parser, cp_id_kind * pidk,
 		return error_mark_node;
 	      /* Build the assignment expression.  Its default
 		 location is the location of the '=' token.  */
-	      saved_input_location = input_location;
-	      input_location = loc;
 	      expr = build_x_modify_expr (loc, expr,
 					  assignment_operator,
 					  rhs,
 					  complain_flags (decltype_p));
-	      input_location = saved_input_location;
 	    }
 	}
     }
@@ -19245,7 +19241,8 @@  inject_this_parameter (tree ctype, cp_cv_quals quals)
   /* Clear this first to avoid shortcut in cp_build_indirect_ref.  */
   current_class_ptr = NULL_TREE;
   current_class_ref
-    = cp_build_indirect_ref (this_parm, RO_NULL, tf_warning_or_error);
+    = cp_build_indirect_ref (UNKNOWN_LOCATION, this_parm, RO_NULL,
+                             tf_warning_or_error);
   current_class_ptr = this_parm;
 }
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2904657..4123e75 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -15916,7 +15916,8 @@  tsubst_copy_and_build (tree t,
 				complain|decltype_flag));
 
     case FIX_TRUNC_EXPR:
-      RETURN (cp_build_unary_op (FIX_TRUNC_EXPR, RECUR (TREE_OPERAND (t, 0)),
+      RETURN (cp_build_unary_op (input_location, FIX_TRUNC_EXPR,
+                                 RECUR (TREE_OPERAND (t, 0)),
 				 0, complain));
 
     case ADDR_EXPR:
@@ -16171,7 +16172,7 @@  tsubst_copy_and_build (tree t,
 
 	tree op1 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl);
 	tree op2 = RECUR (TREE_OPERAND (t, 2));
-	ret = build_new (&placement_vec, op1, op2, &init_vec,
+	ret = build_new (UNKNOWN_LOCATION, &placement_vec, op1, op2, &init_vec,
 			 NEW_EXPR_USE_GLOBAL (t),
 			 complain);
 
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index b397b55..9e267cf 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -185,8 +185,8 @@  build_headof (tree exp)
   index = build_int_cst (NULL_TREE,
 			 -2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
 
-  offset = build_vtbl_ref (cp_build_indirect_ref (exp, RO_NULL, 
-                                                  tf_warning_or_error), 
+  offset = build_vtbl_ref (cp_build_indirect_ref (UNKNOWN_LOCATION, exp,
+						  RO_NULL, tf_warning_or_error),
                            index);
 
   type = cp_build_qualified_type (ptr_type_node,
@@ -274,7 +274,7 @@  get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain)
     /* Otherwise return the type_info for the static type of the expr.  */
     t = get_tinfo_ptr (TYPE_MAIN_VARIANT (type));
 
-  return cp_build_indirect_ref (t, RO_NULL, complain);
+  return cp_build_indirect_ref (UNKNOWN_LOCATION, t, RO_NULL, complain);
 }
 
 static bool
@@ -334,7 +334,7 @@  build_typeid (tree exp, tsubst_flags_t complain)
       exp = cp_build_addr_expr (exp, complain);
       exp = stabilize_reference (exp);
       cond = cp_convert (boolean_type_node, exp, complain);
-      exp = cp_build_indirect_ref (exp, RO_NULL, complain);
+      exp = cp_build_indirect_ref (UNKNOWN_LOCATION, exp, RO_NULL, complain);
     }
 
   exp = get_tinfo_decl_dynamic (exp, complain);
@@ -498,7 +498,8 @@  get_typeid (tree type, tsubst_flags_t complain)
   if (!type)
     return error_mark_node;
 
-  return cp_build_indirect_ref (get_tinfo_ptr (type), RO_NULL, complain);
+  return cp_build_indirect_ref (UNKNOWN_LOCATION, get_tinfo_ptr (type),
+				RO_NULL, complain);
 }
 
 /* Check whether TEST is null before returning RESULT.  If TEST is used in
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index e7e5d8e..ead2bba 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -588,7 +588,8 @@  simplify_loop_decl_cond (tree *cond_p, tree body)
   *cond_p = boolean_true_node;
 
   if_stmt = begin_if_stmt ();
-  cond = cp_build_unary_op (TRUTH_NOT_EXPR, cond, 0, tf_warning_or_error);
+  cond = cp_build_unary_op (input_location, TRUTH_NOT_EXPR, cond, 0,
+			    tf_warning_or_error);
   finish_if_stmt_cond (cond, if_stmt);
   finish_break_stmt ();
   finish_then_clause (if_stmt);
@@ -2601,7 +2602,8 @@  finish_compound_literal (tree type, tree compound_literal,
       compound_literal
 	= finish_compound_literal (TREE_TYPE (type), compound_literal,
 				   complain);
-      return cp_build_c_cast (type, compound_literal, complain);
+      return cp_build_c_cast (UNKNOWN_LOCATION, type, compound_literal,
+			      complain);
     }
 
   if (!TYPE_OBJ_P (type))
@@ -7916,7 +7918,7 @@  finish_omp_for (location_t locus, enum tree_code code, tree declv,
 	{
 	  if (orig_incr)
 	    TREE_VEC_ELT (orig_incr, i) = incr;
-	  incr = cp_build_modify_expr (TREE_OPERAND (incr, 0),
+	  incr = cp_build_modify_expr (input_location, TREE_OPERAND (incr, 0),
 				       TREE_CODE (TREE_OPERAND (incr, 1)),
 				       TREE_OPERAND (incr, 2),
 				       tf_warning_or_error);
@@ -7950,7 +7952,8 @@  finish_omp_for (location_t locus, enum tree_code code, tree declv,
       if (!processing_template_decl)
 	{
 	  init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
-	  init = cp_build_modify_expr (decl, NOP_EXPR, init, tf_warning_or_error);
+	  init = cp_build_modify_expr (input_location, decl, NOP_EXPR, init,
+				       tf_warning_or_error);
 	}
       else
 	init = build2 (MODIFY_EXPR, void_type_node, decl, init);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d2db31a..49ecf16 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3186,7 +3186,8 @@  tree
 build_dummy_object (tree type)
 {
   tree decl = build1 (CONVERT_EXPR, build_pointer_type (type), void_node);
-  return cp_build_indirect_ref (decl, RO_NULL, tf_warning_or_error);
+  return cp_build_indirect_ref (UNKNOWN_LOCATION, decl, RO_NULL,
+				tf_warning_or_error);
 }
 
 /* We've gotten a reference to a member of TYPE.  Return *this if appropriate,
@@ -4099,7 +4100,8 @@  stabilize_expr (tree exp, tree* initp)
       exp = cp_build_addr_expr (exp, tf_warning_or_error);
       init_expr = get_target_expr (exp);
       exp = TARGET_EXPR_SLOT (init_expr);
-      exp = cp_build_indirect_ref (exp, RO_NULL, tf_warning_or_error);
+      exp = cp_build_indirect_ref (UNKNOWN_LOCATION, exp, RO_NULL,
+				   tf_warning_or_error);
       if (xval)
 	exp = move (exp);
     }
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 5f7d4bb..cc98813 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -37,7 +37,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-ubsan.h"
 #include "params.h"
 
-static tree cp_build_addr_expr_strict (tree, tsubst_flags_t);
+static tree cp_build_addr_expr_strict (location_t, tree, tsubst_flags_t);
 static tree cp_build_function_call (tree, tree, tsubst_flags_t);
 static tree pfn_from_ptrmemfunc (tree);
 static tree delta_from_ptrmemfunc (tree);
@@ -2196,17 +2196,17 @@  rationalize_conditional_expr (enum tree_code code, tree t,
 						   op1, TREE_CODE (op1),
 						   /*overload=*/NULL,
 						   complain),
-                                cp_build_unary_op (code, op0, 0, complain),
-                                cp_build_unary_op (code, op1, 0, complain),
+                                cp_build_unary_op (loc, code, op0, 0, complain),
+                                cp_build_unary_op (loc, code, op1, 0, complain),
                                 complain);
     }
 
   return
     build_conditional_expr (loc, TREE_OPERAND (t, 0),
-			    cp_build_unary_op (code, TREE_OPERAND (t, 1), 0,
-                                               complain),
-			    cp_build_unary_op (code, TREE_OPERAND (t, 2), 0,
-                                               complain),
+			    cp_build_unary_op (loc, code, TREE_OPERAND (t, 1),
+					       0, complain),
+			    cp_build_unary_op (loc, code, TREE_OPERAND (t, 2),
+					       0, complain),
                             complain);
 }
 
@@ -2337,7 +2337,8 @@  build_class_member_access_expr (tree object, tree member,
   {
     tree temp = unary_complex_lvalue (ADDR_EXPR, object);
     if (temp)
-      object = cp_build_indirect_ref (temp, RO_NULL, complain);
+      object = cp_build_indirect_ref (UNKNOWN_LOCATION, temp, RO_NULL,
+				      complain);
   }
 
   /* In [expr.ref], there is an explicit list of the valid choices for
@@ -2907,7 +2908,7 @@  build_x_indirect_ref (location_t loc, tree expr, ref_operator errorstring,
   rval = build_new_op (loc, INDIRECT_REF, LOOKUP_NORMAL, expr,
 		       NULL_TREE, NULL_TREE, /*overload=*/NULL, complain);
   if (!rval)
-    rval = cp_build_indirect_ref (expr, errorstring, complain);
+    rval = cp_build_indirect_ref (loc, expr, errorstring, complain);
 
   if (processing_template_decl && rval != error_mark_node)
     return build_min_non_dep (INDIRECT_REF, rval, orig_expr);
@@ -2917,14 +2918,14 @@  build_x_indirect_ref (location_t loc, tree expr, ref_operator errorstring,
 
 /* Helper function called from c-common.  */
 tree
-build_indirect_ref (location_t /*loc*/,
+build_indirect_ref (location_t loc,
 		    tree ptr, ref_operator errorstring)
 {
-  return cp_build_indirect_ref (ptr, errorstring, tf_warning_or_error);
+  return cp_build_indirect_ref (loc, ptr, errorstring, tf_warning_or_error);
 }
 
 tree
-cp_build_indirect_ref (tree ptr, ref_operator errorstring, 
+cp_build_indirect_ref (location_t loc, tree ptr, ref_operator errorstring,
                        tsubst_flags_t complain)
 {
   tree pointer, type;
@@ -2979,7 +2980,7 @@  cp_build_indirect_ref (tree ptr, ref_operator errorstring,
 	return TREE_OPERAND (pointer, 0);
       else
 	{
-	  tree ref = build1 (INDIRECT_REF, t, pointer);
+	  tree ref = build1_loc (loc, INDIRECT_REF, t, pointer);
 
 	  /* We *must* set TREE_READONLY when dereferencing a pointer to const,
 	     so that we get the proper error message if the result is used
@@ -3203,12 +3204,12 @@  cp_build_array_ref (location_t loc, tree array, tree idx,
 
     warn_array_subscript_with_type_char (loc, idx);
 
-    ret = cp_build_indirect_ref (cp_build_binary_op (input_location,
+    ret = cp_build_indirect_ref (loc,
+				 cp_build_binary_op (input_location,
 						     PLUS_EXPR, ar, ind,
 						     complain),
                                  RO_ARRAY_INDEXING,
                                  complain);
-    protected_set_expr_location (ret, loc);
     if (non_lvalue)
       ret = non_lvalue_loc (loc, ret);
     return ret;
@@ -3358,13 +3359,13 @@  get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
       /* Next extract the vtable pointer from the object.  */
       vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
 		     instance_ptr);
-      vtbl = cp_build_indirect_ref (vtbl, RO_NULL, complain);
+      vtbl = cp_build_indirect_ref (input_location, vtbl, RO_NULL, complain);
       if (vtbl == error_mark_node)
 	return error_mark_node;
 
       /* Finally, extract the function pointer from the vtable.  */
       e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx);
-      e2 = cp_build_indirect_ref (e2, RO_NULL, complain);
+      e2 = cp_build_indirect_ref (input_location, e2, RO_NULL, complain);
       if (e2 == error_mark_node)
 	return error_mark_node;
       TREE_CONSTANT (e2) = 1;
@@ -4955,8 +4956,10 @@  cp_build_binary_op (location_t location,
 	  if (first_complex)
 	    {
 	      op0 = save_expr (op0);
-	      real = cp_build_unary_op (REALPART_EXPR, op0, 1, complain);
-	      imag = cp_build_unary_op (IMAGPART_EXPR, op0, 1, complain);
+	      real = cp_build_unary_op (input_location, REALPART_EXPR, op0,
+					1, complain);
+	      imag = cp_build_unary_op (input_location, IMAGPART_EXPR, op0,
+					1, complain);
 	      switch (code)
 		{
 		case MULT_EXPR:
@@ -4975,8 +4978,10 @@  cp_build_binary_op (location_t location,
 	  else
 	    {
 	      op1 = save_expr (op1);
-	      real = cp_build_unary_op (REALPART_EXPR, op1, 1, complain);
-	      imag = cp_build_unary_op (IMAGPART_EXPR, op1, 1, complain);
+	      real = cp_build_unary_op (input_location, REALPART_EXPR, op1,
+					1, complain);
+	      imag = cp_build_unary_op (input_location, IMAGPART_EXPR, op1,
+					1, complain);
 	      switch (code)
 		{
 		case MULT_EXPR:
@@ -5355,7 +5360,7 @@  build_x_unary_op (location_t loc, enum tree_code code, tree xarg,
 	    }
 	}
 
-      exp = cp_build_addr_expr_strict (xarg, complain);
+      exp = cp_build_addr_expr_strict (loc, xarg, complain);
     }
 
   if (processing_template_decl && exp != error_mark_node)
@@ -5422,6 +5427,21 @@  build_address (tree t)
   return t;
 }
 
+/* As build_address, but at location LOC, rather than
+   UNKNOWN_LOCATION.  */
+
+tree
+build_address_loc (location_t loc, tree t)
+{
+  if (error_operand_p (t) || !cxx_mark_addressable (t))
+    return error_mark_node;
+  gcc_checking_assert (TREE_CODE (t) != CONSTRUCTOR);
+  t = build_fold_addr_expr_loc (loc, t);
+  if (TREE_CODE (t) != ADDR_EXPR)
+    t = rvalue (t);
+  return t;
+}
+
 /* Return a NOP_EXPR converting EXPR to TYPE.  */
 
 tree
@@ -5429,7 +5449,17 @@  build_nop (tree type, tree expr)
 {
   if (type == error_mark_node || error_operand_p (expr))
     return expr;
-  return build1 (NOP_EXPR, type, expr);
+  return build1_loc (EXPR_LOCATION (expr), NOP_EXPR, type, expr);
+}
+
+/* Return a NOP_EXPR converting EXPR to TYPE.  */
+
+tree
+build_nop_loc (location_t loc, tree type, tree expr)
+{
+  if (type == error_mark_node || error_operand_p (expr))
+    return expr;
+  return build1_loc (loc, NOP_EXPR, type, expr);
 }
 
 /* Take the address of ARG, whatever that means under C++ semantics.
@@ -5440,7 +5470,8 @@  build_nop (tree type, tree expr)
    cp_build_addr_expr or cp_build_addr_expr_strict.  */
 
 static tree
-cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
+cp_build_addr_expr_1 (location_t loc, tree arg, bool strict_lvalue,
+		      tsubst_flags_t complain)
 {
   tree argtype;
   tree val;
@@ -5500,7 +5531,7 @@  cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
      address of a function is a no-op, so just return the
      argument.  */
   if (type_unknown_p (arg))
-    return build1 (ADDR_EXPR, unknown_type_node, arg);
+    return build1_loc (loc, ADDR_EXPR, unknown_type_node, arg);
 
   if (TREE_CODE (arg) == OFFSET_REF)
     /* We want a pointer to member; bypass all the code for actually taking
@@ -5534,7 +5565,7 @@  cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
   if (TREE_CODE (argtype) == REFERENCE_TYPE)
     {
       tree type = build_pointer_type (TREE_TYPE (argtype));
-      arg = build1 (CONVERT_EXPR, type, arg);
+      arg = build1_loc (loc, CONVERT_EXPR, type, arg);
       return arg;
     }
   else if (pedantic && DECL_MAIN_P (arg))
@@ -5561,7 +5592,7 @@  cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
       if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
 	{
 	  tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
-	  arg = build1 (CONVERT_EXPR, type, arg);
+	  arg = build1_loc (loc, CONVERT_EXPR, type, arg);
 	}
       else
 	/* Don't let this be an lvalue.  */
@@ -5579,7 +5610,7 @@  cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
       && TREE_CONSTANT (TREE_OPERAND (val, 0)))
     {
       tree type = build_pointer_type (argtype);
-      return fold_convert (type, fold_offsetof_1 (arg));
+      return fold_convert_loc (loc, type, fold_offsetof_1 (arg));
     }
 
   /* Handle complex lvalues (when permitted)
@@ -5648,7 +5679,7 @@  cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
      so we can just form an ADDR_EXPR with the correct type.  */
   if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
     {
-      val = build_address (arg);
+      val = build_address_loc (loc, arg);
       if (TREE_CODE (arg) == OFFSET_REF)
 	PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
     }
@@ -5701,15 +5732,15 @@  cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
 tree
 cp_build_addr_expr (tree arg, tsubst_flags_t complain)
 {
-  return cp_build_addr_expr_1 (arg, 0, complain);
+  return cp_build_addr_expr_1 (UNKNOWN_LOCATION, arg, 0, complain);
 }
 
 /* Take the address of ARG, but only if it's an lvalue.  */
 
 static tree
-cp_build_addr_expr_strict (tree arg, tsubst_flags_t complain)
+cp_build_addr_expr_strict (location_t loc, tree arg, tsubst_flags_t complain)
 {
-  return cp_build_addr_expr_1 (arg, 1, complain);
+  return cp_build_addr_expr_1 (loc, arg, 1, complain);
 }
 
 /* C++: Must handle pointers to members.
@@ -5722,8 +5753,8 @@  cp_build_addr_expr_strict (tree arg, tsubst_flags_t complain)
    (such as from short to int).  */
 
 tree
-cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, 
-                   tsubst_flags_t complain)
+cp_build_unary_op (location_t loc, enum tree_code code, tree xarg,
+		   int noconvert, tsubst_flags_t complain)
 {
   /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
   tree arg = xarg;
@@ -5816,11 +5847,11 @@  cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
 
     case TRUTH_NOT_EXPR:
       if (VECTOR_TYPE_P (TREE_TYPE (arg)))
-	return cp_build_binary_op (input_location, EQ_EXPR, arg,
+	return cp_build_binary_op (loc, EQ_EXPR, arg,
 				   build_zero_cst (TREE_TYPE (arg)), complain);
       arg = perform_implicit_conversion (boolean_type_node, arg,
 					 complain);
-      val = invert_truthvalue_loc (input_location, arg);
+      val = invert_truthvalue_loc (loc, arg);
       if (arg != error_mark_node)
 	return val;
       errstring = _("in argument to unary !");
@@ -5854,13 +5885,15 @@  cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
 	  tree real, imag;
 
 	  arg = stabilize_reference (arg);
-	  real = cp_build_unary_op (REALPART_EXPR, arg, 1, complain);
-	  imag = cp_build_unary_op (IMAGPART_EXPR, arg, 1, complain);
-	  real = cp_build_unary_op (code, real, 1, complain);
+	  real = cp_build_unary_op (input_location, REALPART_EXPR, arg,
+				    1, complain);
+	  imag = cp_build_unary_op (input_location, IMAGPART_EXPR, arg,
+				    1, complain);
+	  real = cp_build_unary_op (input_location, code, real, 1, complain);
 	  if (real == error_mark_node || imag == error_mark_node)
 	    return error_mark_node;
-	  return build2 (COMPLEX_EXPR, TREE_TYPE (arg),
-			 real, imag);
+	  return build2_loc (loc, COMPLEX_EXPR, TREE_TYPE (arg),
+			     real, imag);
 	}
 
       /* Report invalid types.  */
@@ -5954,7 +5987,7 @@  cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
 	   need to ask Objective-C to build the increment or decrement
 	   expression for it.  */
 	if (objc_is_property_ref (arg))
-	  return objc_build_incr_expr_for_property_ref (input_location, code, 
+	  return objc_build_incr_expr_for_property_ref (loc, code,
 							arg, inc);	
 
 	/* Complain about anything else that is not a true lvalue.  */
@@ -5978,9 +6011,10 @@  cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
 	  }
 	else if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
 	  /* An rvalue has no cv-qualifiers.  */
-	  val = build2 (code, cv_unqualified (TREE_TYPE (arg)), arg, inc);
+	  val = build2_loc (loc, code, cv_unqualified (TREE_TYPE (arg)), arg,
+			    inc);
 	else
-	  val = build2 (code, TREE_TYPE (arg), arg, inc);
+	  val = build2_loc (loc, code, TREE_TYPE (arg), arg, inc);
 
 	TREE_SIDE_EFFECTS (val) = 1;
 	return val;
@@ -5999,7 +6033,7 @@  cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
     {
       if (argtype == 0)
 	argtype = TREE_TYPE (arg);
-      return build1 (code, argtype, arg);
+      return build1_loc (loc, code, argtype, arg);
     }
 
   if (complain & tf_error)
@@ -6009,10 +6043,11 @@  cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
 
 /* Hook for the c-common bits that build a unary op.  */
 tree
-build_unary_op (location_t /*location*/,
+build_unary_op (location_t location,
 		enum tree_code code, tree xarg, int noconvert)
 {
-  return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error);
+  return cp_build_unary_op (location, code, xarg, noconvert,
+			    tf_warning_or_error);
 }
 
 /* Apply unary lvalue-demanding operator CODE to the expression ARG
@@ -6034,7 +6069,8 @@  unary_complex_lvalue (enum tree_code code, tree arg)
   /* Handle (a, b) used as an "lvalue".  */
   if (TREE_CODE (arg) == COMPOUND_EXPR)
     {
-      tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 1), 0,
+      tree real_result = cp_build_unary_op (input_location, code,
+					    TREE_OPERAND (arg, 1), 0,
                                             tf_warning_or_error);
       return build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
 		     TREE_OPERAND (arg, 0), real_result);
@@ -6068,7 +6104,8 @@  unary_complex_lvalue (enum tree_code code, tree arg)
   if (TREE_CODE (arg) == MODIFY_EXPR
       || TREE_CODE (arg) == INIT_EXPR)
     {
-      tree real_result = cp_build_unary_op (code, TREE_OPERAND (arg, 0), 0,
+      tree real_result = cp_build_unary_op (input_location, code,
+					    TREE_OPERAND (arg, 0), 0,
                                             tf_warning_or_error);
       arg = build2 (COMPOUND_EXPR, TREE_TYPE (real_result),
 		    arg, real_result);
@@ -6519,7 +6556,7 @@  convert_ptrmem (tree type, tree expr, bool allow_inverse_p,
    indicate whether or not the cast was valid.  */
 
 static tree
-build_static_cast_1 (tree type, tree expr, bool c_cast_p,
+build_static_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p,
 		     bool *valid_p, tsubst_flags_t complain)
 {
   tree intype;
@@ -6623,7 +6660,7 @@  build_static_cast_1 (tree type, tree expr, bool c_cast_p,
 	  /* Make sure we don't fold back down to a named rvalue reference,
 	     because that would be an lvalue.  */
 	  if (DECL_P (result))
-	    result = build1 (NON_LVALUE_EXPR, type, result);
+	    result = build1_loc (loc, NON_LVALUE_EXPR, type, result);
 	  return convert_from_reference (result);
 	}
       else
@@ -6673,7 +6710,7 @@  build_static_cast_1 (tree type, tree expr, bool c_cast_p,
 
 	  if (result == expr && SCALAR_TYPE_P (type))
 	    /* Leave some record of the cast.  */
-	    result = build_nop (type, expr);
+	    result = build_nop_loc (loc, type, expr);
 	}
       return result;
     }
@@ -6787,7 +6824,7 @@  build_static_cast_1 (tree type, tree expr, bool c_cast_p,
 	  && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
 					       complain))
 	return error_mark_node;
-      return build_nop (type, expr);
+      return build_nop_loc (loc, type, expr);
     }
 
   *valid_p = false;
@@ -6820,8 +6857,8 @@  build_static_cast (tree type, tree expr, tsubst_flags_t complain)
       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
     expr = TREE_OPERAND (expr, 0);
 
-  result = build_static_cast_1 (type, expr, /*c_cast_p=*/false, &valid_p,
-                                complain);
+  result = build_static_cast_1 (input_location, type, expr, /*c_cast_p=*/false,
+				&valid_p, complain);
   if (valid_p)
     {
       if (result != error_mark_node)
@@ -6881,7 +6918,7 @@  convert_member_func_to_ptr (tree type, tree expr, tsubst_flags_t complain)
    indicate whether or not reinterpret_cast was valid.  */
 
 static tree
-build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
+build_reinterpret_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p,
 			  bool *valid_p, tsubst_flags_t complain)
 {
   tree intype;
@@ -6931,7 +6968,8 @@  build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
 
       if (expr != error_mark_node)
 	expr = build_reinterpret_cast_1
-	  (build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
+	  (input_location,
+	   build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
 	   valid_p, complain);
       if (expr != error_mark_node)
 	/* cp_build_indirect_ref isn't right for rvalue refs.  */
@@ -7027,7 +7065,7 @@  build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
       if (warn_strict_aliasing <= 2)
 	strict_aliasing_warning (intype, type, sexpr);
 
-      return build_nop (type, expr);
+      return build_nop_loc (loc, type, expr);
     }
   else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
 	   || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
@@ -7038,7 +7076,7 @@  build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
 	warning (OPT_Wconditionally_supported,
 		 "casting between pointer-to-function and pointer-to-object "
 		 "is conditionally-supported");
-      return build_nop (type, expr);
+      return build_nop_loc (loc, type, expr);
     }
   else if (VECTOR_TYPE_P (type))
     return convert_to_vector (type, expr);
@@ -7076,7 +7114,8 @@  build_reinterpret_cast (tree type, tree expr, tsubst_flags_t complain)
       return convert_from_reference (t);
     }
 
-  r = build_reinterpret_cast_1 (type, expr, /*c_cast_p=*/false,
+  r = build_reinterpret_cast_1 (input_location,
+				type, expr, /*c_cast_p=*/false,
 				/*valid_p=*/NULL, complain);
   if (r != error_mark_node)
     maybe_warn_about_useless_cast (type, expr, complain);
@@ -7091,8 +7130,8 @@  build_reinterpret_cast (tree type, tree expr, tsubst_flags_t complain)
    whether or not the conversion succeeded.  */
 
 static tree
-build_const_cast_1 (tree dst_type, tree expr, tsubst_flags_t complain,
-		    bool *valid_p)
+build_const_cast_1 (location_t loc, tree dst_type, tree expr,
+		    tsubst_flags_t complain, bool *valid_p)
 {
   tree src_type;
   tree reference_type;
@@ -7195,7 +7234,7 @@  build_const_cast_1 (tree dst_type, tree expr, tsubst_flags_t complain,
 	      expr = cp_build_addr_expr (expr, complain);
 	      if (expr == error_mark_node)
 		return error_mark_node;
-	      expr = build_nop (reference_type, expr);
+	      expr = build_nop_loc (loc, reference_type, expr);
 	      return convert_from_reference (expr);
 	    }
 	  else
@@ -7210,7 +7249,7 @@  build_const_cast_1 (tree dst_type, tree expr, tsubst_flags_t complain,
 	      if (TREE_CODE (expr) == NOP_EXPR
 		  && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
 		expr = TREE_OPERAND (expr, 0);
-	      return build_nop (dst_type, expr);
+	      return build_nop_loc (loc, dst_type, expr);
 	    }
 	}
       else if (valid_p
@@ -7245,7 +7284,8 @@  build_const_cast (tree type, tree expr, tsubst_flags_t complain)
       return convert_from_reference (t);
     }
 
-  r = build_const_cast_1 (type, expr, complain, /*valid_p=*/NULL);
+  r = build_const_cast_1 (input_location, type, expr, complain,
+			  /*valid_p=*/NULL);
   if (r != error_mark_node)
     maybe_warn_about_useless_cast (type, expr, complain);
   return r;
@@ -7254,16 +7294,16 @@  build_const_cast (tree type, tree expr, tsubst_flags_t complain)
 /* Like cp_build_c_cast, but for the c-common bits.  */
 
 tree
-build_c_cast (location_t /*loc*/, tree type, tree expr)
+build_c_cast (location_t loc, tree type, tree expr)
 {
-  return cp_build_c_cast (type, expr, tf_warning_or_error);
+  return cp_build_c_cast (loc, type, expr, tf_warning_or_error);
 }
 
 /* Build an expression representing an explicit C-style cast to type
    TYPE of expression EXPR.  */
 
 tree
-cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
+cp_build_c_cast (location_t loc, tree type, tree expr, tsubst_flags_t complain)
 {
   tree value = expr;
   tree result;
@@ -7286,7 +7326,7 @@  cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
      in method lookup.  */
   if (objc_is_object_ptr (type)
       && objc_is_object_ptr (TREE_TYPE (expr)))
-    return build_nop (type, expr);
+    return build_nop_loc (loc, type, expr);
 
   /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
      Strip such NOP_EXPRs if VALUE is being used in non-lvalue context.  */
@@ -7333,7 +7373,7 @@  cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
 		"cast to pointer from integer of different size");
 
   /* A C-style cast can be a const_cast.  */
-  result = build_const_cast_1 (type, value, complain & tf_warning,
+  result = build_const_cast_1 (loc, type, value, complain & tf_warning,
 			       &valid_p);
   if (valid_p)
     {
@@ -7343,11 +7383,11 @@  cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
     }
 
   /* Or a static cast.  */
-  result = build_static_cast_1 (type, value, /*c_cast_p=*/true,
+  result = build_static_cast_1 (loc, type, value, /*c_cast_p=*/true,
 				&valid_p, complain);
   /* Or a reinterpret_cast.  */
   if (!valid_p)
-    result = build_reinterpret_cast_1 (type, value, /*c_cast_p=*/true,
+    result = build_reinterpret_cast_1 (loc, type, value, /*c_cast_p=*/true,
 				       &valid_p, complain);
   /* The static_cast or reinterpret_cast may be followed by a
      const_cast.  */
@@ -7373,7 +7413,7 @@  cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
 	 to succeed.  */
       if (!same_type_p (non_reference (type), non_reference (result_type)))
 	{
-	  result = build_const_cast_1 (type, result, false, &valid_p);
+	  result = build_const_cast_1 (loc, type, result, false, &valid_p);
 	  gcc_assert (valid_p);
 	}
       return result;
@@ -7384,13 +7424,14 @@  cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
 
 /* For use from the C common bits.  */
 tree
-build_modify_expr (location_t /*location*/,
+build_modify_expr (location_t location,
 		   tree lhs, tree /*lhs_origtype*/,
 		   enum tree_code modifycode, 
 		   location_t /*rhs_location*/, tree rhs,
 		   tree /*rhs_origtype*/)
 {
-  return cp_build_modify_expr (lhs, modifycode, rhs, tf_warning_or_error);
+  return cp_build_modify_expr (location, lhs, modifycode, rhs,
+			       tf_warning_or_error);
 }
 
 /* Build an assignment expression of lvalue LHS from value RHS.
@@ -7401,8 +7442,8 @@  build_modify_expr (location_t /*location*/,
    C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed.  */
 
 tree
-cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
-		      tsubst_flags_t complain)
+cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
+		      tree rhs, tsubst_flags_t complain)
 {
   tree result;
   tree newrhs = rhs;
@@ -7424,31 +7465,31 @@  cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
 		      stabilize_reference (TREE_OPERAND (lhs, 0)),
 		      TREE_OPERAND (lhs, 1));
-      newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 0),
+      newrhs = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 0),
 				     modifycode, rhs, complain);
       if (newrhs == error_mark_node)
 	return error_mark_node;
-      return build2 (COMPOUND_EXPR, lhstype, lhs, newrhs);
+      return build2_loc (loc, COMPOUND_EXPR, lhstype, lhs, newrhs);
 
       /* Handle (a, b) used as an "lvalue".  */
     case COMPOUND_EXPR:
-      newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 1),
+      newrhs = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
 				     modifycode, rhs, complain);
       if (newrhs == error_mark_node)
 	return error_mark_node;
-      return build2 (COMPOUND_EXPR, lhstype,
-		     TREE_OPERAND (lhs, 0), newrhs);
+      return build2_loc (loc, COMPOUND_EXPR, lhstype,
+			 TREE_OPERAND (lhs, 0), newrhs);
 
     case MODIFY_EXPR:
       if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
 	lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
 		      stabilize_reference (TREE_OPERAND (lhs, 0)),
 		      TREE_OPERAND (lhs, 1));
-      newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs,
-				     complain);
+      newrhs = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 0), modifycode,
+				     rhs, complain);
       if (newrhs == error_mark_node)
 	return error_mark_node;
-      return build2 (COMPOUND_EXPR, lhstype, lhs, newrhs);
+      return build2_loc (loc, COMPOUND_EXPR, lhstype, lhs, newrhs);
 
     case MIN_EXPR:
     case MAX_EXPR:
@@ -7493,10 +7534,10 @@  cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	  return error_mark_node;
 
 	cond = build_conditional_expr
-	  (input_location, TREE_OPERAND (lhs, 0),
-	   cp_build_modify_expr (TREE_OPERAND (lhs, 1),
+	  (loc, TREE_OPERAND (lhs, 0),
+	   cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
 				 modifycode, rhs, complain),
-	   cp_build_modify_expr (TREE_OPERAND (lhs, 2),
+	   cp_build_modify_expr (loc, TREE_OPERAND (lhs, 2),
 				 modifycode, rhs, complain),
            complain);
 
@@ -7505,7 +7546,8 @@  cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	/* Make sure the code to compute the rhs comes out
 	   before the split.  */
 	if (preeval)
-	  cond = build2 (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
+	  cond = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (lhs), preeval,
+			     cond);
 	return cond;
       }
 
@@ -7523,7 +7565,7 @@  cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	  if (! same_type_p (TREE_TYPE (rhs), lhstype))
 	    /* Call convert to generate an error; see PR 11063.  */
 	    rhs = convert (lhstype, rhs);
-	  result = build2 (INIT_EXPR, lhstype, lhs, rhs);
+	  result = build2_loc (loc, INIT_EXPR, lhstype, lhs, rhs);
 	  TREE_SIDE_EFFECTS (result) = 1;
 	  return result;
 	}
@@ -7561,7 +7603,7 @@  cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	    /* Do the default thing.  */;
 	  else
 	    {
-	      result = build_new_op (input_location, MODIFY_EXPR,
+	      result = build_new_op (loc, MODIFY_EXPR,
 				     LOOKUP_NORMAL, lhs, rhs,
 				     make_node (NOP_EXPR), /*overload=*/NULL,
 				     complain);
@@ -7594,7 +7636,7 @@  cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	  lhs = stabilize_reference (lhs);
 	  rhs = rvalue (rhs);
 	  rhs = stabilize_expr (rhs, &init);
-	  newrhs = cp_build_binary_op (input_location,
+	  newrhs = cp_build_binary_op (loc,
 				       modifycode, lhs, rhs,
 				       complain);
 	  if (newrhs == error_mark_node)
@@ -7606,7 +7648,8 @@  cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	    }
 
 	  if (init)
-	    newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs);
+	    newrhs = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (newrhs), init,
+				 newrhs);
 
 	  /* Now it looks like a plain assignment.  */
 	  modifycode = NOP_EXPR;
@@ -7754,8 +7797,9 @@  cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	return result;
     }
 
-  result = build2 (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
-		   lhstype, lhs, newrhs);
+  result = build2_loc (loc,
+		       modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
+		       lhstype, lhs, newrhs);
 
   TREE_SIDE_EFFECTS (result) = 1;
   if (!plain_assign)
@@ -7784,7 +7828,7 @@  build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
 	  return rval;
 	}
     }
-  return cp_build_modify_expr (lhs, modifycode, rhs, complain);
+  return cp_build_modify_expr (loc, lhs, modifycode, rhs, complain);
 }
 
 /* Helper function for get_delta_difference which assumes FROM is a base
@@ -8024,7 +8068,7 @@  build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
   /* Handle null pointer to member function conversions.  */
   if (null_ptr_cst_p (pfn))
     {
-      pfn = cp_build_c_cast (type, pfn, complain);
+      pfn = cp_build_c_cast (UNKNOWN_LOCATION, type, pfn, complain);
       return build_ptrmemfunc1 (to_type,
 				integer_zero_node,
 				pfn);
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 839091c..51fbc77 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1740,7 +1740,7 @@  build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
 	  return expr;
 	}
 
-      return cp_build_indirect_ref (last_rval, RO_NULL, complain);
+      return cp_build_indirect_ref (loc, last_rval, RO_NULL, complain);
     }
 
   if (complain & tf_error)
@@ -1841,7 +1841,8 @@  build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
 	 value stored in the pointer-to-data-member.  */
       ptype = build_pointer_type (type);
       datum = fold_build_pointer_plus (fold_convert (ptype, datum), component);
-      datum = cp_build_indirect_ref (datum, RO_NULL, complain);
+      datum = cp_build_indirect_ref (UNKNOWN_LOCATION, datum, RO_NULL,
+				     complain);
       if (datum == error_mark_node)
 	return error_mark_node;
 
@@ -1955,7 +1956,7 @@  build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
 
       /* This must build a C cast.  */
       parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain);
-      return cp_build_c_cast (type, parms, complain);
+      return cp_build_c_cast (UNKNOWN_LOCATION, type, parms, complain);
     }
 
   /* Prepare to evaluate as a call to a constructor.  If this expression
@@ -1976,7 +1977,8 @@  build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
      conversion is equivalent (in definedness, and if defined in
      meaning) to the corresponding cast expression.  */
   if (parms && TREE_CHAIN (parms) == NULL_TREE)
-    return cp_build_c_cast (type, TREE_VALUE (parms), complain);
+    return cp_build_c_cast (UNKNOWN_LOCATION, type, TREE_VALUE (parms),
+			    complain);
 
   /* [expr.type.conv]