Fix bug with nested if's; fix missing EXPR wrap.

097c054 introduced a bug that we hadn't caught until now.

In some occasions, it could swap nested conditions in such a way that the 'else' of the outer statement was made to belong to the inner one, like this:

    if (a)
        if (b)
            stuff;
    else
        stuff;

That is of course parsed with the 'else' belonging to if(b).

Fix implemented at output time, by detecting 'if(a) stmt; else y;' with stmt being an 'if' without 'else', and wrapping the stmt in {} like this: 'if(a){if(b) x;} else y;'. This has some similarity with parenthesis addition.

But the fix has the corner case that, since {} hides visibility of labels, when the inner 'if' has a label as direct child, it can't be swapped lest the label becomes out of scope. So these cases are detected and skipped in the constant folding module.

In the case of 'if(cond);', we transform it to 'cond;', but we forgot to wrap the cond in an EXPR node as required. Fixed too.
This commit is contained in:
Sei Lisa 2017-11-13 03:50:05 +01:00
parent a4b3c1eadd
commit e42479756b
2 changed files with 33 additions and 10 deletions

View file

@ -384,7 +384,15 @@ class outscript(object):
if nt == 'IF':
ret = self.dent()
while True:
ret += 'if (' + self.OutExpr(child[0]) + ')\n' + self.OutIndented(child[1])
ret += 'if (' + self.OutExpr(child[0]) + ')\n'
if (len(child) == 3
and child[1]['nt'] == 'IF' and len(child[1]['ch']) < 3
):
ret += self.dent() + '{\n'
ret += self.OutIndented(child[1])
ret += self.dent() + '}\n'
else:
ret += self.OutIndented(child[1])
if len(child) < 3:
return ret
if child[2]['nt'] != 'IF':