From f52b480f89d41988f656be19cd3a38be47a2356d Mon Sep 17 00:00:00 2001 From: Matthias Gatto Date: Fri, 8 Aug 2025 01:04:25 +0200 Subject: [PATCH] c2y if declaration (std n3356) standart is here: https://www.open-std.org/JTC1/SC22/WG14/www/docs/n3356.htm This feature should not add bug to existing features, as it is called only if there is a declaration in a switch or an if. --- tccgen.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/tccgen.c b/tccgen.c index e309f621..770370c5 100644 --- a/tccgen.c +++ b/tccgen.c @@ -7051,6 +7051,31 @@ static void lblock(int *bsym, int *csym) } } +static void condition_expresion(void) +{ + Sym *s; + int decl_ret; + + /* c2y if init decl? */ + if (!(decl_ret = decl(VT_JMPI))) { + /* no, regular if init expr */ + gexpr(); + } else { + if (decl_ret == 1) + tcc_error("declaration in the controlling expression must have an initializer"); + + if (tok == ';') { + /* finish the push */ + next(); + gexpr(); + } else { + s = sym_find(decl_ret); + vset(&s->type, s->r, s->c); + vtop->sym = s; + } + } +} + static void block(int flags) { int a, b, c, d, e, t; @@ -7071,7 +7096,7 @@ again: if (t == TOK_IF) { new_scope_s(&o); skip('('); - gexpr(); + condition_expresion(); a = gvtst(1, 0); skip(')'); block(0); @@ -7240,7 +7265,7 @@ again: new_scope_s(&o); skip('('); - gexpr(); + condition_expresion(); if (!is_integer_btype(vtop->type.t & VT_BTYPE)) tcc_error("switch value not an integer"); skip(')'); @@ -8562,7 +8587,9 @@ static void pe_check_linkage(CType *type, AttributeDef *ad) /* 'l' is VT_LOCAL or VT_CONST to define default storage type or VT_CMP if parsing old style parameter list - or VT_JMP if parsing c99 for decl: for (int i = 0, ...) */ + or VT_JMP if parsing c99 for decl: for (int i = 0, ...) + or VT_JMPI if parsing c2y if decl; if (int = 0; ...) +*/ static int decl(int l) { int v, has_init, r, oldint; @@ -8575,7 +8602,7 @@ static int decl(int l) oldint = 0; if (!parse_btype(&btype, &adbase, l == VT_LOCAL)) { - if (l == VT_JMP) + if (l == VT_JMP || l == VT_JMPI) return 0; /* skip redundant ';' if not in old parameter decl scope */ if (tok == ';' && l != VT_CMP) { @@ -8815,10 +8842,12 @@ static int decl(int l) } } if (tok != ',') { - if (l == VT_JMP) + if (l == VT_JMP || l == VT_JMPI) return has_init ? v : 1; skip(';'); break; + } else if (l == VT_JMPI) { + tcc_error("declaration in condition can only declare a single object"); } next(); }