ref: 02d2ec7eb3137a12297f11cac8569cf489739ad9
parent: c183aab9883ecbf6caaa473a1c54648257f4954c
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Jul 25 02:55:18 EDT 2017
Rewrite initializers Initializers had strong problems using recursd designated initializers. This patch had rewrite the code to add recursivty between designator and initlist.
--- a/cc1/init.c
+++ b/cc1/init.c
@@ -19,22 +19,19 @@
};
struct init {- Type *type;
- size_t pos;
- size_t max;
+ TUINT pos;
+ TUINT max;
struct designator *tail;
struct designator *head;
};
-
static TINT
-arydesig(Init *ip)
+arydesig(Type *tp, Init *ip)
{TINT npos;
Node *np;
- Type *tp = ip->type;
- if (ip->type->op != ARY)
+ if (tp->op != ARY)
errorp("array index in non-array initializer");next();
np = constexpr();
@@ -49,11 +46,10 @@
}
static TINT
-fielddesig(Init *ip)
+fielddesig(Type *tp, Init *ip)
{int ons;
Symbol *sym, **p;
- Type *tp = ip->type;
if (!(tp->prop & TAGGREG))
errorp("field name not in record or union initializer");@@ -64,6 +60,7 @@
if (yytoken != IDEN)
unexpected();
sym = yylval.sym;
+ next();
if ((sym->flags & SDECLARED) == 0) { errorp("unknown field '%s' specified in initializer",sym->name);
@@ -71,85 +68,78 @@
}
for (p = tp->p.fields; *p != sym; ++p)
/* nothing */;
- next();
return p - tp->p.fields;
}
static Init *
-designation(Init *ip)
+init(Init *ip)
{- TINT (*fun)(Init *);
-
- switch (yytoken) {- case '[': fun = arydesig; break;
- case '.': fun = fielddesig; break;
- default: return ip;
- }
-
- ip->pos = (*fun)(ip);
- expect('=');+ ip->tail = ip->head = NULL;
+ ip->pos = ip->max = 0;
return ip;
}
static Node *
-initialize(Type *tp)
+str2ary(Type *tp)
{Node *np;
+ Type *btp = tp->type;;
Symbol *sym;
- Type *btp;
size_t len;
char *s;
- int isstring;
- if ((tp->op == ARY || tp->op == STRUCT) &&
- yytoken != '{' && yytoken != STRING) {- return initlist(tp);
+ np = assign();
+ sym = np->left->sym;
+ if (btp != chartype && btp != uchartype && btp != schartype) {+ errorp("array of inappropriate type initialized from string constant");+ return constnode(zero);
}
- isstring = yytoken == STRING;
- np = (yytoken == '{') ? initlist(tp) : assign();+ len = sym->type->n.elem-1;
+ if (!(tp->prop & TDEFINED)) {+ tp->n.elem = len+1;
+ deftype(tp);
+ } else if (tp->n.elem < len) {+ warn("initializer-string for array of chars is too long");+ }
- if (isstring && tp->op == ARY) {- sym = np->left->sym;
- btp = tp->type;
- if (btp != chartype &&
- btp != uchartype &&
- btp != schartype) {- errorp("array of inappropriate type initialized from string constant");- goto return_zero;
- }
- len = sym->type->n.elem-1;
- if (!(tp->prop & TDEFINED)) {- tp->n.elem = len+1;
- deftype(tp);
- } else if (tp->n.elem < len) {- warn("initializer-string for array of chars is too long");- }
- len = tp->n.elem;
- s = sym->u.s;
- sym = newstring(NULL, len);
- strncpy(sym->u.s, s, len);
- np->sym = sym;
- np->type = sym->type;
+ len = tp->n.elem;
+ s = sym->u.s;
+ sym = newstring(NULL, len);
+ strncpy(sym->u.s, s, len);
+ np->sym = sym;
+ np->type = sym->type;
+ return np;
+}
+
+static Node *
+initialize(Type *tp)
+{+ Node *np;
+ Symbol *sym;
+
+ if (tp->op == ARY && yytoken == STRING)
+ return str2ary(tp);
+
+ if (yytoken == '{' || tp->op == STRUCT || tp->op == ARY)+ return initlist(tp);
+
+ np = assign();
+ if (eqtype(tp, np->type, 1))
return np;
- } else {- if (eqtype(tp, np->type, 1))
- return np;
- np = convert(decay(np), tp, 0);
- if (!np) {- errorp("incorrect initializer");- goto return_zero;
- }
+
+ np = convert(decay(np), tp, 0);
+ if (!np) {+ errorp("incorrect initializer");+ return constnode(zero);
}
- return simplify(np);
-return_zero:
- return constnode(zero);
+ return simplify(np);
}
static Node *
-mkcompound(Init *ip)
+mkcompound(Init *ip, Type *tp)
{Node **v, **p;
size_t n;
@@ -156,27 +146,41 @@
struct designator *dp, *next;
Symbol *sym;
- if ((n = ip->max) == 0) {- v = NULL;
- } else if (n > SIZE_MAX / sizeof(*v)) {- errorp("compound literal too big");- return constnode(zero);
- } else {- n *= sizeof(*v);
- v = memset(xmalloc(n), 0, n);
+ if (tp->op == UNION) {+ Node *np = NULL;
+ v = xmalloc(sizeof(*v));
for (dp = ip->head; dp; dp = next) {- p = &v[dp->pos];
- freetree(*p);
- *p = dp->expr;
+ freetree(np);
+ np = dp->expr;
next = dp->next;
free(dp);
}
+ *v = np;
+ } else {+ n = (tp->prop&TDEFINED) ? tp->n.elem : ip->max;
+ if (n == 0) {+ v = NULL;
+ } else if (n > SIZE_MAX / sizeof(*v)) {+ errorp("compound literal too big");+ return constnode(zero);
+ } else {+ n *= sizeof(*v);
+ v = memset(xmalloc(n), 0, n);
+
+ for (dp = ip->head; dp; dp = next) {+ p = &v[dp->pos];
+ freetree(*p);
+ *p = dp->expr;
+ next = dp->next;
+ free(dp);
+ }
+ }
}
sym = newsym(NS_IDEN, NULL);
sym->u.init = v;
- sym->type = ip->type;
+ sym->type = tp;
sym->flags |= SINITLST;
return constnode(sym);
@@ -198,6 +202,9 @@
ip->tail->next = dp;
ip->tail = dp;
}
+
+ if (ip->pos+1 > ip->max)
+ ip->max = ip->pos+1;
}
Node *
@@ -204,14 +211,16 @@
initlist(Type *tp)
{Init in;
- int braces, scalar, toomany, outbound;
- Type *newtp;
Node *np;
+ Type *curtp;
+ int braces, scalar, toomany, outbound;
+ TINT nelem = tp->n.elem;
+ static int depth;
- in.tail = in.head = NULL;
- in.type = tp;
- in.pos = 0;
- in.max = 0;
+ if (depth == NR_SUBTYPE)
+ error("too many nested initializers");+ ++depth;
+ init(&in);
braces = scalar = toomany = 0;
if (accept('{'))@@ -218,57 +227,72 @@
braces = 1;
do {- if (yytoken == '}')
- break;
- outbound = 0;
- designation(&in);
- switch (tp->op) {- case ARY:
- newtp = tp->type;
- if (!(tp->prop & TDEFINED) || in.pos < tp->n.elem)
- break;
- if (!toomany)
- warn("excess elements in array initializer");- outbound = 1;
- toomany = 1;
- break;
- /* TODO: case UNION: */
- case STRUCT:
- if (in.pos < tp->n.elem) {- newtp = tp->p.fields[in.pos]->type;
- break;
+ curtp = inttype;
+ switch (yytoken) {+ case '[':
+ in.pos = arydesig(tp, &in);
+ curtp = tp->type;
+ goto desig_list;
+ case '.':
+ in.pos = fielddesig(tp, &in);
+ if (in.pos < nelem)
+ curtp = tp->p.fields[in.pos]->type;
+ desig_list:
+ if (yytoken == '[' || yytoken == '.') {+ np = initlist(curtp);
+ goto new_desig;
}
- newtp = inttype;
- if (!toomany)
- warn("excess elements in struct initializer");- toomany = 1;
- outbound = 1;
- break;
+ expect('=');default:
- newtp = tp;
- if (!scalar)
- warn("braces around scalar initializer");- scalar = 1;
- if (in.pos == 0)
+ outbound = 0;
+
+ switch (tp->op) {+ case ARY:
+ curtp = tp->type;
+ if (!(tp->prop & TDEFINED) || in.pos < tp->n.elem)
+ break;
+ if (!toomany)
+ warn("excess elements in array initializer");+ toomany = 1;
+ outbound = 1;
break;
- if (!toomany)
- warn("excess elements in scalar initializer");- toomany = 1;
- outbound = 1;
- break;
+ case UNION:
+ case STRUCT:
+ if (in.pos < nelem) {+ curtp = tp->p.fields[in.pos]->type;
+ break;
+ }
+ if (!toomany)
+ warn("excess elements in struct initializer");+ toomany = 1;
+ outbound = 1;
+ break;
+ default:
+ curtp = tp;
+ if (!scalar)
+ warn("braces around scalar initializer");+ scalar = 1;
+ if (in.pos == 0)
+ break;
+ if (!toomany)
+ warn("excess elements in scalar initializer");+ toomany = 1;
+ outbound = 1;
+ break;
+ }
+ np = initialize(curtp);
+ if (outbound) {+ freetree(np);
+ np = NULL;
+ }
}
- np = initialize(newtp);
- if (outbound)
- freetree(np);
- else
+new_desig:
+ if (np)
newdesig(&in, np);
-
if (++in.pos == 0)
errorp("compound literal too big");- if (in.pos > in.max)
- in.max = in.pos;
- if (tp->n.elem == in.pos && !braces)
+ if (nelem == in.pos && !braces)
break;
} while (accept(','));@@ -275,18 +299,17 @@
if (braces)
expect('}');+
if (tp->op == ARY && !(tp->prop & TDEFINED)) {tp->n.elem = in.max;
deftype(tp);
}
- if (tp->op == ARY || tp->op == STRUCT)
- in.max = tp->n.elem;
- else if (in.max == 0) {- errorp("empty scalar initializer");+ if (in.max == 0) {+ errorp("empty braced initializer");return constnode(zero);
}
- return mkcompound(&in);
+ return mkcompound(&in, tp);
}
static void
@@ -294,8 +317,6 @@
{Symbol *hidden;
Type *tp = sym->type;
- size_t n; /* FIXME: It should be SIZET */
-
repeat:
switch (tp->op) {--
⑨