[C++ Patch] PR 53152

Paolo Carlini paolo.carlini@oracle.com
Sun May 6 13:16:00 GMT 2012


Hi,

this is about the caret not pointing to the operator in the error 
messages produced by op_error. To fix the problem I'm simply passing 
down from the parser the proper location, via build_x_* and build_op_new 
and this appears to work fine.

In this area - accurate locations - small issues remain (eg,  
build_m_component_ref) but I'd like to resolve first this specific PR 
and then, when time will allow, we'll incrementally make progress.

Booted and tested x86_64-linux.

Thanks,
Paolo.

///////////////
-------------- next part --------------
2012-05-06  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/53152
	* call.c (op_error, build_new_op_1, build_new_op): Add location_t
	parameter.
	(build_conditional_expr_1): Adjust.
	* typeck.c (build_x_indirect_ref, build_x_binary_op,
	build_x_unary_op): Add location_t parameter.
	(rationalize_conditional_expr, build_x_array_ref,
	build_x_compound_expr, cp_build_modify_expr, build_x_modify_expr):
	Adjust.
	* typeck2.c (build_x_arrow): Add location_t parameter.
	* semantics.c (finish_unary_op_expr): Likewise.
	(finish_increment_expr, handle_omp_for_class_iterator): Adjust.
	* decl2.c (grok_array_decl): Add location_t parameter.
	* parser.c (cp_parser_postfix_open_square_expression,
	cp_parser_postfix_dot_deref_expression, cp_parser_unary_expression,
	cp_parser_binary_expression, cp_parser_builtin_offsetof,
	do_range_for_auto_deduction, cp_convert_range_for,
	cp_parser_template_argument, cp_parser_omp_for_cond): Pass the
	location, adjust.
	* pt.c (tsubst_copy_and_build): Adjust.
	* tree.c (maybe_dummy_object): Likewise.
	* cp-tree.h: Update declarations.
