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.
Unified · Split
| @@ -7051,6 +7051,31 @@ static void lblock(int *bsym, int *csym) · 7050 unmodified lines | ||
| 7051 | 7051 | } |
| 7052 | 7052 | } |
| 7053 | 7053 | |
| 7054 | +static void condition_expresion(void) | |
| 7055 | +{ | |
| 7056 | + Sym *s; | |
| 7057 | + int decl_ret; | |
| 7058 | + | |
| 7059 | + /* c2y if init decl? */ | |
| 7060 | + if (!(decl_ret = decl(VT_JMPI))) { | |
| 7061 | + /* no, regular if init expr */ | |
| 7062 | + gexpr(); | |
| 7063 | + } else { | |
| 7064 | + if (decl_ret == 1) | |
| 7065 | + tcc_error("declaration in the controlling expression must have an initializer"); | |
| 7066 | + | |
| 7067 | + if (tok == ';') { | |
| 7068 | + /* finish the push */ | |
| 7069 | + next(); | |
| 7070 | + gexpr(); | |
| 7071 | + } else { | |
| 7072 | + s = sym_find(decl_ret); | |
| 7073 | + vset(&s->type, s->r, s->c); | |
| 7074 | + vtop->sym = s; | |
| 7075 | + } | |
| 7076 | + } | |
| 7077 | +} | |
| 7078 | + | |
| 7054 | 7079 | static void block(int flags) |
| 7055 | 7080 | { |
| 7056 | 7081 | int a, b, c, d, e, t; |
| @@ -7071,7 +7096,7 @@ again: · 14 unmodified lines | ||
| 7071 | 7096 | if (t == TOK_IF) { |
| 7072 | 7097 | new_scope_s(&o); |
| 7073 | 7098 | skip('('); |
| 7074 | − gexpr(); | |
| 7099 | + condition_expresion(); | |
| 7075 | 7100 | a = gvtst(1, 0); |
| 7076 | 7101 | skip(')'); |
| 7077 | 7102 | block(0); |
| @@ -7240,7 +7265,7 @@ again: · 162 unmodified lines | ||
| 7240 | 7265 | |
| 7241 | 7266 | new_scope_s(&o); |
| 7242 | 7267 | skip('('); |
| 7243 | − gexpr(); | |
| 7268 | + condition_expresion(); | |
| 7244 | 7269 | if (!is_integer_btype(vtop->type.t & VT_BTYPE)) |
| 7245 | 7270 | tcc_error("switch value not an integer"); |
| 7246 | 7271 | skip(')'); |
| @@ -8562,7 +8587,9 @@ static void pe_check_linkage(CType *type, AttributeDef *ad) · 1315 unmodified lines | ||
| 8562 | 8587 | |
| 8563 | 8588 | /* 'l' is VT_LOCAL or VT_CONST to define default storage type |
| 8564 | 8589 | or VT_CMP if parsing old style parameter list |
| 8565 | − or VT_JMP if parsing c99 for decl: for (int i = 0, ...) */ | |
| 8590 | + or VT_JMP if parsing c99 for decl: for (int i = 0, ...) | |
| 8591 | + or VT_JMPI if parsing c2y if decl; if (int = 0; ...) | |
| 8592 | +*/ | |
| 8566 | 8593 | static int decl(int l) |
| 8567 | 8594 | { |
| 8568 | 8595 | int v, has_init, r, oldint; |
| @@ -8575,7 +8602,7 @@ static int decl(int l) · 6 unmodified lines | ||
| 8575 | 8602 | |
| 8576 | 8603 | oldint = 0; |
| 8577 | 8604 | if (!parse_btype(&btype, &adbase, l == VT_LOCAL)) { |
| 8578 | − if (l == VT_JMP) | |
| 8605 | + if (l == VT_JMP || l == VT_JMPI) | |
| 8579 | 8606 | return 0; |
| 8580 | 8607 | /* skip redundant ';' if not in old parameter decl scope */ |
| 8581 | 8608 | if (tok == ';' && l != VT_CMP) { |
| @@ -8815,10 +8842,12 @@ static int decl(int l) · 233 unmodified lines | ||
| 8815 | 8842 | } |
| 8816 | 8843 | } |
| 8817 | 8844 | if (tok != ',') { |
| 8818 | − if (l == VT_JMP) | |
| 8845 | + if (l == VT_JMP || l == VT_JMPI) | |
| 8819 | 8846 | return has_init ? v : 1; |
| 8820 | 8847 | skip(';'); |
| 8821 | 8848 | break; |
| 8849 | + } else if (l == VT_JMPI) { | |
| 8850 | + tcc_error("declaration in condition can only declare a single object"); | |
| 8822 | 8851 | } |
| 8823 | 8852 | next(); |
| 8824 | 8853 | } |