diff --git a/tcc.h b/tcc.h index 6d37860..2db18bc 100644 --- a/tcc.h +++ b/tcc.h @@ -1094,6 +1094,7 @@ ST_FUNC void gexpr(void); ST_FUNC int expr_const(void); ST_FUNC void gen_inline_functions(void); ST_FUNC void decl(int l); +ST_FUNC void for_loop_init(); #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size); #endif diff --git a/tccgen.c b/tccgen.c index 8a50832..32a2060 100644 --- a/tccgen.c +++ b/tccgen.c @@ -4376,8 +4376,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, next(); skip('('); if (tok != ';') { - gexpr(); - vpop(); + for_loop_init(); } skip(';'); d = ind; @@ -5403,7 +5402,7 @@ ST_FUNC void gen_inline_functions(void) } /* 'l' is VT_LOCAL or VT_CONST to define default storage type */ -ST_FUNC void decl(int l) +static void decl0(int l, int is_for_loop_init) { int v, has_init, r; CType type, btype; @@ -5412,6 +5411,11 @@ ST_FUNC void decl(int l) while (1) { if (!parse_btype(&btype, &ad)) { + if (is_for_loop_init) { + gexpr(); + vpop(); + return; + } /* skip redundant ';' */ /* XXX: find more elegant solution */ if (tok == ';') { @@ -5626,6 +5630,8 @@ ST_FUNC void decl(int l) } } if (tok != ',') { + if (is_for_loop_init) + return; skip(';'); break; } @@ -5634,3 +5640,13 @@ ST_FUNC void decl(int l) } } } + +ST_FUNC void for_loop_init(void) +{ + decl0(VT_LOCAL, 1); +} + +ST_FUNC void decl(int l) +{ + decl0(l, 0); +} diff --git a/tests/Makefile b/tests/Makefile index 4bebc2b..d1c732a 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -42,7 +42,7 @@ libtcc_test$(EXESUF): libtcc_test.c ../$(LIBTCC) # copy only tcclib.h so GCC's stddef and stdarg will be used test.ref: tcctest.c cp -u ../include/tcclib.h . - $(CC) -o tcctest.gcc $< -I. -w $(CFLAGS) + $(CC) -o tcctest.gcc $< -I. -w $(CFLAGS) -std=gnu99 ./tcctest.gcc > $@ # auto test diff --git a/tests/tcctest.c b/tests/tcctest.c index 1b2fb36..e0e0dba 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -387,6 +387,10 @@ void loop_test() } while (i < 10); printf("\n"); + /* c99 for loop init test */ + for (size_t count = 1; count < 3; count++) + printf("count=%d\n", count); + /* break/continue tests */ i = 0; while (1) {