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]

fix garbage in diagnostics


The recent conversion of the C++ front-end to use the new-style
quoting  exposes a bug in c_parse_error().  That routine was wrong in
many respects.  Fixed with this patch.  I do not particularly like the
control flow in c_parser_error(), but the current patch is better than
nothing. 

-- Gaby

2004-10-30  Gabriel Dos Reis  <gdr@integrable-solutions.net>

        * c-common.c (catenate_strings): New.
        (c_parse_error): Use it.  Don't over-escape.

testssuite/
2004-10-30  Gabriel Dos Reis  <gdr@integrable-solutions.net>

        * gcc.dg/20040910-1.c: Adjust regex.

Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.579
diff -p -r1.579 c-common.c
*** c-common.c	18 Oct 2004 22:01:51 -0000	1.579
--- c-common.c	31 Oct 2004 02:07:46 -0000
*************** resort_sorted_fields (void *obj,
*** 5479,5514 ****
  	 resort_field_decl_cmp);
  }
  
  /* Issue the error given by MSGID, indicating that it occurred before
     TOKEN, which had the associated VALUE.  */
  
  void
  c_parse_error (const char *msgid, enum cpp_ttype token, tree value)
  {
!   const char *string = _(msgid);
  
    if (token == CPP_EOF)
!     error ("%s at end of input", string);
    else if (token == CPP_CHAR || token == CPP_WCHAR)
      {
        unsigned int val = TREE_INT_CST_LOW (value);
        const char *const ell = (token == CPP_CHAR) ? "" : "L";
        if (val <= UCHAR_MAX && ISGRAPH (val))
! 	error ("%s before %s'%c'", string, ell, val);
        else
! 	error ("%s before %s'\\x%x'", string, ell, val);
      }
!   else if (token == CPP_STRING
! 	   || token == CPP_WSTRING)
!     error ("%s before string constant", string);
    else if (token == CPP_NUMBER)
!     error ("%s before numeric constant", string);
    else if (token == CPP_NAME)
!     error ("%s before \"%s\"", string, IDENTIFIER_POINTER (value));
    else if (token < N_TTYPES)
!     error ("%s before %qs token", string, cpp_type2name (token));
    else
!     error ("%s", string);
  }
  
  /* Walk a gimplified function and warn for functions whose return value is
--- 5479,5553 ----
  	 resort_field_decl_cmp);
  }
  
+ /* Subroutine of c_parse_error.
+    Return the result of concatenating LHS and RHS. RHS is really
+    a string literal, its first character is indicated by RHS_START and
+    RHS_SIZE is its lenght (including the terminating NUL character).
+ 
+    The caller is responsible for deleting the returned pointer.  */
+ 
+ static char *
+ catenate_strings (const char *lhs, const char *rhs_start, int rhs_size)
+ {
+   const int lhs_size = strlen (lhs);
+   char *result = XNEWVEC (char, lhs_size + rhs_size);
+   strncpy (result, lhs, lhs_size);
+   strncpy (result + lhs_size, rhs_start, rhs_size);
+   return result;
+ }
+ 
  /* Issue the error given by MSGID, indicating that it occurred before
     TOKEN, which had the associated VALUE.  */
  
  void
  c_parse_error (const char *msgid, enum cpp_ttype token, tree value)
  {
! #define catenate_messages(M1, M2) catenate_strings ((M1), (M2), sizeof (M2))
! 
!   char *message = NULL;
  
    if (token == CPP_EOF)
!     message = catenate_messages (msgid, " at end of input");
    else if (token == CPP_CHAR || token == CPP_WCHAR)
      {
        unsigned int val = TREE_INT_CST_LOW (value);
        const char *const ell = (token == CPP_CHAR) ? "" : "L";
        if (val <= UCHAR_MAX && ISGRAPH (val))
!         message = catenate_messages (msgid, " before %s'%c'");
        else
!         message = catenate_messages (msgid, " before %s'\\x%x'");
! 
!       error (message, ell, val);
!       free (message);
!       message = NULL;
      }
!   else if (token == CPP_STRING || token == CPP_WSTRING)
!     message = catenate_messages (msgid, " before string constant");
    else if (token == CPP_NUMBER)
!     message = catenate_messages (msgid, " before numeric constant");
    else if (token == CPP_NAME)
!     {
!       message = catenate_messages (msgid, " before %qs");
!       error (message, IDENTIFIER_POINTER (value));
!       free (message);
!       message = NULL;
!     }
    else if (token < N_TTYPES)
!     {
!       message = catenate_messages (msgid, " before %qs token");
!       error (message, cpp_type2name (token));
!       free (message);
!       message = NULL;
!     }
    else
!     error (msgid);
! 
!   if (message)
!     {
!       error (message);
!       free (message);
!     }
! #undef catenate_messages  
  }
  
  /* Walk a gimplified function and warn for functions whose return value is
Index: testsuite/gcc.dg/20040910-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/20040910-1.c,v
retrieving revision 1.2
diff -p -r1.2 20040910-1.c
*** testsuite/gcc.dg/20040910-1.c	11 Sep 2004 21:17:23 -0000	1.2
--- testsuite/gcc.dg/20040910-1.c	31 Oct 2004 02:08:03 -0000
***************
*** 1,2 ****
  /* Tests error recovery for invalid code.  */
! __attribute__((foo)  int f (){} /* { dg-error "(parse|syntax) error before \"int\"" } */
--- 1,2 ----
  /* Tests error recovery for invalid code.  */
! __attribute__((foo)  int f (){} /* { dg-error "(parse|syntax) error before 'int'" } */


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