Fix preprocessing of string literals for C++11 (PR preprocessor/57757)

Submitted by Jakub Jelinek on July 5, 2013, 3:25 p.m.

Details

Message ID 20130705152528.GA2336@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek July 5, 2013, 3:25 p.m.
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  <jakub@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.


	Jakub

Comments

Jason Merrill July 10, 2013, 6:38 a.m.
OK.

Jason

Patch hide | download patch | download mbox

--- 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);
+}