-------------- next part --------------
Index: typeck.c
===================================================================
--- typeck.c	(revision 187205)
+++ typeck.c	(working copy)
@@ -2060,7 +2060,8 @@ rationalize_conditional_expr (enum tree_code code,
       gcc_assert (!TREE_SIDE_EFFECTS (op0)
 		  && !TREE_SIDE_EFFECTS (op1));
       return
-	build_conditional_expr (build_x_binary_op ((TREE_CODE (t) == MIN_EXPR
+	build_conditional_expr (build_x_binary_op (input_location,
+						   (TREE_CODE (t) == MIN_EXPR
 						    ? LE_EXPR : GE_EXPR),
 						   op0, TREE_CODE (op0),
 						   op1, TREE_CODE (op1),
@@ -2730,7 +2731,7 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree me
    Must also handle REFERENCE_TYPEs for C++.  */
 
 tree
-build_x_indirect_ref (tree expr, ref_operator errorstring, 
+build_x_indirect_ref (location_t loc, tree expr, ref_operator errorstring, 
                       tsubst_flags_t complain)
 {
   tree orig_expr = expr;
@@ -2746,8 +2747,8 @@ tree
       expr = build_non_dependent_expr (expr);
     }
 
-  rval = build_new_op (INDIRECT_REF, LOOKUP_NORMAL, expr, NULL_TREE,
-		       NULL_TREE, /*overload=*/NULL, complain);
+  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);
 
@@ -3580,8 +3581,9 @@ convert_arguments (tree typelist, VEC(tree,gc) **v
    ARG2_CODE as ERROR_MARK.  */
 
 tree
-build_x_binary_op (enum tree_code code, tree arg1, enum tree_code arg1_code,
-		   tree arg2, enum tree_code arg2_code, tree *overload,
+build_x_binary_op (location_t loc, enum tree_code code, tree arg1,
+		   enum tree_code arg1_code, tree arg2,
+		   enum tree_code arg2_code, tree *overload,
 		   tsubst_flags_t complain)
 {
   tree orig_arg1;
@@ -3603,7 +3605,7 @@ tree
   if (code == DOTSTAR_EXPR)
     expr = build_m_component_ref (arg1, arg2, complain);
   else
-    expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
+    expr = build_new_op (loc, code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
 			 overload, complain);
 
   /* Check for cases such as x+y<<z which users are likely to
@@ -3643,8 +3645,8 @@ build_x_array_ref (tree arg1, tree arg2, tsubst_fl
       arg2 = build_non_dependent_expr (arg2);
     }
 
-  expr = build_new_op (ARRAY_REF, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
-		       /*overload=*/NULL, complain);
+  expr = build_new_op (input_location, ARRAY_REF, LOOKUP_NORMAL, arg1,
+		       arg2, NULL_TREE, /*overload=*/NULL, complain);
 
   if (processing_template_decl && expr != error_mark_node)
     return build_min_non_dep (ARRAY_REF, expr, orig_arg1, orig_arg2,
@@ -4659,7 +4661,8 @@ pointer_diff (tree op0, tree op1, tree ptrtype)
    and XARG is the operand.  */
 
 tree
-build_x_unary_op (enum tree_code code, tree xarg, tsubst_flags_t complain)
+build_x_unary_op (location_t loc, enum tree_code code, tree xarg,
+		  tsubst_flags_t complain)
 {
   tree orig_expr = xarg;
   tree exp;
@@ -4690,8 +4693,8 @@ tree
 	  || (TREE_CODE (xarg) == OFFSET_REF)))
     /* Don't look for a function.  */;
   else
-    exp = build_new_op (code, LOOKUP_NORMAL, xarg, NULL_TREE, NULL_TREE,
-			/*overload=*/NULL, complain);
+    exp = build_new_op (loc, code, LOOKUP_NORMAL, xarg, NULL_TREE,
+			NULL_TREE, /*overload=*/NULL, complain);
   if (!exp && code == ADDR_EXPR)
     {
       if (is_overloaded_fn (xarg))
@@ -5720,8 +5723,8 @@ build_x_compound_expr (tree op1, tree op2, tsubst_
       op2 = build_non_dependent_expr (op2);
     }
 
-  result = build_new_op (COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2, NULL_TREE,
-			 /*overload=*/NULL, complain);
+  result = build_new_op (input_location, COMPOUND_EXPR, LOOKUP_NORMAL,
+			 op1, op2, NULL_TREE, /*overload=*/NULL, complain);
   if (!result)
     result = cp_build_compound_expr (op1, op2, complain);
 
@@ -6909,9 +6912,9 @@ cp_build_modify_expr (tree lhs, enum tree_code mod
 	    /* Do the default thing.  */;
 	  else
 	    {
-	      result = build_new_op (MODIFY_EXPR, LOOKUP_NORMAL,
-				     lhs, rhs, make_node (NOP_EXPR),
-				     /*overload=*/NULL,
+	      result = build_new_op (input_location, MODIFY_EXPR,
+				     LOOKUP_NORMAL, lhs, rhs,
+				     make_node (NOP_EXPR), /*overload=*/NULL,
 				     complain);
 	      if (result == NULL_TREE)
 		return error_mark_node;
@@ -7111,10 +7114,9 @@ build_x_modify_expr (tree lhs, enum tree_code modi
 
   if (modifycode != NOP_EXPR)
     {
-      tree rval = build_new_op (MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs,
-				make_node (modifycode),
-				/*overload=*/NULL,
-				complain);
+      tree rval = build_new_op (input_location, MODIFY_EXPR, LOOKUP_NORMAL,
+				lhs, rhs, make_node (modifycode),
+				/*overload=*/NULL, complain);
       if (rval)
 	{
 	  TREE_NO_WARNING (rval) = 1;
Index: tree.c
===================================================================
--- tree.c	(revision 187205)
+++ tree.c	(working copy)
@@ -2598,8 +2598,8 @@ maybe_dummy_object (tree type, tree* binfop)
 	   && context == nonlambda_method_basetype ())
     /* In a lambda, need to go through 'this' capture.  */
     decl = (build_x_indirect_ref
-	    ((lambda_expr_this_capture
-	      (CLASSTYPE_LAMBDA_EXPR (current_class_type))),
+	    (input_location, (lambda_expr_this_capture
+			      (CLASSTYPE_LAMBDA_EXPR (current_class_type))),
 	     RO_NULL, tf_warning_or_error));
   else
     decl = build_dummy_object (context);
Index: typeck2.c
===================================================================
--- typeck2.c	(revision 187205)
+++ typeck2.c	(working copy)
@@ -1471,7 +1471,7 @@ build_scoped_ref (tree datum, tree basetype, tree*
    delegation is detected.  */
 
 tree
-build_x_arrow (tree expr, tsubst_flags_t complain)
+build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
 {
   tree orig_expr = expr;
   tree type = TREE_TYPE (expr);
@@ -1493,8 +1493,8 @@ tree
       struct tinst_level *actual_inst = current_instantiation ();
       tree fn = NULL;
 
-      while ((expr = build_new_op (COMPONENT_REF, LOOKUP_NORMAL, expr,
-				   NULL_TREE, NULL_TREE,
+      while ((expr = build_new_op (loc, COMPONENT_REF,
+				   LOOKUP_NORMAL, expr, NULL_TREE, NULL_TREE,
 				   &fn, complain)))
 	{
 	  if (expr == error_mark_node)
Index: pt.c
===================================================================
--- pt.c	(revision 187205)
+++ pt.c	(working copy)
@@ -13466,7 +13466,7 @@ tsubst_copy_and_build (tree t,
 	      r = convert_from_reference (r);
 	  }
 	else
-	  r = build_x_indirect_ref (r, RO_UNARY_STAR, complain);
+	  r = build_x_indirect_ref (input_location, r, RO_UNARY_STAR, complain);
 	return r;
       }
 
@@ -13543,7 +13543,7 @@ tsubst_copy_and_build (tree t,
     case POSTINCREMENT_EXPR:
       op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
 						args, complain, in_decl);
-      return build_x_unary_op (TREE_CODE (t), op1, complain);
+      return build_x_unary_op (input_location, TREE_CODE (t), op1, complain);
 
     case PREDECREMENT_EXPR:
     case PREINCREMENT_EXPR:
@@ -13554,8 +13554,8 @@ tsubst_copy_and_build (tree t,
     case UNARY_PLUS_EXPR:  /* Unary + */
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-      return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0)),
-                               complain);
+      return build_x_unary_op (input_location, TREE_CODE (t),
+			       RECUR (TREE_OPERAND (t, 0)), complain);
 
     case FIX_TRUNC_EXPR:
       return cp_build_unary_op (FIX_TRUNC_EXPR, RECUR (TREE_OPERAND (t, 0)),
@@ -13572,7 +13572,7 @@ tsubst_copy_and_build (tree t,
       else
 	op1 = tsubst_non_call_postfix_expression (op1, args, complain,
 						  in_decl);
-      return build_x_unary_op (ADDR_EXPR, op1, complain);
+      return build_x_unary_op (input_location, ADDR_EXPR, op1, complain);
 
     case PLUS_EXPR:
     case MINUS_EXPR:
@@ -13607,7 +13607,7 @@ tsubst_copy_and_build (tree t,
     case DOTSTAR_EXPR:
       {
 	tree r = build_x_binary_op
-	  (TREE_CODE (t),
+	  (input_location, TREE_CODE (t),
 	   RECUR (TREE_OPERAND (t, 0)),
 	   (TREE_NO_WARNING (TREE_OPERAND (t, 0))
 	    ? ERROR_MARK
@@ -13711,7 +13711,7 @@ tsubst_copy_and_build (tree t,
       /* Remember that there was a reference to this entity.  */
       if (DECL_P (op1))
 	mark_used (op1);
-      return build_x_arrow (op1, complain);
+      return build_x_arrow (input_location, op1, complain);
 
     case NEW_EXPR:
       {
Index: semantics.c
===================================================================
--- semantics.c	(revision 187205)
+++ semantics.c	(working copy)
@@ -2224,7 +2224,7 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bo
 tree
 finish_increment_expr (tree expr, enum tree_code code)
 {
-  return build_x_unary_op (code, expr, tf_warning_or_error);
+  return build_x_unary_op (input_location, code, expr, tf_warning_or_error);
 }
 
 /* Finish a use of `this'.  Returns an expression for `this'.  */
@@ -2318,9 +2318,9 @@ finish_pseudo_destructor_expr (tree object, tree s
 /* Finish an expression of the form CODE EXPR.  */
 
 tree
-finish_unary_op_expr (enum tree_code code, tree expr)
+finish_unary_op_expr (location_t loc, enum tree_code code, tree expr)
 {
-  tree result = build_x_unary_op (code, expr, tf_warning_or_error);
+  tree result = build_x_unary_op (loc, code, expr, tf_warning_or_error);
   if (TREE_OVERFLOW_P (result) && !TREE_OVERFLOW_P (expr))
     overflow_warning (input_location, result);
 
@@ -4456,7 +4456,8 @@ handle_omp_for_class_iterator (int i, location_t l
 	cond = error_mark_node;
       else
 	{
-	  tree tem = build_x_binary_op (TREE_CODE (cond), iter, ERROR_MARK,
+	  tree tem = build_x_binary_op (input_location, TREE_CODE (cond),
+					iter, ERROR_MARK,
 					TREE_OPERAND (cond, 1), ERROR_MARK,
 					NULL, tf_warning_or_error);
 	  if (error_operand_p (tem))
@@ -4472,7 +4473,7 @@ handle_omp_for_class_iterator (int i, location_t l
       error_at (elocus, "invalid controlling predicate");
       return true;
     }
-  diff = build_x_binary_op (MINUS_EXPR, TREE_OPERAND (cond, 1),
+  diff = build_x_binary_op (input_location, MINUS_EXPR, TREE_OPERAND (cond, 1),
 			    ERROR_MARK, iter, ERROR_MARK, NULL,
 			    tf_warning_or_error);
   if (error_operand_p (diff))
@@ -4495,7 +4496,7 @@ handle_omp_for_class_iterator (int i, location_t l
 	  incr = error_mark_node;
 	  break;
 	}
-      iter_incr = build_x_unary_op (TREE_CODE (incr), iter,
+      iter_incr = build_x_unary_op (input_location, TREE_CODE (incr), iter,
 				    tf_warning_or_error);
       if (error_operand_p (iter_incr))
 	return true;
@@ -4545,7 +4546,7 @@ handle_omp_for_class_iterator (int i, location_t l
 		incr = error_mark_node;
 	      else
 		{
-		  iter_incr = build_x_binary_op (PLUS_EXPR,
+		  iter_incr = build_x_binary_op (input_location, PLUS_EXPR,
 						 TREE_OPERAND (rhs, 0),
 						 ERROR_MARK, iter,
 						 ERROR_MARK, NULL,
Index: decl2.c
===================================================================
--- decl2.c	(revision 187205)
+++ decl2.c	(working copy)
@@ -336,7 +336,7 @@ grokclassfn (tree ctype, tree function, enum overl
    along the way.  */
 
 tree
-grok_array_decl (tree array_expr, tree index_exp)
+grok_array_decl (location_t loc, tree array_expr, tree index_exp)
 {
   tree type;
   tree expr;
@@ -362,7 +362,7 @@ tree
 
   /* If they have an `operator[]', use that.  */
   if (MAYBE_CLASS_TYPE_P (type) || MAYBE_CLASS_TYPE_P (TREE_TYPE (index_exp)))
-    expr = build_new_op (ARRAY_REF, LOOKUP_NORMAL,
+    expr = build_new_op (loc, ARRAY_REF, LOOKUP_NORMAL,
 			 array_expr, index_exp, NULL_TREE,
 			 /*overload=*/NULL, tf_warning_or_error);
   else
Index: parser.c
===================================================================
--- parser.c	(revision 187205)
+++ parser.c	(working copy)
@@ -5850,6 +5850,7 @@ cp_parser_postfix_open_square_expression (cp_parse
 					  bool for_offsetof)
 {
   tree index;
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
 
   /* Consume the `[' token.  */
   cp_lexer_consume_token (parser->lexer);
@@ -5880,7 +5881,7 @@ cp_parser_postfix_open_square_expression (cp_parse
   cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
 
   /* Build the ARRAY_REF.  */
-  postfix_expression = grok_array_decl (postfix_expression, index);
+  postfix_expression = grok_array_decl (loc, postfix_expression, index);
 
   /* When not doing offsetof, array references are not permitted in
      constant-expressions.  */
@@ -5918,7 +5919,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser
 
   /* If this is a `->' operator, dereference the pointer.  */
   if (token_type == CPP_DEREF)
-    postfix_expression = build_x_arrow (postfix_expression,
+    postfix_expression = build_x_arrow (location, postfix_expression,
 					tf_warning_or_error);
   /* Check to see whether or not the expression is type-dependent.  */
   dependent_p = type_dependent_expression_p (postfix_expression);
@@ -6435,7 +6436,8 @@ cp_parser_unary_expression (cp_parser *parser, boo
 	    /* Parse the cast-expression.  */
 	    expression = cp_parser_simple_cast_expression (parser);
 	    /* Create the complete representation.  */
-	    return build_x_unary_op ((keyword == RID_REALPART
+	    return build_x_unary_op (token->location,
+				     (keyword == RID_REALPART
 				      ? REALPART_EXPR : IMAGPART_EXPR),
 				     expression,
                                      tf_warning_or_error);
@@ -6531,7 +6533,7 @@ cp_parser_unary_expression (cp_parser *parser, boo
 	{
 	  tree identifier;
 	  tree expression;
-	  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+	  location_t loc = token->location;
 
 	  /* Consume the '&&' token.  */
 	  cp_lexer_consume_token (parser->lexer);
@@ -6550,6 +6552,7 @@ cp_parser_unary_expression (cp_parser *parser, boo
       tree cast_expression;
       tree expression = error_mark_node;
       non_integral_constant non_constant_p = NIC_NONE;
+      location_t loc = token->location;
 
       /* Consume the operator token.  */
       token = cp_lexer_consume_token (parser->lexer);
@@ -6563,7 +6566,8 @@ cp_parser_unary_expression (cp_parser *parser, boo
 	{
 	case INDIRECT_REF:
 	  non_constant_p = NIC_STAR;
-	  expression = build_x_indirect_ref (cast_expression, RO_UNARY_STAR,
+	  expression = build_x_indirect_ref (loc, cast_expression,
+					     RO_UNARY_STAR,
                                              tf_warning_or_error);
 	  break;
 
@@ -6571,7 +6575,8 @@ cp_parser_unary_expression (cp_parser *parser, boo
 	   non_constant_p = NIC_ADDR;
 	  /* Fall through.  */
 	case BIT_NOT_EXPR:
-	  expression = build_x_unary_op (unary_operator, cast_expression,
+	  expression = build_x_unary_op (loc, unary_operator,
+					 cast_expression,
                                          tf_warning_or_error);
 	  break;
 
@@ -6583,7 +6588,8 @@ cp_parser_unary_expression (cp_parser *parser, boo
 	case UNARY_PLUS_EXPR:
 	case NEGATE_EXPR:
 	case TRUTH_NOT_EXPR:
-	  expression = finish_unary_op_expr (unary_operator, cast_expression);
+	  expression = finish_unary_op_expr (loc, unary_operator,
+					     cast_expression);
 	  break;
 
 	default:
@@ -7271,6 +7277,7 @@ cp_parser_binary_expression (cp_parser* parser, bo
   cp_parser_expression_stack_entry *sp = &stack[0];
   tree lhs, rhs;
   cp_token *token;
+  location_t loc;
   enum tree_code tree_type, lhs_type, rhs_type;
   enum cp_parser_prec new_prec, lookahead_prec;
   tree overload;
@@ -7283,16 +7290,15 @@ cp_parser_binary_expression (cp_parser* parser, bo
     {
       /* Get an operator token.  */
       token = cp_lexer_peek_token (parser->lexer);
+      loc = token->location;
 
       if (warn_cxx0x_compat
           && token->type == CPP_RSHIFT
           && !parser->greater_than_is_operator_p)
         {
-          if (warning_at (token->location, OPT_Wc__0x_compat, 
-			  "%<>>%> operator is treated as"
-			  " two right angle brackets in C++11"))
-	    inform (token->location,
-		    "suggest parentheses around %<>>%> expression");
+          if (warning_at (loc, OPT_Wc__0x_compat, "%<>>%> operator is treated"
+			  " as two right angle brackets in C++11"))
+	    inform (loc, "suggest parentheses around %<>>%> expression");
         }
 
       new_prec = TOKEN_PRECEDENCE (token);
@@ -7390,7 +7396,7 @@ cp_parser_binary_expression (cp_parser* parser, bo
 	  && TREE_CODE_CLASS (tree_type) == tcc_comparison)
 	lhs = build2 (tree_type, boolean_type_node, lhs, rhs);
       else
-	lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type,
+	lhs = build_x_binary_op (loc, tree_type, lhs, lhs_type, rhs, rhs_type,
 				 &overload, tf_warning_or_error);
       lhs_type = tree_type;
 
@@ -7798,7 +7804,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
 
 	case CPP_DEREF:
 	  /* offsetof-member-designator "->" identifier */
-	  expr = grok_array_decl (expr, integer_zero_node);
+	  expr = grok_array_decl (token->location, expr, integer_zero_node);
 	  /* FALLTHRU */
 
 	case CPP_DOT:
@@ -9407,7 +9413,7 @@ do_range_for_auto_deduction (tree decl, tree range
       iter_type = (cp_parser_perform_range_for_lookup
 		   (range_temp, &begin_dummy, &end_dummy));
       iter_decl = build_decl (input_location, VAR_DECL, NULL_TREE, iter_type);
-      iter_decl = build_x_indirect_ref (iter_decl, RO_NULL,
+      iter_decl = build_x_indirect_ref (input_location, iter_decl, RO_NULL,
 					tf_warning_or_error);
       TREE_TYPE (decl) = do_auto_deduction (TREE_TYPE (decl),
 					    iter_decl, auto_node);
@@ -9495,19 +9501,21 @@ cp_convert_range_for (tree statement, tree range_d
   finish_for_init_stmt (statement);
 
   /* The new for condition.  */
-  condition = build_x_binary_op (NE_EXPR,
+  condition = build_x_binary_op (input_location, NE_EXPR,
 				 begin, ERROR_MARK,
 				 end, ERROR_MARK,
 				 NULL, tf_warning_or_error);
   finish_for_cond (condition, statement);
 
   /* The new increment expression.  */
-  expression = finish_unary_op_expr (PREINCREMENT_EXPR, begin);
+  expression = finish_unary_op_expr (input_location,
+				     PREINCREMENT_EXPR, begin);
   finish_for_expr (expression, statement);
 
   /* The declaration is initialized with *__begin inside the loop body.  */
   cp_finish_decl (range_decl,
-		  build_x_indirect_ref (begin, RO_NULL, tf_warning_or_error),
+		  build_x_indirect_ref (input_location, begin, RO_NULL,
+					tf_warning_or_error),
 		  /*is_constant_init*/false, NULL_TREE,
 		  LOOKUP_ONLYCONVERTING);
 
@@ -12858,6 +12866,7 @@ cp_parser_template_argument (cp_parser* parser)
   bool address_p;
   bool maybe_type_id = false;
   cp_token *token = NULL, *argument_start_token = NULL;
+  location_t loc = 0;
   cp_id_kind idk;
 
   /* There's really no way to know what we're looking at, so we just
@@ -12973,7 +12982,10 @@ cp_parser_template_argument (cp_parser* parser)
      object or function with external linkage.  */
   address_p = cp_lexer_next_token_is (parser->lexer, CPP_AND);
   if (address_p)
-    cp_lexer_consume_token (parser->lexer);
+    {
+      loc = cp_lexer_peek_token (parser->lexer)->location;
+      cp_lexer_consume_token (parser->lexer);
+    }
   /* See if we might have an id-expression.  */
   token = cp_lexer_peek_token (parser->lexer);
   if (token->type == CPP_NAME
@@ -13033,8 +13045,8 @@ cp_parser_template_argument (cp_parser* parser)
 	  if (cp_parser_parse_definitely (parser))
 	    {
 	      if (address_p)
-		argument = build_x_unary_op (ADDR_EXPR, argument,
-                                             tf_warning_or_error);
+		argument = build_x_unary_op (loc, ADDR_EXPR, argument,
+					     tf_warning_or_error);
 	      return argument;
 	    }
 	}
@@ -26062,7 +26074,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree de
 	  || CLASS_TYPE_P (TREE_TYPE (decl))))
     return cond;
 
-  return build_x_binary_op (TREE_CODE (cond),
+  return build_x_binary_op (input_location, TREE_CODE (cond),
 			    TREE_OPERAND (cond, 0), ERROR_MARK,
 			    TREE_OPERAND (cond, 1), ERROR_MARK,
 			    /*overload=*/NULL, tf_warning_or_error);
@@ -26138,11 +26150,12 @@ cp_parser_omp_for_incr (cp_parser *parser, tree de
 	      if (op == PLUS_EXPR)
 		lhs = rhs;
 	      else
-		lhs = build_x_unary_op (NEGATE_EXPR, rhs, tf_warning_or_error);
+		lhs = build_x_unary_op (input_location, NEGATE_EXPR, rhs,
+					tf_warning_or_error);
 	    }
 	  else
-	    lhs = build_x_binary_op (op, lhs, ERROR_MARK, rhs, ERROR_MARK,
-				     NULL, tf_warning_or_error);
+	    lhs = build_x_binary_op (input_location, op, lhs, ERROR_MARK, rhs,
+				     ERROR_MARK, NULL, tf_warning_or_error);
 	}
     }
   while (token->type == CPP_PLUS || token->type == CPP_MINUS);
Index: call.c
===================================================================
--- call.c	(revision 187205)
+++ call.c	(working copy)
@@ -159,8 +159,8 @@ static tree build_java_interface_fn_ref (tree, tre
 		     /*c_cast_p=*/false, (COMPLAIN))
 static tree convert_like_real (conversion *, tree, tree, int, int, bool,
 			       bool, tsubst_flags_t);
-static void op_error (enum tree_code, enum tree_code, tree, tree,
-		      tree, bool);
+static void op_error (location_t, enum tree_code, enum tree_code, tree,
+		      tree, tree, bool);
 static struct z_candidate *build_user_type_conversion_1 (tree, tree, int,
 							 tsubst_flags_t);
 static void print_z_candidate (const char *, struct z_candidate *);
@@ -4200,7 +4200,7 @@ op_error_string (const char *errmsg, int ntypes, b
 }
 
 static void
-op_error (enum tree_code code, enum tree_code code2,
+op_error (location_t loc, enum tree_code code, enum tree_code code2,
 	  tree arg1, tree arg2, tree arg3, bool match)
 {
   const char *opname;
@@ -4214,62 +4214,65 @@ static void
     {
     case COND_EXPR:
       if (flag_diagnostics_show_caret)
-	error (op_error_string (G_("ternary %<operator?:%>"), 3, match),
-	       TREE_TYPE (arg1), TREE_TYPE (arg2), TREE_TYPE (arg3));
+	error_at (loc, op_error_string (G_("ternary %<operator?:%>"),
+					3, match),
+		  TREE_TYPE (arg1), TREE_TYPE (arg2), TREE_TYPE (arg3));
       else
-	error (op_error_string (G_("ternary %<operator?:%> "
-				   "in %<%E ? %E : %E%>"), 3, match),
-	       arg1, arg2, arg3,
-	       TREE_TYPE (arg1), TREE_TYPE (arg2), TREE_TYPE (arg3));
+	error_at (loc, op_error_string (G_("ternary %<operator?:%> "
+					   "in %<%E ? %E : %E%>"), 3, match),
+		  arg1, arg2, arg3,
+		  TREE_TYPE (arg1), TREE_TYPE (arg2), TREE_TYPE (arg3));
       break;
 
     case POSTINCREMENT_EXPR:
     case POSTDECREMENT_EXPR:
       if (flag_diagnostics_show_caret)
-	error (op_error_string (G_("%<operator%s%>"), 1, match),
-	       opname, TREE_TYPE (arg1));
+	error_at (loc, op_error_string (G_("%<operator%s%>"), 1, match),
+		  opname, TREE_TYPE (arg1));
       else
-	error (op_error_string (G_("%<operator%s%> in %<%E%s%>"), 1, match),
-	       opname, arg1, opname, TREE_TYPE (arg1));
+	error_at (loc, op_error_string (G_("%<operator%s%> in %<%E%s%>"),
+					1, match),
+		  opname, arg1, opname, TREE_TYPE (arg1));
       break;
 
     case ARRAY_REF:
       if (flag_diagnostics_show_caret)
-	error (op_error_string (G_("%<operator[]%>"), 2, match),
-	       TREE_TYPE (arg1), TREE_TYPE (arg2));
+	error_at (loc, op_error_string (G_("%<operator[]%>"), 2, match),
+		  TREE_TYPE (arg1), TREE_TYPE (arg2));
       else
-	error (op_error_string (G_("%<operator[]%> in %<%E[%E]%>"), 2, match),
-	       arg1, arg2, TREE_TYPE (arg1), TREE_TYPE (arg2));
+	error_at (loc, op_error_string (G_("%<operator[]%> in %<%E[%E]%>"),
+					2, match),
+		  arg1, arg2, TREE_TYPE (arg1), TREE_TYPE (arg2));
       break;
 
     case REALPART_EXPR:
     case IMAGPART_EXPR:
       if (flag_diagnostics_show_caret)
-	error (op_error_string (G_("%qs"), 1, match),
-	       opname, TREE_TYPE (arg1));
+	error_at (loc, op_error_string (G_("%qs"), 1, match),
+		  opname, TREE_TYPE (arg1));
       else
-	error (op_error_string (G_("%qs in %<%s %E%>"), 1, match),
-	       opname, opname, arg1, TREE_TYPE (arg1));
+	error_at (loc, op_error_string (G_("%qs in %<%s %E%>"), 1, match),
+		  opname, opname, arg1, TREE_TYPE (arg1));
       break;
 
     default:
       if (arg2)
 	if (flag_diagnostics_show_caret)
-	  error (op_error_string (G_("%<operator%s%>"), 2, match),
-		 opname, TREE_TYPE (arg1), TREE_TYPE (arg2));
+	  error_at (loc, op_error_string (G_("%<operator%s%>"), 2, match),
+		    opname, TREE_TYPE (arg1), TREE_TYPE (arg2));
 	else
-	  error (op_error_string (G_("%<operator%s%> in %<%E %s %E%>"),
-				  2, match),
-		 opname, arg1, opname, arg2,
-		 TREE_TYPE (arg1), TREE_TYPE (arg2));
+	  error_at (loc, op_error_string (G_("%<operator%s%> in %<%E %s %E%>"),
+					  2, match),
+		    opname, arg1, opname, arg2,
+		    TREE_TYPE (arg1), TREE_TYPE (arg2));
       else
 	if (flag_diagnostics_show_caret)
-	  error (op_error_string (G_("%<operator%s%>"), 1, match),
-		 opname, TREE_TYPE (arg1));
+	  error_at (loc, op_error_string (G_("%<operator%s%>"), 1, match),
+		    opname, TREE_TYPE (arg1));
 	else
-	  error (op_error_string (G_("%<operator%s%> in %<%s%E%>"),
-				  1, match),
-		 opname, opname, arg1, TREE_TYPE (arg1));
+	  error_at (loc, op_error_string (G_("%<operator%s%> in %<%s%E%>"),
+					  1, match),
+		    opname, opname, arg1, TREE_TYPE (arg1));
       break;
     }
 }
@@ -4607,7 +4610,8 @@ build_conditional_expr_1 (tree arg1, tree arg2, tr
 	{
           if (complain & tf_error)
             {
-              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
+              op_error (input_location, COND_EXPR, NOP_EXPR,
+			arg1, arg2, arg3, FALSE);
               print_z_candidates (location_of (arg1), candidates);
             }
 	  return error_mark_node;
@@ -4617,7 +4621,8 @@ build_conditional_expr_1 (tree arg1, tree arg2, tr
 	{
           if (complain & tf_error)
             {
-              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
+              op_error (input_location, COND_EXPR, NOP_EXPR,
+			arg1, arg2, arg3, FALSE);
               print_z_candidates (location_of (arg1), candidates);
             }
 	  return error_mark_node;
@@ -4944,8 +4949,8 @@ add_candidates (tree fns, tree first_arg, const VE
 }
 
 static tree
-build_new_op_1 (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
-		tree *overload, tsubst_flags_t complain)
+build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
+		tree arg2, tree arg3, tree *overload, tsubst_flags_t complain)
 {
   struct z_candidate *candidates = 0, *cand;
   VEC(tree,gc) *arglist;
@@ -5098,8 +5103,7 @@ static tree
 		? G_("no %<%D(int)%> declared for postfix %qs,"
 		     " trying prefix operator instead")
 		: G_("no %<%D(int)%> declared for postfix %qs");
-	      permerror (input_location, msg, fnname,
-			 operator_name_info[code].name);
+	      permerror (loc, msg, fnname, operator_name_info[code].name);
 	    }
 
 	  if (!flag_permissive)
@@ -5109,8 +5113,8 @@ static tree
 	    code = PREINCREMENT_EXPR;
 	  else
 	    code = PREDECREMENT_EXPR;
-	  result = build_new_op_1 (code, flags, arg1, NULL_TREE, NULL_TREE,
-				   overload, complain);
+	  result = build_new_op_1 (loc, code, flags, arg1, NULL_TREE,
+				   NULL_TREE, overload, complain);
 	  break;
 
 	  /* The caller will deal with these.  */
@@ -5135,8 +5139,8 @@ static tree
 		  {
 		    /* ... Otherwise, report the more generic
 		       "no matching operator found" error */
-		    op_error (code, code2, arg1, arg2, arg3, FALSE);
-		    print_z_candidates (input_location, candidates);
+		    op_error (loc, code, code2, arg1, arg2, arg3, FALSE);
+		    print_z_candidates (loc, candidates);
 		  }
 	    }
 	  result = error_mark_node;
@@ -5150,8 +5154,8 @@ static tree
 	{
 	  if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
 	    {
-	      op_error (code, code2, arg1, arg2, arg3, TRUE);
-	      print_z_candidates (input_location, candidates);
+	      op_error (loc, code, code2, arg1, arg2, arg3, TRUE);
+	      print_z_candidates (loc, candidates);
 	    }
 	  result = error_mark_node;
 	}
@@ -5213,7 +5217,7 @@ static tree
 	      /* We need to call warn_logical_operator before
 		 converting arg2 to a boolean_type.  */
 	      if (complain & tf_warning)
-		warn_logical_operator (input_location, code, boolean_type_node,
+		warn_logical_operator (loc, code, boolean_type_node,
 				       code_orig_arg1, arg1,
 				       code_orig_arg2, arg2);
 
@@ -5254,7 +5258,7 @@ static tree
     case TRUTH_ORIF_EXPR:
     case TRUTH_AND_EXPR:
     case TRUTH_OR_EXPR:
-      warn_logical_operator (input_location, code, boolean_type_node,
+      warn_logical_operator (loc, code, boolean_type_node,
 			     code_orig_arg1, arg1, code_orig_arg2, arg2);
       /* Fall through.  */
     case PLUS_EXPR:
@@ -5313,12 +5317,14 @@ static tree
 /* Wrapper for above.  */
 
 tree
-build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
+build_new_op (location_t loc, enum tree_code code, int flags,
+	      tree arg1, tree arg2, tree arg3,
 	      tree *overload, tsubst_flags_t complain)
 {
   tree ret;
   bool subtime = timevar_cond_start (TV_OVERLOAD);
-  ret = build_new_op_1 (code, flags, arg1, arg2, arg3, overload, complain);
+  ret = build_new_op_1 (loc, code, flags, arg1, arg2, arg3,
+			overload, complain);
   timevar_cond_stop (TV_OVERLOAD, subtime);
   return ret;
 }
Index: cp-tree.h
===================================================================
--- cp-tree.h	(revision 187205)
+++ cp-tree.h	(working copy)
@@ -4874,8 +4874,8 @@ extern tree build_new_method_call		(tree, tree, VE
 						 tsubst_flags_t);
 extern tree build_special_member_call		(tree, tree, VEC(tree,gc) **,
 						 tree, int, tsubst_flags_t);
-extern tree build_new_op			(enum tree_code, int, tree, 
-						 tree, tree, tree *,
+extern tree build_new_op			(location_t, enum tree_code,
+						 int, tree, tree, tree, tree *,
 						 tsubst_flags_t);
 extern tree build_op_call			(tree, VEC(tree,gc) **,
 						 tsubst_flags_t);
@@ -5112,7 +5112,7 @@ extern void maybe_make_one_only			(tree);
 extern bool vague_linkage_p			(tree);
 extern void grokclassfn				(tree, tree,
 						 enum overload_flags);
-extern tree grok_array_decl			(tree, tree);
+extern tree grok_array_decl			(location_t, tree, tree);
 extern tree delete_sanity			(tree, tree, bool, int, tsubst_flags_t);
 extern tree check_classfn			(tree, tree, tree);
 extern void check_member_template		(tree);
@@ -5564,7 +5564,7 @@ extern tree finish_call_expr			(tree, VEC(tree,gc)
 extern tree finish_increment_expr		(tree, enum tree_code);
 extern tree finish_this_expr			(void);
 extern tree finish_pseudo_destructor_expr       (tree, tree, tree);
-extern tree finish_unary_op_expr		(enum tree_code, tree);
+extern tree finish_unary_op_expr		(location_t, enum tree_code, tree);
 extern tree finish_compound_literal		(tree, tree, tsubst_flags_t);
 extern tree finish_fname			(tree);
 extern void finish_translation_unit		(void);
@@ -5791,8 +5791,8 @@ extern tree build_class_member_access_expr      (t
 						 tsubst_flags_t);
 extern tree finish_class_member_access_expr     (tree, tree, bool, 
 						 tsubst_flags_t);
-extern tree build_x_indirect_ref		(tree, ref_operator, 
-                                                 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,
                                                  tsubst_flags_t);
 extern tree build_array_ref			(location_t, tree, tree);
@@ -5804,12 +5804,14 @@ extern tree cp_build_function_call_nary         (t
 						ATTRIBUTE_SENTINEL;
 extern tree cp_build_function_call_vec		(tree, VEC(tree,gc) **,
 						 tsubst_flags_t);
-extern tree build_x_binary_op			(enum tree_code, tree,
+extern tree build_x_binary_op			(location_t,
 						 enum tree_code, tree,
+						 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_unary_op			(enum tree_code, tree,
+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_addr_expr_strict		(tree, tsubst_flags_t);
@@ -5898,7 +5900,8 @@ extern void check_narrowing			(tree, tree);
 extern tree digest_init				(tree, tree, tsubst_flags_t);
 extern tree digest_init_flags			(tree, tree, int);
 extern tree build_scoped_ref			(tree, tree, tree *);
-extern tree build_x_arrow			(tree, tsubst_flags_t);
+extern tree build_x_arrow			(location_t, tree,
+						 tsubst_flags_t);
 extern tree build_m_component_ref		(tree, tree, tsubst_flags_t);
 extern tree build_functional_cast		(tree, tree, tsubst_flags_t);
 extern tree add_exception_specifier		(tree, tree, int);


More information about the Gcc-patches mailing list