diff mbox

[C++] PR 44516

Message ID 4FB1926F.1040100@oracle.com
State New
Headers show

Commit Message

Paolo Carlini May 14, 2012, 11:17 p.m. UTC
Hi,

On 05/14/2012 07:38 PM, Jason Merrill wrote:
> On 05/14/2012 12:53 PM, Paolo Carlini wrote:
>> Yeah. I'm trying to replace *all* the current ones with the _loc
>> variant. The patch as you can imagine is becoming *huge*. Some details
>> will probably need another pass.
>
> One approach would be to make the non-_loc names macros that just call 
> the _loc variants with UNKNOWN_LOCATION.
But wouldn't this in turn require variadic macros which are C99-only? Or 
you mean something else?

Anyway, for this *specific* PR, if you agree I would rather follow your 
original advice and simply add build_min_nt_loc, and use it everywhere, 
thus removing completely the non-_loc variant (*) In a couple of 
situations I'm simply using UNKNOWN_LOCATION to be safe, this allows to 
replace completely the non-_loc variant and only two existing testcases 
must be adjusted, pure improvements (besides what appears in the 
testsuite, we are for example handling much better ARRAY_REFs and more).

Tested x86_64-linux.

Thanks!
Paolo.

(*) As you know, I tried to do more at once, but while I can easily see 
improvements in the testsuite, I can also see "random" regressions. I'd 
like to proceed incrementally.

/////////////////////////////////
gcc/cp
2012-05-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/44516
	* typeck.c (build_x_array_ref, build_x_conditional_expr,
	build_x_compound_expr, build_x_modify_expr): Add location_t parameter.
	(finish_class_member_access_expr, build_x_indirect_ref,
	build_x_binary_op, build_x_compound_expr_from_list,
	build_x_compound_expr_from_vec): Adjust callers.
	* tree.c (build_min_nt_loc): New.
	(build_min_nt): Remove.
	* typeck2.c (build_x_arrow): Adjust callers.
	* pt.c (tsubst_qualified_id, tsubst_omp_for_iterator,
	tsubst_copy_and_build): Likewise.
	* semantics.c (finish_mem_initializers, handle_omp_for_class_iterator,
	 finish_omp_atomic): Likewise.
	* decl2.c (grok_array_decl, build_anon_union_vars): Adjust.
	* parser.c (cp_parser_question_colon_clause,
	cp_parser_assignment_expression, cp_parser_expression,
	cp_parser_template_id, cp_parser_omp_for_loop): Likewise.
	* cp-tree.h: Update.

gcc/testsuite
2012-05-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/44516
	* g++.dg/parse/error48.C: New.
	* g++.dg/template/crash89.C: Adjust dg-error line numbers.

libstdc++
2012-05-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/44516
	* testsuite/20_util/ratio/cons/cons_overflow_neg.cc: Adjust
	dg-error line number.

Comments

