Kaydet (Commit) f1a7178c authored tarafından Amaury Forgeot d'Arc's avatar Amaury Forgeot d'Arc

#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.
üst d933e0a7
...@@ -511,6 +511,15 @@ while 0: pass ...@@ -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
......
...@@ -12,6 +12,11 @@ What's New in Python 2.5.2c1? ...@@ -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).
......
...@@ -2256,8 +2256,11 @@ compiler_while(struct compiler *c, stmt_ty s) ...@@ -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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment