This is the mail archive of the gcc-bugs@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]

Re: Warning from cpp on macro argument stringification is missing


 > From: Neil Booth <NeilB@earthling.net>
 > 
 > [...]
 > I hope this is of some help.  If you're almost there, send me a patch
 > and I'll help you finish it off.
 > Neil.

Thanks, your info was helpful.


 > 
 > From: Zack Weinberg <zack@wolery.cumb.org>
 > 
 > You shouldn't need to split up the string.  Something like this should
 > do fine:
 > 
 >    U_CHAR *p, *q;
 >    for (p = string; p < limit; p = q) {
 >      while(!is_idstart(*p)) p++;
 >      q = p;
 >      while(is_idchar(*q)) q++;
 >      for(i = 0; i < nargs; i++)
 >        if(argv[i].len == q - p && !memcmp(p, argv[i].str, q - p))
 > 	  issue warning;
 >    }
 > 
 > - flesh out with checks for running off the end of the string as
 > appropriate.  IIRC, ->val.str.text is not nul-terminated.
 > zw

Thanks, that made it go much easier. :-)

I wrote a patch which seems to work.  Given the following input:

 > #define foo(h) sdf sdf sdf "h" fds fds fds
 > #define foo2(j) "j"
 > #define bar(h) sdf sdf sdf 'h' fds fds fds
 > #define baz(A, hello, E) sdf "A B hello C,hello,DhelloE F" fds

With "gcc -E -Wtraditional" I get:

 > # 1 "f.c"
 > f.c:1:12: warning: checking string `h', nparams=1
 > f.c:1:12: warning: checking string subtoken `h' vs arg `h'
 > f.c:1:12: warning: macro arg `h' would be stringified with -traditional.
 >  
 > f.c:2:13: warning: checking string `j', nparams=1
 > f.c:2:13: warning: checking string subtoken `j' vs arg `j'
 > f.c:2:13: warning: macro arg `j' would be stringified with -traditional.
 >  
 > f.c:3:12: warning: checking string `h', nparams=1
 > f.c:3:12: warning: checking string subtoken `h' vs arg `h'
 > f.c:3:12: warning: macro arg `h' would be stringified with -traditional.
 >  
 > f.c:4:12: warning: checking string `A B hello C,hello,DhelloE F', nparams=3
 > f.c:4:12: warning: checking string subtoken `A' vs arg `A'
 > f.c:4:12: warning: macro arg `A' would be stringified with -traditional.
 > f.c:4:12: warning: checking string subtoken `B' vs arg `A'
 > f.c:4:12: warning: checking string subtoken `B' vs arg `hello'
 > f.c:4:12: warning: checking string subtoken `B' vs arg `E'
 > f.c:4:12: warning: checking string subtoken `hello' vs arg `A'
 > f.c:4:12: warning: checking string subtoken `hello' vs arg `hello'
 > f.c:4:12: warning: macro arg `hello' would be stringified with -traditional.
 > f.c:4:12: warning: checking string subtoken `C' vs arg `A'
 > f.c:4:12: warning: checking string subtoken `C' vs arg `hello'
 > f.c:4:12: warning: checking string subtoken `C' vs arg `E'
 > f.c:4:12: warning: checking string subtoken `hello' vs arg `A'
 > f.c:4:12: warning: checking string subtoken `hello' vs arg `hello'
 > f.c:4:12: warning: macro arg `hello' would be stringified with -traditional.
 > f.c:4:12: warning: checking string subtoken `DhelloE' vs arg `A'
 > f.c:4:12: warning: checking string subtoken `DhelloE' vs arg `hello'
 > f.c:4:12: warning: checking string subtoken `DhelloE' vs arg `E'
 > f.c:4:12: warning: checking string subtoken `F' vs arg `A'
 > f.c:4:12: warning: checking string subtoken `F' vs arg `hello'
 > f.c:4:12: warning: checking string subtoken `F' vs arg `E'

and the above seems correct.

Here's the patch so far.  It isn't quite ready for prime time, I have
the debugging prints still in there and there's no ChangeLog and I
haven't bootstrapped it yet.  Just looking for some quick comments.

		Thanks,
		--Kaveh


diff -rup orig/egcs-CVS20000906/gcc/cppmacro.c egcs-CVS20000906/gcc/cppmacro.c
--- orig/egcs-CVS20000906/gcc/cppmacro.c	Fri Aug 18 09:48:44 2000
+++ egcs-CVS20000906/gcc/cppmacro.c	Thu Sep  7 18:59:29 2000
@@ -52,6 +52,9 @@ static const cpp_toklist * save_expansio
 static unsigned int find_param PARAMS ((const cpp_token *,
  					const cpp_token *));
 static cpp_toklist * alloc_macro PARAMS ((cpp_reader *, struct macro_info *));
+static void _cpp_cktrad_stringification PARAMS ((cpp_reader *,
+						 const struct macro_info *,
+						 const cpp_string *));
 
 /* These are all the tokens that can have something pasted after them.
    Comma is included in the list only to support the GNU varargs extension
@@ -502,6 +505,12 @@ save_expansion (pfile, info)
 	    continue;
 	  break;
 
+	case CPP_STRING:
+	case CPP_CHAR:
+	  if (list->paramc > 0 && CPP_WTRADITIONAL (pfile))
+	    _cpp_cktrad_stringification (pfile, info, &token->val.str);
+	  break;
+	  
 	default:
 	  break;
 	}
@@ -617,4 +626,55 @@ dump_macro_args (fp, list)
       param += len + 1;
     }
   putc (')', fp);
+}
+
+/* Warn if a token in `string' matches one of the function macro
+   arguments in `info'.  This function assumes that the macro is a
+   function macro and not an object macro.  */
+static void
+_cpp_cktrad_stringification (pfile, info, string)
+     cpp_reader *pfile;
+     const struct macro_info *info;
+     const cpp_string *string;
+{
+  const U_CHAR *p, *q, *limit = string->text + string->len;
+  const cpp_token *token;
+  
+  cpp_warning (pfile, "checking string `%.*s', nparams=%d",
+	       string->len, string->text, info->paramc);
+
+  /* Loop over the string.  */
+  for (p = string->text; p < limit; p = q)
+    {
+      /* Find the start of an identifier.  */
+      while (!is_idstart(*p))
+	p++;
+
+      /* Find the end of the identifier.  */
+      q = p;
+      while (is_idchar(*q))
+	q++;
+     
+      /* Loop over the function macro arguments to see if the
+	 identifier inside the string matches one of them.  */
+      for (token = info->first_param; token < info->first; token++)
+        {
+	  cpp_hashnode * hn = token->val.node;
+	  
+	  /* Skip the commas in between the arguments.  */
+	  if (token->type != CPP_NAME)
+	    continue;
+	  
+	  cpp_warning (pfile, "checking string subtoken `%.*s' vs arg `%.*s'",
+		       q - p, p, hn->length, hn->name);
+	  if (hn->length == (unsigned long) (q - p)
+	      && !memcmp (p, hn->name, q - p))
+	    {
+	      cpp_warning (pfile,
+			   "macro arg `%.*s' would be stringified with -traditional.",
+			   q - p, p);
+	      break;
+	    }
+	}
+    }
 }

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