Jason Merrill May 15, 2012, 6:53 p.m. UTC | #1
On 05/14/2012 07:17 PM, Paolo Carlini wrote:
> @@ -5670,7 +5672,8 @@ build_x_compound_expr_from_list (tree list, expr_l
>   	return error_mark_node;
>
>         for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
> -	expr = build_x_compound_expr (expr, TREE_VALUE (list),
> +	expr = build_x_compound_expr (EXPR_LOC_OR_HERE (expr), expr,
> +				      TREE_VALUE (list),
>                                         complain);

For a COMPOUND_EXPR, I think the relevant location is that of the comma, 
and since we don't have that location I think the location of the second 
expression is a closer approximation.

Note that when copying the location from one expression to another, 
EXPR_LOC_OR_HERE will change UNKNOWN_LOCATION to input_location, whereas 
EXPR_LOCATION will leave it alone.

Jason
diff mbox

Patch

Index: libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc	(revision 187451)
+++ libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow_neg.cc	(working copy)
@@ -2,7 +2,7 @@ 
 // { dg-options "-std=gnu++0x" }
 // { dg-require-cstdint "" }
 
-// Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation
+// Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -51,5 +51,5 @@  test04()
 // { dg-error "required from here" "" { target *-*-* } 46 }
 // { dg-error "denominator cannot be zero" "" { target *-*-* } 265 }
 // { dg-error "out of range" "" { target *-*-* } 266 }
-// { dg-error "overflow in constant expression" "" { target *-*-* } 61 }
+// { dg-error "overflow in constant expression" "" { target *-*-* } 62 }
 // { dg-prune-output "not a member" }
Index: gcc/testsuite/g++.dg/parse/error48.C
===================================================================
--- gcc/testsuite/g++.dg/parse/error48.C	(revision 0)
+++ gcc/testsuite/g++.dg/parse/error48.C	(revision 0)
@@ -0,0 +1,10 @@ 
+// PR c++/44516
+
+struct WebService {  };
+struct Server {  };
+
+void addHTTPService(Server const &server,
+		    WebService const *http)
+{
+  server += http; // { dg-error "10:no match for 'operator\\+='" }
+}
Index: gcc/testsuite/g++.dg/template/crash89.C
===================================================================
--- gcc/testsuite/g++.dg/template/crash89.C	(revision 187451)
+++ gcc/testsuite/g++.dg/template/crash89.C	(working copy)
@@ -1,8 +1,8 @@ 
 // PR c++/34397
 
-template<typename T, int = T()[0]> struct A
+template<typename T, int = T()[0]> struct A // { dg-error "subscripted|template" }
 {
   typedef A<T> B;
 };
 
-A<int> a; // { dg-error "subscripted|template|declaration" }
+A<int> a; // { dg-error "declaration" }
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 187476)
+++ gcc/cp/typeck.c	(working copy)
@@ -2536,7 +2536,8 @@  finish_class_member_access_expr (tree object, tree
 	  || (TREE_CODE (name) == SCOPE_REF
 	      && TYPE_P (TREE_OPERAND (name, 0))
 	      && dependent_type_p (TREE_OPERAND (name, 0))))
-	return build_min_nt (COMPONENT_REF, object, name, NULL_TREE);
+	return build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF,
+				 object, name, NULL_TREE);
       object = build_non_dependent_expr (object);
     }
   else if (c_dialect_objc ()
@@ -2743,7 +2744,7 @@  build_x_indirect_ref (location_t loc, tree expr, r
       if (TREE_TYPE (expr) && POINTER_TYPE_P (TREE_TYPE (expr)))
 	return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
       if (type_dependent_expression_p (expr))
-	return build_min_nt (INDIRECT_REF, expr);
+	return build_min_nt_loc (loc, INDIRECT_REF, expr);
       expr = build_non_dependent_expr (expr);
     }
 
@@ -3597,7 +3598,7 @@  build_x_binary_op (location_t loc, enum tree_code
     {
       if (type_dependent_expression_p (arg1)
 	  || type_dependent_expression_p (arg2))
-	return build_min_nt (code, arg1, arg2);
+	return build_min_nt_loc (loc, code, arg1, arg2);
       arg1 = build_non_dependent_expr (arg1);
       arg2 = build_non_dependent_expr (arg2);
     }
@@ -3629,7 +3630,8 @@  build_x_binary_op (location_t loc, enum tree_code
 /* Build and return an ARRAY_REF expression.  */
 
 tree
-build_x_array_ref (tree arg1, tree arg2, tsubst_flags_t complain)
+build_x_array_ref (location_t loc, tree arg1, tree arg2,
+		   tsubst_flags_t complain)
 {
   tree orig_arg1 = arg1;
   tree orig_arg2 = arg2;
@@ -3639,13 +3641,13 @@  tree
     {
       if (type_dependent_expression_p (arg1)
 	  || type_dependent_expression_p (arg2))
-	return build_min_nt (ARRAY_REF, arg1, arg2,
-			     NULL_TREE, NULL_TREE);
+	return build_min_nt_loc (loc, ARRAY_REF, arg1, arg2,
+				 NULL_TREE, NULL_TREE);
       arg1 = build_non_dependent_expr (arg1);
       arg2 = build_non_dependent_expr (arg2);
     }
 
-  expr = build_new_op (input_location, ARRAY_REF, LOOKUP_NORMAL, arg1,
+  expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL, arg1,
 		       arg2, NULL_TREE, /*overload=*/NULL, complain);
 
   if (processing_template_decl && expr != error_mark_node)
@@ -4671,7 +4673,7 @@  build_x_unary_op (location_t loc, enum tree_code c
   if (processing_template_decl)
     {
       if (type_dependent_expression_p (xarg))
-	return build_min_nt (code, xarg, NULL_TREE);
+	return build_min_nt_loc (loc, code, xarg, NULL_TREE);
 
       xarg = build_non_dependent_expr (xarg);
     }
@@ -5586,7 +5588,7 @@  cxx_mark_addressable (tree exp)
 /* Build and return a conditional expression IFEXP ? OP1 : OP2.  */
 
 tree
-build_x_conditional_expr (tree ifexp, tree op1, tree op2, 
+build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2, 
                           tsubst_flags_t complain)
 {
   tree orig_ifexp = ifexp;
@@ -5603,7 +5605,7 @@  tree
 	  /* As a GNU extension, the middle operand may be omitted.  */
 	  || (op1 && type_dependent_expression_p (op1))
 	  || type_dependent_expression_p (op2))
-	return build_min_nt (COND_EXPR, ifexp, op1, op2);
+	return build_min_nt_loc (loc, COND_EXPR, ifexp, op1, op2);
       ifexp = build_non_dependent_expr (ifexp);
       if (op1)
 	op1 = build_non_dependent_expr (op1);
@@ -5670,7 +5672,8 @@  build_x_compound_expr_from_list (tree list, expr_l
 	return error_mark_node;
 
       for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
-	expr = build_x_compound_expr (expr, TREE_VALUE (list), 
+	expr = build_x_compound_expr (EXPR_LOC_OR_HERE (expr), expr,
+				      TREE_VALUE (list), 
                                       complain);
     }
 
@@ -5699,7 +5702,8 @@  build_x_compound_expr_from_vec (VEC(tree,gc) *vec,
 
       expr = VEC_index (tree, vec, 0);
       for (ix = 1; VEC_iterate (tree, vec, ix, t); ++ix)
-	expr = build_x_compound_expr (expr, t, tf_warning_or_error);
+	expr = build_x_compound_expr (EXPR_LOC_OR_HERE (expr), expr,
+				      t, tf_warning_or_error);
 
       return expr;
     }
@@ -5708,7 +5712,8 @@  build_x_compound_expr_from_vec (VEC(tree,gc) *vec,
 /* Handle overloading of the ',' operator when needed.  */
 
 tree
-build_x_compound_expr (tree op1, tree op2, tsubst_flags_t complain)
+build_x_compound_expr (location_t loc, tree op1, tree op2,
+		       tsubst_flags_t complain)
 {
   tree result;
   tree orig_op1 = op1;
@@ -5718,12 +5723,12 @@  tree
     {
       if (type_dependent_expression_p (op1)
 	  || type_dependent_expression_p (op2))
-	return build_min_nt (COMPOUND_EXPR, op1, op2);
+	return build_min_nt_loc (loc, COMPOUND_EXPR, op1, op2);
       op1 = build_non_dependent_expr (op1);
       op2 = build_non_dependent_expr (op2);
     }
 
-  result = build_new_op (input_location, COMPOUND_EXPR, LOOKUP_NORMAL,
+  result = build_new_op (loc, COMPOUND_EXPR, LOOKUP_NORMAL,
 			 op1, op2, NULL_TREE, /*overload=*/NULL, complain);
   if (!result)
     result = cp_build_compound_expr (op1, op2, complain);
@@ -7105,16 +7110,17 @@  cp_build_modify_expr (tree lhs, enum tree_code mod
 }
 
 tree
-build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
-		     tsubst_flags_t complain)
+build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
+		     tree rhs, tsubst_flags_t complain)
 {
   if (processing_template_decl)
-    return build_min_nt (MODOP_EXPR, lhs,
-			 build_min_nt (modifycode, NULL_TREE, NULL_TREE), rhs);
+    return build_min_nt_loc (loc, MODOP_EXPR, lhs,
+			     build_min_nt_loc (loc, modifycode, NULL_TREE,
+					       NULL_TREE), rhs);
 
   if (modifycode != NOP_EXPR)
     {
-      tree rval = build_new_op (input_location, MODIFY_EXPR, LOOKUP_NORMAL,
+      tree rval = build_new_op (loc, MODIFY_EXPR, LOOKUP_NORMAL,
 				lhs, rhs, make_node (modifycode),
 				/*overload=*/NULL, complain);
       if (rval)
Index: gcc/cp/tree.c
===================================================================
--- gcc/cp/tree.c	(revision 187476)
+++ gcc/cp/tree.c	(working copy)
@@ -2025,7 +2025,7 @@  break_out_target_exprs (tree t)
    expressions  */
 
 tree
-build_min_nt (enum tree_code code, ...)
+build_min_nt_loc (location_t loc, enum tree_code code, ...)
 {
   tree t;
   int length;
@@ -2037,6 +2037,7 @@  tree
   va_start (p, code);
 
   t = make_node (code);
+  SET_EXPR_LOCATION (t, loc);
   length = TREE_CODE_LENGTH (code);
 
   for (i = 0; i < length; i++)
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 187476)
+++ gcc/cp/typeck2.c	(working copy)
@@ -1484,7 +1484,7 @@  build_x_arrow (location_t loc, tree expr, tsubst_f
   if (processing_template_decl)
     {
       if (type_dependent_expression_p (expr))
-	return build_min_nt (ARROW_EXPR, expr);
+	return build_min_nt_loc (loc, ARROW_EXPR, expr);
       expr = build_non_dependent_expr (expr);
     }
 
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 187476)
+++ gcc/cp/pt.c	(working copy)
@@ -11968,7 +11968,8 @@  tsubst_qualified_id (tree qualified_id, tree args,
   if (dependent_scope_p (scope))
     {
       if (is_template)
-	expr = build_min_nt (TEMPLATE_ID_EXPR, expr, template_args);
+	expr = build_min_nt_loc (UNKNOWN_LOCATION, TEMPLATE_ID_EXPR,
+				 expr, template_args);
       return build_qualified_name (NULL_TREE, scope, expr,
 				   QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
     }
@@ -12672,7 +12673,8 @@  tsubst_omp_for_iterator (tree t, int i, tree declv
       cond = RECUR (TREE_VEC_ELT (OMP_FOR_COND (t), i));
       incr = TREE_VEC_ELT (OMP_FOR_INCR (t), i);
       if (TREE_CODE (incr) == MODIFY_EXPR)
-	incr = build_x_modify_expr (RECUR (TREE_OPERAND (incr, 0)), NOP_EXPR,
+	incr = build_x_modify_expr (EXPR_LOC_OR_HERE (incr),
+				    RECUR (TREE_OPERAND (incr, 0)), NOP_EXPR,
 				    RECUR (TREE_OPERAND (incr, 1)),
 				    complain);
       else
@@ -13631,7 +13633,8 @@  tsubst_copy_and_build (tree t,
     case ARRAY_REF:
       op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
 						args, complain, in_decl);
-      return build_x_array_ref (op1, RECUR (TREE_OPERAND (t, 1)), complain);
+      return build_x_array_ref (EXPR_LOC_OR_HERE (t), op1,
+				RECUR (TREE_OPERAND (t, 1)), complain);
 
     case SIZEOF_EXPR:
       if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
@@ -13692,7 +13695,8 @@  tsubst_copy_and_build (tree t,
     case MODOP_EXPR:
       {
 	tree r = build_x_modify_expr
-	  (RECUR (TREE_OPERAND (t, 0)),
+	  (EXPR_LOC_OR_HERE (t),
+	   RECUR (TREE_OPERAND (t, 0)),
 	   TREE_CODE (TREE_OPERAND (t, 1)),
 	   RECUR (TREE_OPERAND (t, 2)),
 	   complain);
@@ -13776,7 +13780,8 @@  tsubst_copy_and_build (tree t,
 	complain);
 
     case COMPOUND_EXPR:
-      return build_x_compound_expr (RECUR (TREE_OPERAND (t, 0)),
+      return build_x_compound_expr (EXPR_LOC_OR_HERE (t),
+				    RECUR (TREE_OPERAND (t, 0)),
 				    RECUR (TREE_OPERAND (t, 1)),
                                     complain);
 
@@ -14016,7 +14021,8 @@  tsubst_copy_and_build (tree t,
 	    exp2 = RECUR (TREE_OPERAND (t, 2));
 	  }
 
-	return build_x_conditional_expr (cond, exp1, exp2, complain);
+	return build_x_conditional_expr (EXPR_LOC_OR_HERE (t),
+					 cond, exp1, exp2, complain);
       }
 
     case PSEUDO_DTOR_EXPR:
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 187476)
+++ gcc/cp/semantics.c	(working copy)
@@ -1498,7 +1498,8 @@  finish_mem_initializers (tree mem_inits)
             TREE_VALUE (mem) = error_mark_node;
         }
 
-      add_stmt (build_min_nt (CTOR_INITIALIZER, mem_inits));
+      add_stmt (build_min_nt_loc (UNKNOWN_LOCATION,
+				  CTOR_INITIALIZER, mem_inits));
     }
   else
     emit_mem_initializers (mem_inits);
@@ -4456,7 +4457,8 @@  handle_omp_for_class_iterator (int i, location_t l
 	cond = error_mark_node;
       else
 	{
-	  tree tem = build_x_binary_op (input_location, TREE_CODE (cond),
+	  tree tem = build_x_binary_op (EXPR_LOC_OR_HERE (cond),
+					TREE_CODE (cond),
 					iter, ERROR_MARK,
 					TREE_OPERAND (cond, 1), ERROR_MARK,
 					NULL, tf_warning_or_error);
@@ -4473,7 +4475,7 @@  handle_omp_for_class_iterator (int i, location_t l
       error_at (elocus, "invalid controlling predicate");
       return true;
     }
-  diff = build_x_binary_op (input_location, MINUS_EXPR, TREE_OPERAND (cond, 1),
+  diff = build_x_binary_op (elocus, MINUS_EXPR, TREE_OPERAND (cond, 1),
 			    ERROR_MARK, iter, ERROR_MARK, NULL,
 			    tf_warning_or_error);
   if (error_operand_p (diff))
@@ -4496,7 +4498,8 @@  handle_omp_for_class_iterator (int i, location_t l
 	  incr = error_mark_node;
 	  break;
 	}
-      iter_incr = build_x_unary_op (input_location, TREE_CODE (incr), iter,
+      iter_incr = build_x_unary_op (EXPR_LOC_OR_HERE (incr),
+				    TREE_CODE (incr), iter,
 				    tf_warning_or_error);
       if (error_operand_p (iter_incr))
 	return true;
@@ -4520,7 +4523,8 @@  handle_omp_for_class_iterator (int i, location_t l
 		incr = error_mark_node;
 	      else
 		{
-		  iter_incr = build_x_modify_expr (iter, TREE_CODE (rhs),
+		  iter_incr = build_x_modify_expr (EXPR_LOC_OR_HERE (rhs),
+						   iter, TREE_CODE (rhs),
 						   TREE_OPERAND (rhs, 1),
 						   tf_warning_or_error);
 		  if (error_operand_p (iter_incr))
@@ -4546,14 +4550,16 @@  handle_omp_for_class_iterator (int i, location_t l
 		incr = error_mark_node;
 	      else
 		{
-		  iter_incr = build_x_binary_op (input_location, PLUS_EXPR,
+		  iter_incr = build_x_binary_op (EXPR_LOC_OR_HERE (rhs),
+						 PLUS_EXPR,
 						 TREE_OPERAND (rhs, 0),
 						 ERROR_MARK, iter,
 						 ERROR_MARK, NULL,
 						 tf_warning_or_error);
 		  if (error_operand_p (iter_incr))
 		    return true;
-		  iter_incr = build_x_modify_expr (iter, NOP_EXPR,
+		  iter_incr = build_x_modify_expr (EXPR_LOC_OR_HERE (rhs),
+						   iter, NOP_EXPR,
 						   iter_incr,
 						   tf_warning_or_error);
 		  if (error_operand_p (iter_incr))
@@ -4604,18 +4610,22 @@  handle_omp_for_class_iterator (int i, location_t l
   if (orig_pre_body)
     add_stmt (orig_pre_body);
   if (init != NULL)
-    finish_expr_stmt (build_x_modify_expr (iter, NOP_EXPR, init,
+    finish_expr_stmt (build_x_modify_expr (elocus,
+					   iter, NOP_EXPR, init,
 					   tf_warning_or_error));
   init = build_int_cst (TREE_TYPE (diff), 0);
   if (c && iter_incr == NULL)
     {
-      finish_expr_stmt (build_x_modify_expr (incr_var, NOP_EXPR,
+      finish_expr_stmt (build_x_modify_expr (elocus,
+					     incr_var, NOP_EXPR,
 					     incr, tf_warning_or_error));
       incr = incr_var;
-      iter_incr = build_x_modify_expr (iter, PLUS_EXPR, incr,
+      iter_incr = build_x_modify_expr (elocus,
+				       iter, PLUS_EXPR, incr,
 				       tf_warning_or_error);
     }
-  finish_expr_stmt (build_x_modify_expr (last, NOP_EXPR, init,
+  finish_expr_stmt (build_x_modify_expr (elocus,
+					 last, NOP_EXPR, init,
 					 tf_warning_or_error));
   *pre_body = pop_stmt_list (*pre_body);
 
@@ -4628,11 +4638,13 @@  handle_omp_for_class_iterator (int i, location_t l
   orig_body = *body;
   *body = push_stmt_list ();
   iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), decl, last);
-  iter_init = build_x_modify_expr (iter, PLUS_EXPR, iter_init,
+  iter_init = build_x_modify_expr (elocus,
+				   iter, PLUS_EXPR, iter_init,
 				   tf_warning_or_error);
   iter_init = build1 (NOP_EXPR, void_type_node, iter_init);
   finish_expr_stmt (iter_init);
-  finish_expr_stmt (build_x_modify_expr (last, NOP_EXPR, decl,
+  finish_expr_stmt (build_x_modify_expr (elocus,
+					 last, NOP_EXPR, decl,
 					 tf_warning_or_error));
   add_stmt (orig_body);
   *body = pop_stmt_list (*body);
@@ -4939,7 +4951,8 @@  finish_omp_atomic (enum tree_code code, enum tree_
     {
       if (code == OMP_ATOMIC_READ)
 	{
-	  stmt = build_min_nt (OMP_ATOMIC_READ, orig_lhs);
+	  stmt = build_min_nt_loc (EXPR_LOC_OR_HERE (orig_lhs),
+				   OMP_ATOMIC_READ, orig_lhs);
 	  stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
 	}
       else
@@ -4949,10 +4962,12 @@  finish_omp_atomic (enum tree_code code, enum tree_
 	  else 
 	    stmt = build2 (opcode, void_type_node, orig_lhs, orig_rhs);
 	  if (orig_rhs1)
-	    stmt = build_min_nt (COMPOUND_EXPR, orig_rhs1, stmt);
+	    stmt = build_min_nt_loc (EXPR_LOC_OR_HERE (orig_rhs1),
+				     COMPOUND_EXPR, orig_rhs1, stmt);
 	  if (code != OMP_ATOMIC)
 	    {
-	      stmt = build_min_nt (code, orig_lhs1, stmt);
+	      stmt = build_min_nt_loc (EXPR_LOC_OR_HERE (orig_lhs1),
+				       code, orig_lhs1, stmt);
 	      stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
 	    }
 	}
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c	(revision 187476)
+++ gcc/cp/decl2.c	(working copy)
@@ -350,8 +350,8 @@  grok_array_decl (location_t loc, tree array_expr,
     {
       if (type_dependent_expression_p (array_expr)
 	  || type_dependent_expression_p (index_exp))
-	return build_min_nt (ARRAY_REF, array_expr, index_exp,
-			     NULL_TREE, NULL_TREE);
+	return build_min_nt_loc (loc, ARRAY_REF, array_expr, index_exp,
+				 NULL_TREE, NULL_TREE);
       array_expr = build_non_dependent_expr (array_expr);
       index_exp = build_non_dependent_expr (index_exp);
     }
@@ -1370,8 +1370,8 @@  build_anon_union_vars (tree type, tree object)
 	permerror (input_location, "protected member %q+#D in anonymous union", field);
 
       if (processing_template_decl)
-	ref = build_min_nt (COMPONENT_REF, object,
-			    DECL_NAME (field), NULL_TREE);
+	ref = build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF, object,
+				DECL_NAME (field), NULL_TREE);
       else
 	ref = build_class_member_access_expr (object, field, NULL_TREE,
 					      false, tf_warning_or_error);
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 187476)
+++ gcc/cp/parser.c	(working copy)
@@ -7438,6 +7438,7 @@  cp_parser_question_colon_clause (cp_parser* parser
   tree expr;
   tree assignment_expr;
   struct cp_token *token;
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
 
   /* Consume the `?' token.  */
   cp_lexer_consume_token (parser->lexer);
@@ -7472,7 +7473,7 @@  cp_parser_question_colon_clause (cp_parser* parser
   c_inhibit_evaluation_warnings -= logical_or_expr == truthvalue_true_node;
 
   /* Build the conditional-expression.  */
-  return build_x_conditional_expr (logical_or_expr,
+  return build_x_conditional_expr (loc, logical_or_expr,
 				   expr,
 				   assignment_expr,
                                    tf_warning_or_error);
@@ -7512,11 +7513,11 @@  cp_parser_assignment_expression (cp_parser* parser
 	return cp_parser_question_colon_clause (parser, expr);
       else
 	{
-	  enum tree_code assignment_operator;
+	  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
 
 	  /* If it's an assignment-operator, we're using the second
 	     production.  */
-	  assignment_operator
+	  enum tree_code assignment_operator
 	    = cp_parser_assignment_operator_opt (parser);
 	  if (assignment_operator != ERROR_MARK)
 	    {
@@ -7534,7 +7535,7 @@  cp_parser_assignment_expression (cp_parser* parser
 							      NIC_ASSIGNMENT))
 		return error_mark_node;
 	      /* Build the assignment expression.  */
-	      expr = build_x_modify_expr (expr,
+	      expr = build_x_modify_expr (loc, expr,
 					  assignment_operator,
 					  rhs,
 					  tf_warning_or_error);
@@ -7643,6 +7644,7 @@  static tree
 cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk)
 {
   tree expression = NULL_TREE;
+  location_t loc = UNKNOWN_LOCATION;
 
   while (true)
     {
@@ -7656,7 +7658,7 @@  cp_parser_expression (cp_parser* parser, bool cast
       if (!expression)
 	expression = assignment_expression;
       else
-	expression = build_x_compound_expr (expression,
+	expression = build_x_compound_expr (loc, expression,
 					    assignment_expression,
                                             tf_warning_or_error);
       /* If the next token is not a comma, then we are done with the
@@ -7664,6 +7666,7 @@  cp_parser_expression (cp_parser* parser, bool cast
       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
 	break;
       /* Consume the `,'.  */
+      loc = cp_lexer_peek_token (parser->lexer)->location;
       cp_lexer_consume_token (parser->lexer);
       /* A comma operator cannot appear in a constant-expression.  */
       if (cp_parser_non_integral_constant_expression (parser, NIC_COMMA))
@@ -12499,7 +12502,9 @@  cp_parser_template_id (cp_parser *parser,
 
   /* Build a representation of the specialization.  */
   if (TREE_CODE (templ) == IDENTIFIER_NODE)
-    template_id = build_min_nt (TEMPLATE_ID_EXPR, templ, arguments);
+    template_id = build_min_nt_loc (next_token->location,
+				    TEMPLATE_ID_EXPR,
+				    templ, arguments);
   else if (DECL_TYPE_TEMPLATE_P (templ)
 	   || DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
     {
@@ -26350,7 +26355,8 @@  cp_parser_omp_for_loop (cp_parser *parser, tree cl
 		  cp_parser_parse_definitely (parser);
 		  cp_parser_require (parser, CPP_EQ, RT_EQ);
 		  rhs = cp_parser_assignment_expression (parser, false, NULL);
-		  finish_expr_stmt (build_x_modify_expr (decl, NOP_EXPR,
+		  finish_expr_stmt (build_x_modify_expr (EXPR_LOC_OR_HERE (rhs),
+							 decl, NOP_EXPR,
 							 rhs,
 							 tf_warning_or_error));
 		  add_private_clause = true;
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 187476)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -5685,6 +5685,8 @@  extern bool xvalue_p	                        (cons
 extern bool builtin_valid_in_constant_expr_p    (const_tree);
 extern tree build_min				(enum tree_code, tree, ...);
 extern tree build_min_nt			(enum tree_code, ...);
+extern tree build_min_nt_loc			(location_t, enum tree_code,
+						 ...);
 extern tree build_min_non_dep			(enum tree_code, tree, ...);
 extern tree build_min_non_dep_call_vec		(tree, tree, VEC(tree,gc) *);
 extern tree build_cplus_new			(tree, tree, tsubst_flags_t);
@@ -5813,7 +5815,8 @@  extern tree build_x_binary_op			(location_t,
 						 enum tree_code, tree,
 						 enum tree_code, tree *,
 						 tsubst_flags_t);
-extern tree build_x_array_ref			(tree, tree, tsubst_flags_t);
+extern tree build_x_array_ref			(location_t, tree, tree,
+						 tsubst_flags_t);
 extern tree build_x_unary_op			(location_t,
 						 enum tree_code, tree,
                                                  tsubst_flags_t);
@@ -5822,12 +5825,13 @@  extern tree cp_build_addr_expr_strict		(tree, tsub
 extern tree cp_build_unary_op                   (enum tree_code, tree, int, 
                                                  tsubst_flags_t);
 extern tree unary_complex_lvalue		(enum tree_code, tree);
-extern tree build_x_conditional_expr		(tree, tree, tree, 
+extern tree build_x_conditional_expr		(location_t, tree, tree, tree, 
                                                  tsubst_flags_t);
 extern tree build_x_compound_expr_from_list	(tree, expr_list_kind,
 						 tsubst_flags_t);
 extern tree build_x_compound_expr_from_vec	(VEC(tree,gc) *, const char *);
-extern tree build_x_compound_expr		(tree, tree, tsubst_flags_t);
+extern tree build_x_compound_expr		(location_t, tree, tree,
+						 tsubst_flags_t);
 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);
@@ -5835,7 +5839,8 @@  extern tree build_reinterpret_cast		(tree, tree, 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 build_x_modify_expr			(tree, enum tree_code, tree,
+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,
 						 tsubst_flags_t);