diff mbox

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

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

Commit Message

Jakub Jelinek July 5, 2013, 3:25 p.m. UTC
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. UTC | #1
OK.

Jason
diff mbox

Patch

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