Skip excess initializer elements

This commit is contained in:
Rui Ueyama 2019-08-19 08:35:11 +09:00
parent c9dd8d9e7f
commit c8617ad9b1
3 changed files with 49 additions and 17 deletions

View File

@ -42,6 +42,7 @@ struct Token {
void error(char *fmt, ...);
void error_at(char *loc, char *fmt, ...);
void error_tok(Token *tok, char *fmt, ...);
void warn_tok(Token *tok, char *fmt, ...);
Token *peek(char *s);
Token *consume(char *op);
char *strndup(char *p, int len);

43
parse.c
View File

@ -600,12 +600,12 @@ bool peek_end() {
return ret;
}
void expect_end() {
bool consume_end() {
Token *tok = token;
if (consume(",") && consume("}"))
return;
if (consume("}") || (consume(",") && consume("}")))
return true;
token = tok;
expect("}");
return false;
}
// global-var = type-specifier declarator type-suffix ";"
@ -653,6 +653,25 @@ Initializer *emit_struct_padding(Initializer *cur, Type *parent, Member *mem) {
return cur;
}
void skip_excess_elements2() {
for (;;) {
if (consume("{"))
skip_excess_elements2();
else
assign();
if (consume_end())
return;
expect(",");
}
}
void skip_excess_elements() {
expect(",");
warn_tok(token, "excess elements in initializer");
skip_excess_elements2();
}
Initializer *gvar_initializer(Initializer *cur, Type *ty) {
Token *tok = token;
@ -666,8 +685,8 @@ Initializer *gvar_initializer(Initializer *cur, Type *ty) {
i++;
} while (i < limit && !peek_end() && consume(","));
if (open)
expect_end();
if (open && !consume_end())
skip_excess_elements();
// Set excess array elements to zero.
cur = new_init_zero(cur, size_of(ty->base, tok) * (ty->array_size - i));
@ -690,8 +709,8 @@ Initializer *gvar_initializer(Initializer *cur, Type *ty) {
mem = mem->next;
} while (mem && !peek_end() && consume(","));
if (open)
expect_end();
if (open && !consume_end())
skip_excess_elements();
// Set excess struct elements to zero.
if (mem) {
@ -855,8 +874,8 @@ Node *lvar_initializer(Node *cur, Var *var, Type *ty, Designator *desg) {
cur = lvar_initializer(cur, var, ty->base, &desg2);
} while (i < limit && !peek_end() && consume(","));
if (open)
expect_end();
if (open && !consume_end())
skip_excess_elements();
// Set excess array elements to zero.
while (i < ty->array_size) {
@ -881,8 +900,8 @@ Node *lvar_initializer(Node *cur, Var *var, Type *ty, Designator *desg) {
mem = mem->next;
} while (mem && !peek_end() && consume(","));
if (open)
expect_end();
if (open && !consume_end())
skip_excess_elements();
// Set excess struct elements to zero.
for (; mem; mem = mem->next) {

View File

@ -43,7 +43,6 @@ void verror_at(char *loc, char *fmt, va_list ap) {
fprintf(stderr, "^ ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
exit(1);
}
// Reports an error location and exit.
@ -51,20 +50,33 @@ void error_at(char *loc, char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
verror_at(loc, fmt, ap);
exit(1);
}
// Reports an error location and exit.
void error_tok(Token *tok, char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
if (tok)
if (tok) {
verror_at(tok->str, fmt, ap);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
} else {
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
}
exit(1);
}
void warn_tok(Token *tok, char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
if (tok) {
verror_at(tok->str, fmt, ap);
} else {
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
}
}
char *strndup(char *p, int len) {
char *buf = malloc(len + 1);
strncpy(buf, p, len);