aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--tccgen.c103
-rw-r--r--tests/tests2/78_vla_label.c6
3 files changed, 58 insertions, 52 deletions
diff --git a/TODO b/TODO
index ea57823..ffe4ad1 100644
--- a/TODO
+++ b/TODO
@@ -68,7 +68,6 @@ Not critical:
to suppress VT_LOCAL and use a base register instead).
- interactive mode / integrated debugger
- fix preprocessor symbol redefinition
-- better constant opt (&&, ||, ?:)
- add portable byte code generator and interpreter for other
unsupported architectures.
- C++: variable declaration in for, minimal 'class' support.
diff --git a/tccgen.c b/tccgen.c
index e2d9e21..3b5ad75 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -4453,80 +4453,83 @@ static void expr_or(void)
}
}
-/* XXX: fix this mess */
-static void expr_land_const(void)
-{
- expr_or();
- while (tok == TOK_LAND) {
- next();
- expr_or();
- gen_op(TOK_LAND);
- }
-}
-
-/* XXX: fix this mess */
-static void expr_lor_const(void)
-{
- expr_land_const();
- while (tok == TOK_LOR) {
- next();
- expr_land_const();
- gen_op(TOK_LOR);
- }
-}
-
-/* only used if non constant */
static void expr_land(void)
{
- int t;
-
expr_or();
if (tok == TOK_LAND) {
- t = 0;
- save_regs(1);
- for(;;) {
- t = gvtst(1, t);
- if (tok != TOK_LAND) {
- vseti(VT_JMPI, t);
- break;
- }
+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ CType ctb, cti;
+ ctb.t = VT_BOOL;
+ cti.t = VT_INT;
next();
- expr_or();
+ gen_cast(&ctb);
+ if (vtop->c.i) {
+ vpop();
+ expr_land();
+ gen_cast(&ctb);
+ } else {
+ expr_land();
+ vpop();
+ }
+ gen_cast(&cti);
+ } else {
+ int t = 0;
+ save_regs(1);
+ for(;;) {
+ t = gvtst(1, t);
+ if (tok != TOK_LAND) {
+ vseti(VT_JMPI, t);
+ break;
+ }
+ next();
+ expr_or();
+ }
}
}
}
static void expr_lor(void)
{
- int t;
-
expr_land();
if (tok == TOK_LOR) {
- t = 0;
- save_regs(1);
- for(;;) {
- t = gvtst(0, t);
- if (tok != TOK_LOR) {
- vseti(VT_JMP, t);
- break;
- }
+ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ CType ctb, cti;
+ ctb.t = VT_BOOL;
+ cti.t = VT_INT;
next();
- expr_land();
+ gen_cast(&ctb);
+ if (vtop->c.i) {
+ expr_lor();
+ vpop();
+ } else {
+ vpop();
+ expr_lor();
+ gen_cast(&ctb);
+ }
+ gen_cast(&cti);
+ } else {
+ int t = 0;
+ save_regs(1);
+ for(;;) {
+ t = gvtst(0, t);
+ if (tok != TOK_LOR) {
+ vseti(VT_JMP, t);
+ break;
+ }
+ next();
+ expr_land();
+ }
}
}
}
-/* XXX: better constant handling */
static void expr_cond(void)
{
int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
SValue sv;
CType type, type1, type2;
- if (const_wanted)
- expr_lor_const();
- else
- expr_lor();
+ expr_lor();
if (tok == '?') {
next();
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
diff --git a/tests/tests2/78_vla_label.c b/tests/tests2/78_vla_label.c
index 93a8b08..39654c6 100644
--- a/tests/tests2/78_vla_label.c
+++ b/tests/tests2/78_vla_label.c
@@ -17,9 +17,13 @@ void f2(void)
{
goto start;
{
- int a[1 ? 1 : 1]; /* not a variable-length array */
+ int a[1 && 1]; /* not a variable-length array */
+ int b[1 || 1]; /* not a variable-length array */
+ int c[1 ? 1 : 1]; /* not a variable-length array */
start:
a[0] = 0;
+ b[0] = 0;
+ c[0] = 0;
}
}