Hi! As mentioned in the PR, we need to cpp_avoid_paste during preprocessing after non-udlit stirng literals if udlits are enabled, because if next token starts with a-zA-Z_ characters, then when actually parsing the preprocessed output we'd read those as user defined literals when in the source code they weren't. Compilation without separate preprocessing worked just fine even without this.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2013-07-05 Jakub Jelinek <ja...@redhat.com> PR preprocessor/57757 * lex.c (cpp_avoid_paste): Avoid pasting CPP_{,W,UTF8}STRING or CPP_STRING{16,32} with CPP_NAME or SPELL_LITERAL token that starts if a-zA-Z_. * g++.dg/cpp/paste1.C: New test. * g++.dg/cpp/paste2.C: New test. --- libcpp/lex.c.jj 2013-07-05 12:46:33.000000000 +0200 +++ libcpp/lex.c 2013-07-05 13:37:52.127793638 +0200 @@ -2915,6 +2915,15 @@ cpp_avoid_paste (cpp_reader *pfile, cons || (CPP_OPTION (pfile, objc) && token1->val.str.text[0] == '@' && (b == CPP_NAME || b == CPP_STRING))); + case CPP_STRING: + case CPP_WSTRING: + case CPP_UTF8STRING: + case CPP_STRING16: + case CPP_STRING32: return (CPP_OPTION (pfile, user_literals) + && (b == CPP_NAME + || (TOKEN_SPELL (token2) == SPELL_LITERAL + && ISIDST (token2->val.str.text[0])))); + default: break; } --- gcc/testsuite/g++.dg/cpp/paste1.C.jj 2013-07-05 13:48:28.579618400 +0200 +++ gcc/testsuite/g++.dg/cpp/paste1.C 2013-07-05 13:47:22.000000000 +0200 @@ -0,0 +1,14 @@ +// PR preprocessor/57757 +// { dg-do compile } +// { dg-options "-std=c++11" } + +#define S(x) x +extern S("C")void exit (int); +int +main () +{ + (void) (S("foo")and 0); + const wchar_t *p = S(L"foo")L"bar"; + const char *a = S("foo")R"(bar)"; + exit (0); +} --- gcc/testsuite/g++.dg/cpp/paste2.C.jj 2013-07-05 13:48:36.371497492 +0200 +++ gcc/testsuite/g++.dg/cpp/paste2.C 2013-07-05 13:49:19.585816638 +0200 @@ -0,0 +1,15 @@ +// PR preprocessor/57757 +// { dg-do compile } +// { dg-options "-std=c++11 -save-temps" } +// { dg-final cleanup-saved-temps } + +#define S(x) x +extern S("C")void exit (int); +int +main () +{ + (void) (S("foo")and 0); + const wchar_t *p = S(L"foo")L"bar"; + const char *a = S("foo")R"(bar)"; + exit (0); +} Jakub