This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[CPP] fix some diagnostic locations


The way CPP builds expressions loses track of the locations of
subexpressions. The result is that CPP often points to the wrong
location, typically the end of the line. This patch propagates the
correct locations.

Bootstrapped and regression tested on x86_64-unknown-linux-gnu with
--enable-languages=all,obj-c++.

OK for trunk?


2008-10-31  Manuel López-Ibáñez  <manu@gcc.gnu.org>

libcpp/
	* expr.c (struct op): Add location.
	(_cpp_parse_expr): Propagate locations throught the stack
	of expressions.
	(reduce): Likewise.
	(check_promotion): Use explicit location in errors.
	
testsuite/
	* gcc.dg/cpp/Wsignprom.c: Add column numbers.
	* gcc.dg/cpp/if-mpar.c: Likewise.
Index: gcc/testsuite/gcc.dg/cpp/Wsignprom.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/Wsignprom.c	(revision 141458)
+++ gcc/testsuite/gcc.dg/cpp/Wsignprom.c	(working copy)
@@ -1,26 +1,26 @@
 /* { dg-do preprocess } */
-/* { dg-options "-Wall" } */
+/* { dg-options "-Wall -fshow-column" } */
 
 /* Test that -Wall emits the warnings about integer promotion changing
    the sign of an operand.  */
 
-#if -1 > 0U  /* { dg-warning "changes sign when promoted" } */
+#if -1 > 0U  /* { dg-warning "5:changes sign when promoted" } */
 #endif
 
-#if 0U + -1  /* { dg-warning "changes sign when promoted" } */
+#if 0U + -1  /* { dg-warning "10:changes sign when promoted" } */
 #endif
 
-#if 0U * -1  /* { dg-warning "changes sign when promoted" } */
+#if 0U * -1  /* { dg-warning "10:changes sign when promoted" } */
 #endif
 
-#if 1U / -2  /* { dg-warning "changes sign when promoted" } */
+#if 1U / -2  /* { dg-warning "10:changes sign when promoted" } */
 #endif
 
-#if -1 % 1U  /* { dg-warning "changes sign when promoted" } */
+#if -1 % 1U  /* { dg-warning "5:changes sign when promoted" } */
 #endif
 
-#if 1 ? 0U : -1  /* { dg-warning "changes sign when promoted" } */
+#if 1 ? 0U : -1  /* { dg-warning "14:changes sign when promoted" } */
 #endif
 
-#if 1 ? -1 : 0U  /* { dg-warning "changes sign when promoted" } */
+#if 1 ? -1 : 0U  /* { dg-warning "9:changes sign when promoted" } */
 #endif
Index: gcc/testsuite/gcc.dg/cpp/if-mpar.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/if-mpar.c	(revision 141458)
+++ gcc/testsuite/gcc.dg/cpp/if-mpar.c	(working copy)
@@ -2,23 +2,29 @@
 
 /* Test various combinations of missing parentheses give the correct
    missing parenthesis message.  */
 
 /* { dg-do preprocess } */
+/* { dg-options "-fshow-column" } */
+#if (1          /* { dg-error "5:missing '\\)'" "missing ')' no. 1" } */
+#endif
+
+#if 2 * (3 + 4	/* { dg-error "9:missing '\\)'" "missing ')' no. 2" } */
+#endif
 
-#if (1          /* { dg-error "missing '\\)'" "missing ')' no. 1" } */
+#if (2))	/* { dg-error "8:missing '\\('" "missing '(' no. 1" } */
 #endif
 
-#if 2 * (3 + 4	/* { dg-error "missing '\\)'" "missing ')' no. 2" } */
+#if )		/* { dg-error "5:missing '\\('" "missing '(' no. 2" } */
 #endif
 
-#if (2))	/* { dg-error "missing '\\('" "missing '(' no. 1" } */
+#if 4)		/* { dg-error "6:missing '\\('" "missing '(' no. 3" } */
 #endif
 
-#if )		/* { dg-error "missing '\\('" "missing '(' no. 2" } */
+#if (		/* { dg-error "5:missing '\\)'" "missing ')' no. 3" } */
 #endif
 
-#if 4)		/* { dg-error "missing '\\('" "missing '(' no. 3" } */
+#if ((2 + 3) + 5 /* { dg-error "5:missing '\\)'" "missing ')' no. 3" } */
 #endif
 
-#if (		/* { dg-error "missing '\\)'" "missing ')' no. 3" } */
+#if ((2 + 3 + 5 /* { dg-error "6:missing '\\)'" "missing ')' no. 3" } */
 #endif
Index: libcpp/expr.c
===================================================================
--- libcpp/expr.c	(revision 141458)
+++ libcpp/expr.c	(working copy)
@@ -30,10 +30,11 @@ Boston, MA 02110-1301, USA.  */
 
 struct op
 {
   const cpp_token *token;	/* The token forming op (for diagnostics).  */
   cpp_num value;		/* The value logically "right" of op.  */
+  source_location loc;          /* The location of this value.         */
   enum cpp_ttype op;
 };
 
 /* Some simple utility routines on double integers.  */
 #define num_zerop(num) ((num.low | num.high) == 0)
