diff --git a/compiler/src/dmd/optimize.d b/compiler/src/dmd/optimize.d index 2c89a58d5d..649ef10b6a 100644 --- a/compiler/src/dmd/optimize.d +++ b/compiler/src/dmd/optimize.d @@ -1238,18 +1238,21 @@ Expression optimize(Expression e, int result, bool keepLvalue = false) if (expOptimize(e.e1, WANTvalue)) return; const oror = e.op == EXP.orOr; + void returnE_e1() + { + ret = e.e1; + if (!e.e1.type.equals(e.type)) + { + ret = new CastExp(e.loc, ret, e.type); + ret.type = e.type; + ret = optimize(ret, result, false); + } + } if (e.e1.toBool().hasValue(oror)) { - // Replace with (e1, oror) - ret = IntegerExp.createBool(oror); - ret = Expression.combine(e.e1, ret); - if (e.type.toBasetype().ty == Tvoid) - { - ret = new CastExp(e.loc, ret, Type.tvoid); - ret.type = e.type; - } - ret = optimize(ret, result, false); - return; + // e_true || e2 -> e_true + // e_false && e2 -> e_false + return returnE_e1(); } expOptimize(e.e2, WANTvalue); if (e.e1.isConst()) @@ -1263,6 +1266,7 @@ Expression optimize(Expression e, int result, bool keepLvalue = false) } else if (e1Opt.hasValue(!oror)) { + if (e.type.toBasetype().ty == Tvoid) ret = e.e2; else @@ -1272,6 +1276,29 @@ Expression optimize(Expression e, int result, bool keepLvalue = false) } } } + else if (e.e2.isConst()) + { + const e2Opt = e.e2.toBool(); + if (e2Opt.hasValue(oror)) + { + // e1 || true -> (e1, true) + // e1 && false -> (e1, false) + ret = IntegerExp.createBool(oror); + ret = Expression.combine(e.e1, ret); + if (e.type.toBasetype().ty == Tvoid) + { + ret = new CastExp(e.loc, ret, Type.tvoid); + ret.type = e.type; + } + ret = optimize(ret, result, false); + } + else if (e2Opt.hasValue(!oror)) + { + // e1 || false -> e1 + // e1 && true -> e1 + return returnE_e1(); + } + } } void visitCmp(CmpExp e) diff --git a/compiler/test/compilable/issue24566.d b/compiler/test/compilable/issue24566.d new file mode 100644 index 0000000000..df1bf6f0e1 --- /dev/null +++ b/compiler/test/compilable/issue24566.d @@ -0,0 +1,23 @@ +// https://issues.dlang.org/show_bug.cgi?id=24566 + +void test24566a() +{ + enum a = true; + bool b = true; + enum str = "a"; + if (a && str.length > 1 && str[1] == 'a') {} + if (b && str.length > 1 && str[1] == 'a') {} + if (!b && str.length > 1 && str[1] == 'a') {} + if (str.length > 1 && b && str[1] == 'a') {} +} + +void test24566b() +{ + enum a = false; + bool b = false; + enum str = "a"; + if (a || str.length <= 1 || str[1] == 'a') {} + if (b || str.length <= 1 || str[1] == 'a') {} + if (!b || str.length <= 1 || str[1] == 'a') {} + if (str.length <= 1 || b || str[1] == 'a') {} +}