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

login
register
mail settings
Submitter Jakub Jelinek
Date July 5, 2013, 3:25 p.m.
Message ID <20130705152528.GA2336@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/257192/
State New
Headers show

Comments

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
Jason Merrill - July 10, 2013, 6:38 a.m.
OK.

Jason

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