This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: Warning from cpp on macro argument stringification is missing
- To: zack at wolery dot cumb dot org
- Subject: Re: Warning from cpp on macro argument stringification is missing
- From: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- Date: Thu, 7 Sep 2000 19:14:14 -0400 (EDT)
- Cc: NeilB at earthling dot net, gcc-bugs at gcc dot gnu dot org
> 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;
+ }
+ }
+ }
}