commit 57722b5e8fb04004d69edee448957a8dc10c982f
Author:     Roberto E. Vargas Caballero <[email protected]>
AuthorDate: Thu Feb 23 21:25:48 2017 +0100
Commit:     Roberto E. Vargas Caballero <[email protected]>
CommitDate: Thu Feb 23 21:35:23 2017 +0100

    [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.

diff --git a/cc1/expr.c b/cc1/expr.c
index fed3300..b6c405d 100644
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -600,6 +600,34 @@ notdefined(Symbol *sym)
        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 @@ primary(void)
        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();
diff --git a/cc1/lex.c b/cc1/lex.c
index a582fcb..448a7c1 100644
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -561,8 +561,6 @@ repeat:
        }
 
        input->begin = ++input->p;
-       if (ahead() == '"')
-               goto repeat;
        *bp = '\0';
 
        yylen = bp - yytext + 1;
diff --git a/tests/execute/0119-macrostr.c b/tests/execute/0119-macrostr.c
new file mode 100644
index 0000000..77f2734
--- /dev/null
+++ b/tests/execute/0119-macrostr.c
@@ -0,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;
+}
diff --git a/tests/execute/scc-tests.lst b/tests/execute/scc-tests.lst
index c766571..f620bff 100644
--- 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

Reply via email to