@@ -873,10 +874,11 @@ _cpp_parse_expr (cpp_reader *pfile, bool
       struct op op;
 
       lex_count++;
       op.token = cpp_get_token (pfile);
       op.op = op.token->type;
+      op.loc = op.token->src_loc;
 
       switch (op.op)
 	{
 	  /* These tokens convert into values.  */
 	case CPP_NUMBER:
@@ -976,10 +978,11 @@ _cpp_parse_expr (cpp_reader *pfile, bool
       if (++top == pfile->op_limit)
 	top = _cpp_expand_op_stack (pfile);
 
       top->op = op.op;
       top->token = op.token;
+      top->loc   = op.token->src_loc;
     }
 
   /* The controlling macro expression is only valid if we called lex 3
      times: <!> <defined expression> and <EOF>.  push_conditional ()
      checks that we are at top-of-file.  */
@@ -1029,50 +1032,57 @@ reduce (cpp_reader *pfile, struct op *to
 	case CPP_UPLUS:
 	case CPP_UMINUS:
 	case CPP_NOT:
 	case CPP_COMPL:
 	  top[-1].value = num_unary_op (pfile, top->value, top->op);
+	  top[-1].loc   = top->loc;
 	  break;
 
 	case CPP_PLUS:
 	case CPP_MINUS:
 	case CPP_RSHIFT:
 	case CPP_LSHIFT:
 	case CPP_COMMA:
 	  top[-1].value = num_binary_op (pfile, top[-1].value,
 					 top->value, top->op);
+	  top[-1].loc   = top->loc;
 	  break;
 
 	case CPP_GREATER:
 	case CPP_LESS:
 	case CPP_GREATER_EQ:
 	case CPP_LESS_EQ:
 	  top[-1].value
 	    = num_inequality_op (pfile, top[-1].value, top->value, top->op);
+	  top[-1].loc   = top->loc;
 	  break;
 
 	case CPP_EQ_EQ:
 	case CPP_NOT_EQ:
 	  top[-1].value
 	    = num_equality_op (pfile, top[-1].value, top->value, top->op);
+	  top[-1].loc   = top->loc;
 	  break;
 
 	case CPP_AND:
 	case CPP_OR:
 	case CPP_XOR:
 	  top[-1].value
 	    = num_bitwise_op (pfile, top[-1].value, top->value, top->op);
+	  top[-1].loc   = top->loc;
 	  break;
 
 	case CPP_MULT:
 	  top[-1].value = num_mul (pfile, top[-1].value, top->value);
+	  top[-1].loc   = top->loc;
 	  break;
 
 	case CPP_DIV:
 	case CPP_MOD:
 	  top[-1].value = num_div_op (pfile, top[-1].value,
 				      top->value, top->op);
+	  top[-1].loc   = top->loc;
 	  break;
 
 	case CPP_OR_OR:
 	  top--;
 	  if (!num_zerop (top->value))
@@ -1080,10 +1090,11 @@ reduce (cpp_reader *pfile, struct op *to
 	  top->value.low = (!num_zerop (top->value)
 			    || !num_zerop (top[1].value));
 	  top->value.high = 0;
 	  top->value.unsignedp = false;
 	  top->value.overflow = false;
+	  top->loc = top[1].loc;
 	  continue;
 
 	case CPP_AND_AND:
 	  top--;
 	  if (num_zerop (top->value))
@@ -1091,31 +1102,39 @@ reduce (cpp_reader *pfile, struct op *to
 	  top->value.low = (!num_zerop (top->value)
 			    && !num_zerop (top[1].value));
 	  top->value.high = 0;
 	  top->value.unsignedp = false;
 	  top->value.overflow = false;
+	  top->loc = top[1].loc;
 	  continue;
 
 	case CPP_OPEN_PAREN:
 	  if (op != CPP_CLOSE_PAREN)
 	    {
-	      cpp_error (pfile, CPP_DL_ERROR, "missing ')' in expression");
+	      cpp_error_with_line (pfile, CPP_DL_ERROR, 
+				   top->token->src_loc,
+				   0, "missing ')' in expression");
 	      return 0;
 	    }
 	  top--;
 	  top->value = top[1].value;
+	  top->loc = top[1].loc;
 	  return top;
 
 	case CPP_COLON:
 	  top -= 2;
 	  if (!num_zerop (top->value))
 	    {
 	      pfile->state.skip_eval--;
 	      top->value = top[1].value;
+	      top->loc = top[1].loc;
 	    }
 	  else
-	    top->value = top[2].value;
+	    {
+	      top->value = top[2].value;
+	      top->loc = top[2].loc;
+	    }
 	  top->value.unsignedp = (top[1].value.unsignedp
 				  || top[2].value.unsignedp);
 	  continue;
 
 	case CPP_QUERY:
@@ -1166,16 +1185,16 @@ check_promotion (cpp_reader *pfile, cons
     return;
 
   if (op->value.unsignedp)
     {
       if (!num_positive (op[-1].value, CPP_OPTION (pfile, precision)))
-	cpp_error (pfile, CPP_DL_WARNING,
-		   "the left operand of \"%s\" changes sign when promoted",
-		   cpp_token_as_text (pfile, op->token));
+	cpp_error_with_line (pfile, CPP_DL_WARNING, op[-1].loc, 0,
+			     "the left operand of \"%s\" changes sign when promoted",
+			     cpp_token_as_text (pfile, op->token));
     }
   else if (!num_positive (op->value, CPP_OPTION (pfile, precision)))
-    cpp_error (pfile, CPP_DL_WARNING,
+    cpp_error_with_line (pfile, CPP_DL_WARNING, op->loc, 0,
 	       "the right operand of \"%s\" changes sign when promoted",
 	       cpp_token_as_text (pfile, op->token));
 }
 
 /* Clears the unused high order bits of the number pointed to by PNUM.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]