mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
translate_c: prevent a while under an if from stealing the else
This commit is contained in:
parent
135cb529de
commit
2d7b55aa0a
2 changed files with 40 additions and 9 deletions
|
|
@ -2808,14 +2808,16 @@ fn maybeBlockify(c: *Context, scope: *Scope, stmt: *const clang.Stmt) TransError
|
|||
.NullStmtClass,
|
||||
.WhileStmtClass,
|
||||
=> return transStmt(c, scope, stmt, .unused),
|
||||
else => {
|
||||
else => return blockify(c, scope, stmt),
|
||||
}
|
||||
}
|
||||
|
||||
fn blockify(c: *Context, scope: *Scope, stmt: *const clang.Stmt) TransError!Node {
|
||||
var block_scope = try Scope.Block.init(c, scope, false);
|
||||
defer block_scope.deinit();
|
||||
const result = try transStmt(c, &block_scope.base, stmt, .unused);
|
||||
try block_scope.statements.append(result);
|
||||
return block_scope.complete(c);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn transIfStmt(
|
||||
|
|
@ -2835,9 +2837,21 @@ fn transIfStmt(
|
|||
const cond_expr = @ptrCast(*const clang.Expr, stmt.getCond());
|
||||
const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used);
|
||||
|
||||
const then_body = try maybeBlockify(c, scope, stmt.getThen());
|
||||
const then_stmt = stmt.getThen();
|
||||
const else_stmt = stmt.getElse();
|
||||
const then_class = then_stmt.getStmtClass();
|
||||
// block needed to keep else statement from attaching to inner while
|
||||
const must_blockify = (else_stmt != null) and switch (then_class) {
|
||||
.DoStmtClass, .ForStmtClass, .WhileStmtClass => true,
|
||||
else => false,
|
||||
};
|
||||
|
||||
const else_body = if (stmt.getElse()) |expr|
|
||||
const then_body = if (must_blockify)
|
||||
try blockify(c, scope, then_stmt)
|
||||
else
|
||||
try maybeBlockify(c, scope, then_stmt);
|
||||
|
||||
const else_body = if (else_stmt) |expr|
|
||||
try maybeBlockify(c, scope, expr)
|
||||
else
|
||||
null;
|
||||
|
|
|
|||
|
|
@ -1767,4 +1767,21 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
|
|||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
|
||||
cases.add("Ensure while loop under an if doesn't steal the else. Issue #9953",
|
||||
\\#include <stdio.h>
|
||||
\\void doWork(int id) { }
|
||||
\\int reallyDelete(int id) { printf("deleted %d\n", id); return 1; }
|
||||
\\int process(int id, int n, int delete) {
|
||||
\\ if(!delete)
|
||||
\\ while(n-- > 0) doWork(id);
|
||||
\\ else
|
||||
\\ return reallyDelete(id);
|
||||
\\ return 0;
|
||||
\\}
|
||||
\\int main(void) {
|
||||
\\ process(99, 3, 0);
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue