From b44f8ad8b2138f7bfd68053e8dce596adb964735 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Wed, 28 Feb 2018 15:27:17 +0000 Subject: [PATCH] PR preprocessor/84517 allow double-underscore macros after string literals gcc/testsuite: PR preprocessor/84517 * g++.dg/cpp0x/udlit-macros.C: Expect a warning for ""__FILE__. libcpp: PR preprocessor/84517 * lex.c (is_macro_not_literal_suffix): New function. (lex_raw_string, lex_string): Use is_macro_not_literal_suffix to decide when to issue -Wliteral-suffix warnings. From-SVN: r258069 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp0x/udlit-macros.C | 2 +- libcpp/ChangeLog | 7 ++++++ libcpp/lex.c | 27 ++++++++++++++++------- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8e963816087..694a0184677 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-28 Jonathan Wakely + + PR preprocessor/84517 + * g++.dg/cpp0x/udlit-macros.C: Expect a warning for ""__FILE__. + 2018-02-28 Eric Botcazou * c-c++-common/dump-ada-spec-12.c: New test. diff --git a/gcc/testsuite/g++.dg/cpp0x/udlit-macros.C b/gcc/testsuite/g++.dg/cpp0x/udlit-macros.C index fb518281811..7ef324b7e04 100644 --- a/gcc/testsuite/g++.dg/cpp0x/udlit-macros.C +++ b/gcc/testsuite/g++.dg/cpp0x/udlit-macros.C @@ -16,7 +16,7 @@ int operator""_ID(const char*, size_t) { return 0; } int main() { long i64 = 123; - char buf[100]; + char buf[] = "xxxxxx"__FILE__; // { dg-warning "invalid suffix on literal" } sprintf(buf, "%"PRId64"abc", i64); // { dg-warning "invalid suffix on literal" } return strcmp(buf, "123abc") + ""_zero diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 39e8895aeb1..791c364f01b 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,10 @@ +2018-02-28 Jonathan Wakely + + PR preprocessor/84517 + * lex.c (is_macro_not_literal_suffix): New function. + (lex_raw_string, lex_string): Use is_macro_not_literal_suffix to + decide when to issue -Wliteral-suffix warnings. + 2018-02-16 Richard Biener PR bootstrap/82939 diff --git a/libcpp/lex.c b/libcpp/lex.c index 92c62517a4d..37c365a3560 100644 --- a/libcpp/lex.c +++ b/libcpp/lex.c @@ -1630,6 +1630,21 @@ is_macro(cpp_reader *pfile, const uchar *base) return !result ? false : (result->type == NT_MACRO); } +/* Returns true if a literal suffix does not have the expected form + and is defined as a macro. */ + +static bool +is_macro_not_literal_suffix(cpp_reader *pfile, const uchar *base) +{ + /* User-defined literals outside of namespace std must start with a single + underscore, so assume anything of that form really is a UDL suffix. + We don't need to worry about UDLs defined inside namespace std because + their names are reserved, so cannot be used as macro names in valid + programs. */ + if (base[0] == '_' && base[1] != '_') + return false; + return is_macro (pfile, base); +} /* Lexes a raw string. The stored string contains the spelling, including double quotes, delimiter string, '(' and ')', any leading @@ -1900,10 +1915,8 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base, { /* If a string format macro, say from inttypes.h, is placed touching 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. - The macro name should not start with '_' for this warning. */ - if ((*cur != '_') && is_macro (pfile, cur)) + literal thus breaking the program. */ + if (is_macro_not_literal_suffix (pfile, cur)) { /* Raise a warning, but do not consume subsequent tokens. */ if (CPP_OPTION (pfile, warn_literal_suffix) && !pfile->state.skipping) @@ -2031,10 +2044,8 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base) { /* If a string format macro, say from inttypes.h, is placed touching 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. - The macro name should not start with '_' for this warning. */ - if ((*cur != '_') && is_macro (pfile, cur)) + literal thus breaking the program. */ + if (is_macro_not_literal_suffix (pfile, cur)) { /* Raise a warning, but do not consume subsequent tokens. */ if (CPP_OPTION (pfile, warn_literal_suffix) && !pfile->state.skipping)