Index: gcc/testsuite/g++.dg/cpp0x/udlit-macros.C =================================================================== --- gcc/testsuite/g++.dg/cpp0x/udlit-macros.C (revision 0) +++ gcc/testsuite/g++.dg/cpp0x/udlit-macros.C (working copy) @@ -0,0 +1,31 @@ +// PR c++/80955 +// { dg-do compile { target c++11 } } + +#define __STDC_FORMAT_MACROS +#include +#include +#include + +using size_t = decltype(sizeof(0)); +#define _zero +#define _ID _xx +int operator""_zero(const char*, size_t) { return 0; } +int operator""_ID(const char*, size_t) { return 0; } + +int main() +{ + int64_t i64 = 123; + char buf[100]; + sprintf(buf, "%"PRId64"abc", i64); // { dg-warning "invalid suffix on literal" } + return strcmp(buf, "123abc") + + ""_zero + + "bob"_zero + + R"#(raw + string)#"_zero + + "xx"_ID + + ""_ID + + R"AA(another + raw + string)AA"_ID; +} + Index: libcpp/lex.c =================================================================== --- libcpp/lex.c (revision 254048) +++ libcpp/lex.c (working copy) @@ -1576,14 +1576,17 @@ /* Returns true if a macro has been defined. + If no_underscore is true, check that the macro + name does not start with underscore. This might not work if compile with -save-temps, or preprocess separately from compilation. */ static bool -is_macro(cpp_reader *pfile, const uchar *base) +is_macro(cpp_reader *pfile, const uchar *base, bool no_underscore) { const uchar *cur = base; - if (! ISIDST (*cur)) + bool invalid_ident = (no_underscore ? ! ISALPHA (*cur) : ! ISIDST (*cur)); + if (invalid_ident) return false; unsigned int hash = HT_HASHSTEP (0, *cur); ++cur; @@ -1872,7 +1875,7 @@ a string literal it could be parsed as a C++11 user-defined string literal thus breaking the program. Try to identify macros with is_macro. A warning is issued. */ - if (is_macro (pfile, cur)) + if (is_macro (pfile, cur, true)) { /* Raise a warning, but do not consume subsequent tokens. */ if (CPP_OPTION (pfile, warn_literal_suffix) && !pfile->state.skipping) @@ -2002,7 +2005,7 @@ a string literal it could be parsed as a C++11 user-defined string literal thus breaking the program. Try to identify macros with is_macro. A warning is issued. */ - if (is_macro (pfile, cur)) + if (is_macro (pfile, cur, true)) { /* Raise a warning, but do not consume subsequent tokens. */ if (CPP_OPTION (pfile, warn_literal_suffix) && !pfile->state.skipping) @@ -2023,7 +2026,7 @@ } } else if (CPP_OPTION (pfile, cpp_warn_cxx11_compat) - && is_macro (pfile, cur) + && is_macro (pfile, cur, false) && !pfile->state.skipping) cpp_warning_with_line (pfile, CPP_W_CXX11_COMPAT, token->src_loc, 0, "C++11 requires a space "