#1920: when considering a block starting by "while 0", the compiler optimized the

whole construct away, even when an 'else' clause is present::

    while 0:
        print("no")
    else:
        print("yes")

did not generate any code at all.

Now the compiler emits the 'else' block, like it already does for 'if' statements.

Backport of r60265.
This commit is contained in:
Amaury Forgeot d'Arc 2008-01-24 23:42:08 +00:00
parent d933e0a7d3
commit f1a7178cd5
3 changed files with 18 additions and 1 deletions

View File

@ -511,6 +511,15 @@ while 0: pass
while 0: pass while 0: pass
else: pass else: pass
# Issue1920: "while 0" is optimized away,
# ensure that the "else" clause is still present.
x = 0
while 0:
x = 1
else:
x = 2
assert x == 2
print 'for_stmt' # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] print 'for_stmt' # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
for i in 1, 2, 3: pass for i in 1, 2, 3: pass
for i, j, k in (): pass for i, j, k in (): pass

View File

@ -12,6 +12,11 @@ What's New in Python 2.5.2c1?
Core and builtins Core and builtins
----------------- -----------------
- Issue #1920: "while 0" statements were completely removed by the compiler,
even in the presence of an "else" clause, which is supposed to be run when
the condition is false. Now the compiler correctly emits bytecode for the
"else" suite.
- A few crashers fixed: weakref_in_del.py (issue #1377858); - A few crashers fixed: weakref_in_del.py (issue #1377858);
loosing_dict_ref.py (issue #1303614, test67.py); loosing_dict_ref.py (issue #1303614, test67.py);
borrowed_ref_[34].py (not in tracker). borrowed_ref_[34].py (not in tracker).

View File

@ -2256,8 +2256,11 @@ compiler_while(struct compiler *c, stmt_ty s)
basicblock *loop, *orelse, *end, *anchor = NULL; basicblock *loop, *orelse, *end, *anchor = NULL;
int constant = expr_constant(s->v.While.test); int constant = expr_constant(s->v.While.test);
if (constant == 0) if (constant == 0) {
if (s->v.While.orelse)
VISIT_SEQ(c, stmt, s->v.While.orelse);
return 1; return 1;
}
loop = compiler_new_block(c); loop = compiler_new_block(c);
end = compiler_new_block(c); end = compiler_new_block(c);
if (constant == -1) { if (constant == -1) {