PR preprocessor/84517 allow double-underscore macros after string literals
authorJonathan Wakely <jwakely@redhat.com>
Wed, 28 Feb 2018 15:27:17 +0000 (15:27 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 28 Feb 2018 15:27:17 +0000 (15:27 +0000)
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
gcc/testsuite/g++.dg/cpp0x/udlit-macros.C
libcpp/ChangeLog
libcpp/lex.c

index 8e963816087bded93500432da5f82948a3ba7f87..694a01846778fb43679c03f3b6c1732a53d03dd4 100644 (file)
@@ -1,3 +1,8 @@
+2018-02-28  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR preprocessor/84517
+       * g++.dg/cpp0x/udlit-macros.C: Expect a warning for ""__FILE__.
+
 2018-02-28  Eric Botcazou  <ebotcazou@adacore.com>
 
        * c-c++-common/dump-ada-spec-12.c: New test.
index fb5182818118d068ba9658d8a7b8d841c2c9b89b..7ef324b7e04c568aeaa3398b8210f1f74015cc01 100644 (file)
@@ -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
index 39e8895aeb1f1b1aadc8c664efa11285b3782941..791c364f01b2017c26c932b0805c99be80f269d9 100644 (file)
@@ -1,3 +1,10 @@
+2018-02-28  Jonathan Wakely  <jwakely@redhat.com>
+
+       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  <rguenther@suse.de>
 
        PR bootstrap/82939
index 92c62517a4d48dbf043116319615d18152d1f367..37c365a3560bcd758ccf69375b43a26f52d38a41 100644 (file)
@@ -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)