diff mbox

[PR,C++/61038] - g++ -E is unusable with UDL strings

Message ID 5372BFEF.5040502@verizon.net
State New
Headers show

Commit Message

Ed Smith-Rowland May 14, 2014, 12:59 a.m. UTC
On 05/13/2014 01:29 PM, Joseph S. Myers wrote:
> On Mon, 12 May 2014, Ed Smith-Rowland wrote:
>
>> This patch is really a libcpp patch.  But UDLs are like that ;-)
>>
>> Add string user-defined literals and char user-defined literals to the list of
>> things to look out for while escaping strings in macro args.
>>
>> I'm not sure how to test this really.  we want to write out *.ii files and
>> verify that internal quotes are escaped.
> You should be able to check the results of stringizing twice, e.g.:
>
> extern "C" int strcmp (const char *, const char *);
> extern "C" void abort (void);
> extern "C" void exit (int);
>
> void operator "" _s(const char *, unsigned long)
> {
> }
>
> #define QUOTE(s) #s
> #define QQUOTE(s) QUOTE(s)
>
> const char *s = QQUOTE(QUOTE("hello"_s));
> const char *t = QUOTE("\"hello\"_s");
>
> int main()
> {
>    if (strcmp(s, t) == 0)
>      exit(0);
>    else
>      abort();
> }
>
> (at least, this fails for me with unmodified GCC, and I think it should
> pass).
>
Thank you Joe!

Here is a new patch with a proper test case.

Built and tested on x86_64-linux.

OK?

Ed

libcpp/

2014-05-12  Edward Smith-Rowland  <3dw4rd@verizon.net>

	PR C++/61038
	* macro.c (stringify_arg (cpp_reader *, macro_arg *)):
	Check for user-defined literal strings and user-defined literal chars
	to escape necessary characters.
gcc/testsuite/

2014-05-12  Edward Smith-Rowland  <3dw4rd@verizon.net>

	PR C++/61038
	* g++.dg/cpp0x/pr61038.C: New.

Comments

Jason Merrill May 20, 2014, 8:44 p.m. UTC | #1
On 05/13/2014 08:59 PM, Ed Smith-Rowland wrote:
> +      escape_it = escape_it || cpp_userdef_string_p (token->type)
> +			    || cpp_userdef_char_p (token->type);

Let's add the new cases to the previous statement instead of a new one. 
  OK with that change.

Jason
diff mbox

Patch

Index: macro.c
===================================================================
--- macro.c	(revision 210315)
+++ macro.c	(working copy)
@@ -494,6 +494,9 @@ 
 		   || token->type == CPP_STRING16 || token->type == CPP_CHAR16
 		   || token->type == CPP_UTF8STRING);
 
+      escape_it = escape_it || cpp_userdef_string_p (token->type)
+			    || cpp_userdef_char_p (token->type);
+
       /* Room for each char being written in octal, initial space and
 	 final quote and NUL.  */
       len = cpp_token_len (token);
Index: ../gcc/testsuite/g++.dg/cpp0x/pr61038.C
===================================================================
--- ../gcc/testsuite/g++.dg/cpp0x/pr61038.C	(revision 0)
+++ ../gcc/testsuite/g++.dg/cpp0x/pr61038.C	(working copy)
@@ -0,0 +1,40 @@ 
+// PR c++/61038
+// { dg-do compile { target c++11 } }
+
+#include <cstring>
+#include <cstdlib>
+
+void
+operator "" _s(const char *, unsigned long)
+{ }
+
+void
+operator "" _t(const char)
+{ }
+
+#define QUOTE(s) #s
+#define QQUOTE(s) QUOTE(s)
+
+int
+main()
+{
+  const char *s = QQUOTE(QUOTE("hello"_s));
+  const char *t = QUOTE("\"hello\"_s");
+  if (strcmp(s, t) != 0)
+    abort();
+
+  const char *c = QQUOTE(QUOTE('"'_t));
+  const char *d = QUOTE("'\"'_t");
+  if (strcmp(c, d) != 0)
+    abort();
+
+  const char *e = QQUOTE(QUOTE('\''_t));
+  const char *f = QUOTE("'\\''_t");
+  if (strcmp(e, f) != 0)
+    abort();
+
+  const char *g = QQUOTE(QUOTE('\\'_t));
+  const char *h = QUOTE("'\\\\'_t");
+  if (strcmp(g, h) != 0)
+    abort();
+}