http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52952
--- Comment #22 from Manuel López-Ibáñez <manu at gcc dot gnu.org> 2013-04-01 14:17:45 UTC --- (In reply to comment #13) > and didn't need to be translated. So, printf ("%.*d"); (the common case) > wouldn't have to be recorded, while printf (R"<<<(%)>>>" "." R"(*)" "d"); > would BTW, your testcase does not work for me and confuses GCC: /home/manuel/loc_offset.c:7:21: error: unterminated raw string __builtin_printf (R"<<<(%)>>>" R"(*d)" ); ^ /home/manuel/loc_offset.c:7:3: error: expected expression at end of input __builtin_printf (R"<<<(%)>>>" R"(*d)" ); ^ /home/manuel/loc_offset.c:7:3: error: expected declaration or statement at end of input It is also very unclear to me how to re-process such a token stream in order to find out the real location+offset. A further issue is that for: #define FORMAT ".*d" #include <stdio.h> void f() { printf( "%" FORMAT); } the token representing "%" is overriden when we call cpp_get_token next time: @@ -1003,10 +1004,13 @@ lex_string (const cpp_token *tok, tree * concatenation. It is 'true' if we have seen an '@' before the current string, and 'false' if not. We must see exactly one or zero '@' before each string. */ bool objc_at_sign_was_seen = false; + // This token is overwritten! How can that happen? + const cpp_token *prev_tok = tok; + retry: tok = cpp_get_token (parse_in); switch (tok->type) { case CPP_PADDING: so prev_tok above may or may not change by the call of cpp_get_token.