From 0e9e97e37571c913864cc4d8d986fa9fda964e8a Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Mon, 13 Sep 2021 18:37:41 -0700 Subject: Revert "Add stringconcat function to concatenate adjacent string literals" This reverts commit c16f07acf655b9f4fb006d8256b4027fb5a13aa8. This incorrectly allows octal escapes to span between adjacent string literals (e.g. "\0" "1" is not the same as "\01"). --- cc.h | 1 - decl.c | 9 +++++---- expr.c | 21 ++++++++++++++------- pp.c | 48 ------------------------------------------------ 4 files changed, 19 insertions(+), 60 deletions(-) diff --git a/cc.h b/cc.h index 7a61cf3..41f7d90 100644 --- a/cc.h +++ b/cc.h @@ -405,7 +405,6 @@ void next(void); _Bool peek(int); char *expect(enum tokenkind, const char *); _Bool consume(int); -char *stringconcat(void); /* type */ diff --git a/decl.c b/decl.c index 3aa720a..2483a47 100644 --- a/decl.c +++ b/decl.c @@ -748,18 +748,19 @@ addmember(struct structbuilder *b, struct qualtype mt, char *name, int align, ui static bool staticassert(struct scope *s) { + struct expr *e; uint64_t c; - char *msg; if (!consume(T_STATIC_ASSERT)) return false; expect(TLPAREN, "after _Static_assert"); c = intconstexpr(s, true); if (consume(TCOMMA)) { - tokencheck(&tok, TSTRINGLIT, "after static assertion expression"); - msg = stringconcat(); + e = assignexpr(s); + if (!e->decayed || e->base->kind != EXPRSTRING) + error(&tok.loc, "expected string literal after static assertion expression"); if (!c) - error(&tok.loc, "static assertion failed: %s", msg + (*msg != '"')); + error(&tok.loc, "static assertion failed: %.*s", (int)e->base->string.size, e->base->string.data); } else if (!c) { error(&tok.loc, "static assertion failed"); } diff --git a/expr.c b/expr.c index 986f438..114aa5a 100644 --- a/expr.c +++ b/expr.c @@ -476,14 +476,21 @@ primaryexpr(struct scope *s) case TSTRINGLIT: e = mkexpr(EXPRSTRING, mkarraytype(&typechar, QUALNONE, 0)); e->lvalue = true; - src = stringconcat(); - dst = e->string.data = xmalloc(strlen(src) - 1); - if (*src != '"') - fatal("wide string literal not yet implemented"); - for (++src; *src != '"'; ++dst) - *dst = unescape(&src); + e->string.size = 0; + e->string.data = NULL; + do { + e->string.data = xreallocarray(e->string.data, e->string.size + strlen(tok.lit) + 1, 1); + dst = e->string.data + e->string.size; + src = tok.lit; + if (*src != '"') + fatal("wide string literal not yet implemented"); + for (++src; *src != '"'; ++dst) + *dst = unescape(&src); + e->string.size = dst - e->string.data; + next(); + } while (tok.kind == TSTRINGLIT); *dst = '\0'; - e->type->array.length = e->string.size = dst - e->string.data + 1; + e->type->array.length = ++e->string.size; e->type->size = e->type->array.length * e->type->base->size; e->type->incomplete = false; e = decay(e); diff --git a/pp.c b/pp.c index a1e6e11..101c7c7 100644 --- a/pp.c +++ b/pp.c @@ -650,51 +650,3 @@ consume(int kind) next(); return true; } - -char * -stringconcat(void) -{ - static struct array buf; - char *lit, *end; - int kind = 0, newkind; - - assert(tok.kind == TSTRINGLIT); - lit = tok.lit; - next(); - if (tok.kind != TSTRINGLIT) { - if (lit[0] == 'u' && lit[1] == '8') - lit += 2; - return lit; - } - - /* concatenate adjacent string literals */ - buf.len = 0; - ((char *)arrayadd(&buf, 2))[1] = '"'; - for (;;) { - switch (*lit) { - case 'u': if (lit[1] == '8') ++lit; /* fallthrough */ - case 'L': - case 'U': newkind = *lit, ++lit; break; - case '"': newkind = 0; break; - default: assert(0); - } - if (kind != newkind && kind && newkind) - error(&tok.loc, "adjacent string literals have differing prefixes"); - if (newkind) - kind = newkind; - arrayaddbuf(&buf, lit + 1, strlen(lit) - 2); - if (tok.kind != TSTRINGLIT) - break; - lit = tok.lit; - next(); - } - end = arrayadd(&buf, 2); - end[0] = '"'; - end[1] = '\0'; - lit = buf.val; - if (kind && kind != '8') - *lit = kind; - else - ++lit; - return lit; -} -- cgit v1.2.3