Skip to content

Commit ff9c0b7

Browse files
committed
[GR-16991] The Else block of generator While loop is not executed.
PullRequest: graalpython/679
2 parents 5767e2a + e1dc1e6 commit ff9c0b7

File tree

5 files changed

+162
-37
lines changed

5 files changed

+162
-37
lines changed

graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/parser/GeneratorAndCompForTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,4 +316,18 @@ public void issueGR18174() throws Exception {
316316
public void issueGR18309() throws Exception {
317317
checkScopeAndTree("[ b for a in d1 if d1 for b in d2]");
318318
}
319+
320+
@Test
321+
public void issueGR16991() throws Exception {
322+
checkScopeAndTree(
323+
"def gen(x): \n" +
324+
" while x: \n" +
325+
" if x == 10: \n" +
326+
" break \n" +
327+
" x = x - 1 \n" +
328+
" yield x \n" +
329+
" else: \n" +
330+
" yield 100");
331+
}
332+
319333
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Scope: []
2+
Kind: Module
3+
FrameDescriptor: Empty
4+
CellVars: Empty
5+
FreeVars: Empty
6+
Scope: gen
7+
Kind: Generator
8+
FrameDescriptor: [x, <return_val>]
9+
CellVars: Empty
10+
FreeVars: Empty
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
ModuleRootNode Name: <module 'issueGR16991'> SourceSection: [0,105]`def gen(x): ↵ while...`
2+
Signature: varArgs=False, varKeywordArgs=False, noArguments=True, positionalOnly=True, requiresKeywordArgs=False
3+
FreeVars: None
4+
NeedsCellFrame: False
5+
FrameDescriptor: Empty
6+
Documentation: None
7+
InnerRootNode SourceSection: [0,105]`def gen(x): ↵ while...`
8+
ExpressionWithSideEffect SourceSection: [0,105]`def gen(x): ↵ while...`
9+
Expression:
10+
EmptyNode SourceSection: None
11+
SideEffect:
12+
WriteNameNodeGen SourceSection: [0,105]`def gen(x): ↵ while...`
13+
Identifier: gen
14+
GeneratorFunctionDefinitionNode Name: gen SourceSection: None
15+
FrameDescriptor: 2 slots [x, <return_val>]
16+
Active Flags: 4
17+
For Nodes: 0
18+
Block Nodes: 1
19+
Arguments: None
20+
KwArguments: None
21+
Documentation: StringLiteralNode: Empty
22+
FreeVarSlots: None
23+
ExecutionSlots:
24+
FreeVarsSlots: None
25+
CellVarsSlots: None
26+
FunctionRootNode SourceSection: [0,105]`def gen(x): ↵ while...`
27+
Name: gen
28+
Signature: varArgs=False, varKeywordArgs=False, noArguments=False, positionalOnly=True, requiresKeywordArgs=False
29+
Param Names: x
30+
CelVars: None
31+
FreeVars: None
32+
NeedsCellFrame: False
33+
FrameDescriptor: 2 slots [x, <return_val>]
34+
ExecutionSlots:
35+
FreeVarsSlots: None
36+
CellVarsSlots: None
37+
InnerRootNode SourceSection: [0,105]`def gen(x): ↵ while...`
38+
GeneratorReturnTargetNode SourceSection: [0,105]`def gen(x): ↵ while...`
39+
flagSlot: 3
40+
ElseNode SourceSection: [15,105]`while x: ↵ if x =...`
41+
GeneratorWhileNode SourceSection: None
42+
GeneratorBlockNode SourceSection: None
43+
IfNode SourceSection: [29,59]`if x == 10: ↵ b...`
44+
YesNodeGen SourceSection: None
45+
BinaryComparisonNodeGen SourceSection: [32,39]`x == 10`
46+
LookupAndCallBinaryNodeGen SourceSection: None
47+
Op: __eq__
48+
ReadGeneratorFrameVariableNode SourceSection: [32,33]`x`
49+
Frame: [0,x,Illegal]
50+
ReadVariableFromFrameNodeGen SourceSection: None
51+
IntegerLiteralNode SourceSection: [37,39]`10`
52+
Value: 10
53+
BreakNode SourceSection: [48,53]`break`
54+
BlockNode SourceSection: None
55+
WriteGeneratorFrameVariableNodeGen SourceSection: [59,68]`x = x - 1`
56+
Identifier: x
57+
WriteGeneraterFrameSlotNodeGen SourceSection: None
58+
Frame: [0,x,Illegal]
59+
BinaryArithmeticExpression SourceSection: [63,68]`x - 1`
60+
LookupAndCallBinaryNodeGen SourceSection: None
61+
Op: __sub__
62+
ReadGeneratorFrameVariableNode SourceSection: [63,64]`x`
63+
Frame: [0,x,Illegal]
64+
ReadVariableFromFrameNodeGen SourceSection: None
65+
IntegerLiteralNode SourceSection: [67,68]`1`
66+
Value: 1
67+
ExpressionStatementNode SourceSection: [74,81]`yield x`
68+
YieldNode SourceSection: [74,81]`yield x`
69+
flagSlot: 0
70+
ReadGeneratorFrameVariableNode SourceSection: [80,81]`x`
71+
Frame: [0,x,Illegal]
72+
ReadVariableFromFrameNodeGen SourceSection: None
73+
GeneratorAccessNode SourceSection: None
74+
GeneratorAccessNode SourceSection: None
75+
YesNodeGen SourceSection: None
76+
ReadGeneratorFrameVariableNode SourceSection: [21,22]`x`
77+
Frame: [0,x,Illegal]
78+
ReadVariableFromFrameNodeGen SourceSection: None
79+
GeneratorAccessNode SourceSection: None
80+
ExpressionStatementNode SourceSection: [96,105]`yield 100`
81+
YieldNode SourceSection: [96,105]`yield 100`
82+
flagSlot: 2
83+
IntegerLiteralNode SourceSection: [102,105]`100`
84+
Value: 100
85+
GeneratorAccessNode SourceSection: None
86+
ReadGeneratorFrameVariableNode SourceSection: None
87+
Frame: [1,<return_val>,Illegal]
88+
ReadVariableFromFrameNodeGen SourceSection: None
89+
WriteGeneratorFrameVariableNodeGen SourceSection: None
90+
Identifier: x
91+
WriteGeneraterFrameSlotNodeGen SourceSection: None
92+
Frame: [0,x,Illegal]
93+
ArgumentExpressionNode SourceSection: None
94+
ReadIndexedArgumentNodeGen SourceSection: None
95+
Index: 0
96+
GeneratorAccessNode SourceSection: None
97+
PRaiseNodeGen SourceSection: None

graalpython/com.oracle.graal.python.test/testData/goldenFiles/YieldStatementTests/while07.tast

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -37,45 +37,52 @@ ModuleRootNode Name: <module 'while07'> SourceSection: [0,101]`def gen(x):↵
3737
InnerRootNode SourceSection: [0,101]`def gen(x):↵ while...`
3838
GeneratorReturnTargetNode SourceSection: [0,101]`def gen(x):↵ while...`
3939
flagSlot: 3
40-
GeneratorWhileNode SourceSection: [15,101]`while x:↵ if x =...`
41-
GeneratorBlockNode SourceSection: None
42-
IfNode SourceSection: [29,58]`if x == 1:↵ br...`
43-
YesNodeGen SourceSection: None
44-
BinaryComparisonNodeGen SourceSection: [32,38]`x == 1`
40+
ElseNode SourceSection: [15,101]`while x:↵ if x =...`
41+
GeneratorWhileNode SourceSection: None
42+
GeneratorBlockNode SourceSection: None
43+
IfNode SourceSection: [29,58]`if x == 1:↵ br...`
44+
YesNodeGen SourceSection: None
45+
BinaryComparisonNodeGen SourceSection: [32,38]`x == 1`
46+
LookupAndCallBinaryNodeGen SourceSection: None
47+
Op: __eq__
48+
ReadGeneratorFrameVariableNode SourceSection: [32,33]`x`
49+
Frame: [0,x,Illegal]
50+
ReadVariableFromFrameNodeGen SourceSection: None
51+
IntegerLiteralNode SourceSection: [37,38]`1`
52+
Value: 1
53+
BreakNode SourceSection: [47,52]`break`
54+
BlockNode SourceSection: None
55+
WriteGeneratorFrameVariableNodeGen SourceSection: [58,65]`x = x-1`
56+
Identifier: x
57+
WriteGeneraterFrameSlotNodeGen SourceSection: None
58+
Frame: [0,x,Illegal]
59+
BinaryArithmeticExpression SourceSection: [62,65]`x-1`
4560
LookupAndCallBinaryNodeGen SourceSection: None
46-
Op: __eq__
47-
ReadGeneratorFrameVariableNode SourceSection: [32,33]`x`
61+
Op: __sub__
62+
ReadGeneratorFrameVariableNode SourceSection: [62,63]`x`
4863
Frame: [0,x,Illegal]
4964
ReadVariableFromFrameNodeGen SourceSection: None
50-
IntegerLiteralNode SourceSection: [37,38]`1`
65+
IntegerLiteralNode SourceSection: [64,65]`1`
5166
Value: 1
52-
BreakNode SourceSection: [47,52]`break`
53-
BlockNode SourceSection: None
54-
WriteGeneratorFrameVariableNodeGen SourceSection: [58,65]`x = x-1`
55-
Identifier: x
56-
WriteGeneraterFrameSlotNodeGen SourceSection: None
67+
ExpressionStatementNode SourceSection: [71,78]`yield x`
68+
YieldNode SourceSection: [71,78]`yield x`
69+
flagSlot: 0
70+
ReadGeneratorFrameVariableNode SourceSection: [77,78]`x`
71+
Frame: [0,x,Illegal]
72+
ReadVariableFromFrameNodeGen SourceSection: None
73+
GeneratorAccessNode SourceSection: None
74+
GeneratorAccessNode SourceSection: None
75+
YesNodeGen SourceSection: None
76+
ReadGeneratorFrameVariableNode SourceSection: [21,22]`x`
5777
Frame: [0,x,Illegal]
58-
BinaryArithmeticExpression SourceSection: [62,65]`x-1`
59-
LookupAndCallBinaryNodeGen SourceSection: None
60-
Op: __sub__
61-
ReadGeneratorFrameVariableNode SourceSection: [62,63]`x`
62-
Frame: [0,x,Illegal]
63-
ReadVariableFromFrameNodeGen SourceSection: None
64-
IntegerLiteralNode SourceSection: [64,65]`1`
65-
Value: 1
66-
ExpressionStatementNode SourceSection: [71,78]`yield x`
67-
YieldNode SourceSection: [71,78]`yield x`
68-
flagSlot: 0
69-
ReadGeneratorFrameVariableNode SourceSection: [77,78]`x`
70-
Frame: [0,x,Illegal]
71-
ReadVariableFromFrameNodeGen SourceSection: None
72-
GeneratorAccessNode SourceSection: None
78+
ReadVariableFromFrameNodeGen SourceSection: None
7379
GeneratorAccessNode SourceSection: None
74-
YesNodeGen SourceSection: None
75-
ReadGeneratorFrameVariableNode SourceSection: [21,22]`x`
76-
Frame: [0,x,Illegal]
77-
ReadVariableFromFrameNodeGen SourceSection: None
78-
GeneratorAccessNode SourceSection: None
80+
ExpressionStatementNode SourceSection: [93,101]`yield 10`
81+
YieldNode SourceSection: [93,101]`yield 10`
82+
flagSlot: 2
83+
IntegerLiteralNode SourceSection: [99,101]`10`
84+
Value: 10
85+
GeneratorAccessNode SourceSection: None
7986
ReadGeneratorFrameVariableNode SourceSection: None
8087
Frame: [1,<return_val>,Illegal]
8188
ReadVariableFromFrameNodeGen SourceSection: None

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/sst/GeneratorFactorySSTVisitor.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,14 +415,11 @@ public PNode visit(WhileSSTNode node) {
415415
if (!node.containsBreak) {
416416
result = nodeFactory.createElse(whileNode, elseBranch);
417417
} else if (oldNumber == numOfActiveFlags) {
418-
// TODO: The old parser doesn't enclude the else branch to the tree. See issue GR-16991
419-
// TODO: this is also strange, that we create don't create ElseNode for break target.
420-
// At least it seems to be inconsistent.
421418
result = node.elseStatement == null ?
422419
// TODO: Do we need to create the empty block here?
423420
nodeFactory.createBreakTarget(whileNode, nodeFactory.createBlock(new StatementNode[0])) : nodeFactory.createBreakTarget(whileNode, elseBranch);
424421
} else {
425-
result = whileNode;
422+
result = node.elseStatement == null ? whileNode : nodeFactory.createElse(whileNode, elseBranch);
426423
}
427424
result.assignSourceSection(createSourceSection(node.startOffset, node.endOffset));
428425
return result;

0 commit comments

Comments
 (0)