https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83063
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- More complete testcase: #define f1(...) int b##__VA_OPT__(c) #define f2(...) int __VA_OPT__(c)##d #define f3(...) int e##__VA_OPT__() #define f4(...) int __VA_OPT__()##f #define f5(...) int g##__VA_OPT__(h)##i #define f6(...) int j##__VA_OPT__()##k #define f7(...) int l##__VA_OPT__() #define f8(...) int __VA_OPT__()##m #define f9(...) int n##__VA_OPT__()##o f1 (1, 2, 3); f1 (); f2 (1, 2); f2 (); f3 (1); f4 (2); f5 (6, 7); f5 (); f6 (8); f7 (); f8 (); f9 (); int main () { return bc + b + cd + d + f + ghi + gi + jk + l + m + no; } I have so far following patch: --- libcpp/macro.c.jj 2018-01-03 10:42:55.938763447 +0100 +++ libcpp/macro.c 2018-01-08 20:36:52.733255700 +0100 @@ -105,6 +105,7 @@ class vaopt_state { : m_pfile (pfile), m_allowed (any_args), m_variadic (is_variadic), + m_any_tokens (false), m_state (0), m_last_was_paste (false), m_paste_location (0), @@ -116,7 +117,8 @@ class vaopt_state { { ERROR, DROP, - INCLUDE + INCLUDE, + PADDING }; /* Given a token, update the state of this tracker and return a @@ -191,9 +193,10 @@ class vaopt_state { return ERROR; } - return DROP; + return m_any_tokens ? DROP : PADDING; } } + m_any_tokens |= m_allowed; return m_allowed ? INCLUDE : DROP; } @@ -220,6 +223,8 @@ class vaopt_state { bool m_allowed; /* True if the macro is variadic. */ bool m_variadic; + /* True if any tokens inside of __VA_OPT__ content were INCLUDE. */ + bool m_any_tokens; /* The state variable: 0 means not parsing @@ -1839,8 +1844,22 @@ replace_args (cpp_reader *pfile, cpp_has const cpp_token **tmp_token_ptr; /* __VA_OPT__ handling. */ - if (vaopt_tracker.update (src) != vaopt_state::INCLUDE) - continue; + vaopt_state::update_type vaopt_state = vaopt_tracker.update (src); + if (vaopt_state != vaopt_state::INCLUDE) + { + if (vaopt_state == vaopt_state::PADDING) + { + const cpp_token *t = padding_token (pfile, src); + unsigned index = expanded_token_index (pfile, macro, src, i); + /* Allocate a virtual location for the padding token and + append the token and its location to BUFF and + VIRT_LOCS. */ + tokens_buff_add_token (buff, virt_locs, t, + t->src_loc, t->src_loc, + map, index); + } + continue; + } if (src->type != CPP_MACRO_ARG) { and while it fixes the ICEs, it doesn't still preprocess it properly.