shithub: scc

Download patch

ref: 598c09bdd15ed4acf036700f3e4ec6e3b8d9be44
parent: 4a695da3a6e31f002608accb745d4369fe7f0eaa
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu Feb 23 16:25:48 EST 2017

[cc1] Move concatenation of strings to primary()

The concatenation of strings was done in lex.c:/^string
and it was to soon. There was a trick in string() which
look ahead to see if the next character was a ", and then
concatenate them. This strategy failed when the consecutive
string was the result of a macro expansion.

--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -600,6 +600,34 @@
 	return install(sym->ns, yylval.sym);
 }
 
+static Symbol *
+adjstrings(Symbol *sym)
+{
+	char *s, *t;
+	size_t len, n;
+	Type *tp;
+
+	tp = sym->type;
+	s = sym->u.s;
+	for (len = strlen(s);; len += n) {
+		next();
+		if (yytoken != STRING)
+			break;
+		t = yylval.sym->u.s;
+		n = strlen(t);
+		s = xrealloc(s, len + n + 1);
+		memcpy(s+len, t, n);
+		s[len + n] = '\0';
+		killsym(yylval.sym);
+	}
+	++len;
+	if (tp->n.elem != len) {
+		sym->type = mktype(chartype, ARY, len, NULL);
+		sym->u.s = s;
+	}
+	return sym;
+}
+
 /*************************************************************
  * grammar functions                                         *
  *************************************************************/
@@ -613,12 +641,11 @@
 	sym = yylval.sym;
 	switch (yytoken) {
 	case STRING:
-		np = constnode(sym);
+		np = constnode(adjstrings(sym));
 		sym->flags |= SHASINIT;
 		emit(ODECL, sym);
 		emit(OINIT, np);
-		np = varnode(sym);
-		break;
+		return varnode(sym);
 	case BUILTIN:
 		fun = sym->u.fun;
 		next();
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -561,8 +561,6 @@
 	}
 
 	input->begin = ++input->p;
-	if (ahead() == '"')
-		goto repeat;
 	*bp = '\0';
 
 	yylen = bp - yytext + 1;
--- /dev/null
+++ b/tests/execute/0119-macrostr.c
@@ -1,0 +1,18 @@
+
+#define B "b"
+
+char s[] = "a" B "c";
+
+int
+main()
+{
+	if (s[0] != 'a')
+		return 1;
+	if (s[1] != 'b')
+		return 2;
+	if (s[2] != 'c')
+		return 3;
+	if (s[3] != '\0')
+		return 4;
+	return 0;
+}
--- a/tests/execute/scc-tests.lst
+++ b/tests/execute/scc-tests.lst
@@ -109,3 +109,4 @@
 0116-floatcmp.c
 0117-pointarith.c
 0118-voidmain.c
+0119-macrostr.c