diff options
| -rw-r--r-- | .gitmodules | 3 | ||||
| -rw-r--r-- | c/c.c | 40 | ||||
| m--------- | test/external/sqlite | 0 |
3 files changed, 31 insertions, 12 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..badbe0a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "test/external/sqlite"] + path = test/external/sqlite + url = https://github.com/sqlite/sqlite @@ -1238,7 +1238,7 @@ Unary: struct expr *sub; span.sl = tk.span.sl; span.ex = ex.span.ex; - if (!isscalar(ex.ty)) + if (!isscalar(ex.ty) && !isptrcvt(ex.ty)) error(&ex.span, "?: condition is not a scalar type: '%ty'", ex.ty); tmp = commaexpr(cm); joinspan(&tk.span.ex, tmp.span.ex); @@ -3469,6 +3469,26 @@ genbitfstore(struct function *fn, const union type ty, union ref addr, genstore(fn, ty, addr, val); } +static bool +knowntruthy(bool *t, struct expr *ex) +{ + if (!eval(ex, EVFOLD)) return 0; + + switch (ex->t) { + default: assert(0 && "!scalar?"); + case ENUMLIT: + *t = isflt(ex->ty) ? ex->f != 0.0 : ex->u != 0; + break; + case ESYM: + assert(isptrcvt(ex->ty)); + case ESTRLIT: + /* string literals & symbol addresses are always truthy */ + *t = 1; + break; + } + return 1; +} + union ref compileexpr(struct function *fn, const struct expr *ex, bool discard) { @@ -3738,12 +3758,10 @@ compileexpr(struct function *fn, const struct expr *ex, bool discard) return narrow(fn, cls, ex->ty, r, 0); return r; case ECOND: - if (eval(&ex->sub[0], EVFOLD)) { - bool k = isflt(ex->sub[0].ty) ? ex->sub[0].f != 0.0 : ex->sub[0].u != 0; - assert(ex->sub[0].t == ENUMLIT); - r = compileexpr(fn, &ex->sub[2-k], discard); + for (bool c; knowntruthy(&c, &ex->sub[0]);) { + r = compileexpr(fn, &ex->sub[2-c], discard); if (discard) return NOREF; - return cvt(fn, ex->ty, ex->sub[2-k].ty, r); + return cvt(fn, ex->ty, ex->sub[2-c].ty, r); } if (ex->ty.t == TYVOID || discard) { @@ -3764,13 +3782,11 @@ compileexpr(struct function *fn, const struct expr *ex, bool discard) return condexprvalue(fn, ex, discard); case ELOGAND: case ELOGIOR: - if (eval(&ex->sub[0], EVFOLD)) { - bool k = isflt(ex->sub[0].ty) ? ex->sub[0].f != 0.0 : ex->sub[0].u != 0; - assert(ex->sub[0].t == ENUMLIT); - k ^= ex->t == ELOGIOR; - r = compileexpr(fn, &ex->sub[k], discard); + for (bool c; knowntruthy(&c, &ex->sub[0]);) { + c ^= ex->t == ELOGIOR; + r = compileexpr(fn, &ex->sub[c], discard); if (discard) return NOREF; - return cvt(fn, mktype(TYBOOL), ex->sub[k].ty, r); + return cvt(fn, mktype(TYBOOL), ex->sub[c].ty, r); } return condexprvalue(fn, ex, discard); case ESEQ: diff --git a/test/external/sqlite b/test/external/sqlite new file mode 160000 +Subproject 60f132bf1288549ef1e7043f4a88fe6e199f0cf |