mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
Fix bugzilla issue 24566 - condition that starts with runtime value and uses compile time array does not short circuit
This commit is contained in:
parent
f56d15b9f0
commit
d92734bdac
2 changed files with 60 additions and 10 deletions
|
@ -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)
|
||||
|
|
23
compiler/test/compilable/issue24566.d
Normal file
23
compiler/test/compilable/issue24566.d
Normal file
|
@ -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') {}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue