On Thu, Feb 15, 2018 at 01:12:08AM -0500, Jason Merrill wrote: > > This is just a partial fix, one thing this patch doesn't change is that > > the standard says that __VA_OPT__ ( contents ) should be treated as > > parameter, which means that #__VA_OPT__ ( contents ) should stringify it, > > which we right now reject. My preprocessor knowledge is too limited to > > handle this right myself, including all the corner cases, e.g. one can have > > #define f(x, ...) #__VA_OPT__(#x x ## x) etc.. I presume > > m_flags = token->flags & (PREV_FALLTHROUGH | PREV_WHITE); > > could be changed into: > > m_flags = token->flags & (PREV_FALLTHROUGH | PREV_WHITE | STRINGIFY_ARG); > > and when handling the PADDING result from update, we could just emit a > > "" token, but for INCLUDE_FIRST with this we'd need something complex, > > probably a new routine similar to stringify_arg to some extent. > > Yes, I think long term we really need to treat __VA_OPT__ more like an > argument. > > The first patch below makes your testcases work in what seems to me a > simpler way: pad when we see __VA_OPT__ if we aren't pasting to the left, > and fix up the end of the body if we're pasting to the right. > > The second further patch below makes the rest of the clang testcase work the > way it does in clang, apart from stringification. But it feels more > kludgey. > > Thoughts?
Both patches LGTM, thanks for looking at this. If you apply the second patch, you might want to apply also following incremental patch with some additional tests from my (failed) attempt to extend the patch further (this passes with your second patch). --- gcc/testsuite/c-c++-common/cpp/va-opt-3.c 2018-01-09 17:20:14.985142201 +0100 +++ gcc/testsuite/c-c++-common/cpp/va-opt-3.c 2018-01-09 17:54:17.564372639 +0100 @@ -19,6 +19,15 @@ #define f13(...) __VA_OPT__(a)__VA_OPT__(b)c #define f14(a, b, c, ...) __VA_OPT__(a)__VA_OPT__(b)c #define f15(a, b, c, ...) __VA_OPT__(a b)__VA_OPT__(b c)a/**/__VA_OPT__(c a)a +#define m1 ( +#define f16() f17 m1 ) +#define f17() f18 m1 ) +#define f18() m2 m1 ) +#define m3f17() g +#define f19(x, ...) m3 ## __VA_OPT__(x x f16() #x) +#define f20(x, ...) __VA_OPT__(x x)##m4() +#define f21() f17 +#define f17m4() h t1 f1 (1, 2, 3); /* { dg-final { scan-file va-opt-3.i "t1 bc;" } } */ t2 f1 (); @@ -69,0 +79,4 @@ +t25 f19 (f16 (), 1); +/* { dg-final { scan-file va-opt-3.i "t25 g f18 \\( \\) f17 \\( \\) \"f16 \\(\\)\";" } } */ +t26 f20 (f21 (), 2); +/* { dg-final { scan-file va-opt-3.i "t26 f17 h;" } } */ Jakub