ref: b17cc0af133dcaeb60d742159836cae7d0d431f7
parent: e1bc6c3a19ded30fb1affa8dceaeec7d5c0a0951
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sun Oct 31 05:47:30 EDT 2021
cc1: Disable escape() while parsing #define When the expansion part of a #define was parsed the code was applying the same escape rules than when it parses normal C code. The result of this was that strings were escaped in the definition of the macro, so any embedded and escaped " would be expanded without the escape sequence. This change disables escape for strings when a define is parsed, but cc2-qbe is still passing an unescape string to qbe.
--- a/src/cmd/cc/cc1/cc1.h
+++ b/src/cmd/cc/cc1/cc1.h
@@ -514,7 +514,7 @@
extern char yytext[];
extern int yytoken;
extern unsigned short yylen;
-extern int disexpand;
+extern int disexpand, disescape;
extern unsigned cppctx;
extern Input *input;
extern int lexmode, namespace;
--- a/src/cmd/cc/cc1/cpp.c
+++ b/src/cmd/cc/cc1/cpp.c
@@ -19,6 +19,7 @@
unsigned cppctx;
int disexpand;
+int disescape;
void
defdefine(char *macro, char *val, char *source)
@@ -379,6 +380,7 @@
if (cppoff)
return;
+ disescape = 1;
namespace = NS_CPP;
next();
@@ -400,6 +402,7 @@
goto delete;
if (n > 0 && !args[n-1]) /* it is a variadic function */
--n;
+
sprintf(buff, "%02d#", n);
if (!getdefs(args, n, buff+3, LINESIZ-3))
goto delete;
@@ -761,6 +764,7 @@
errorp("trailing characters after preprocessor directive");
error:
+ disescape = 0;
disexpand = 0;
lexmode = CCMODE;
namespace = ns;
--- a/src/cmd/cc/cc1/lex.c
+++ b/src/cmd/cc/cc1/lex.c
@@ -543,16 +543,28 @@
string(void)
{
char *bp = yytext;
- int c;
+ int c, esc;
*bp++ = '"';
- for (++input->p; (c = *input->p) != '"'; ++input->p) {
+ esc = 0;
+ for (++input->p; ; ++input->p) {
+ c = *input->p;
+
+ if (c == '"' && !esc)
+ break;
+
if (c == '\0') {
errorp("missing terminating '\"' character");
break;
}
- if (c == '\\')
- c = escape();
+ if (c != '\\') {
+ esc = 0;
+ } else {
+ if (!disescape)
+ c = escape();
+ else
+ esc = 1;
+ }
if (bp == &yytext[STRINGSIZ+1]) {
for (++input->p; *input->p != '"'; ++input->p) {
if (*input->p == '\\')