mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 13:30:45 +00:00
fix a var decl in scope preventing for loop spills
This commit is contained in:
parent
a3993465fe
commit
852679c369
@ -5701,23 +5701,30 @@ static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) {
|
||||
// (await y) + x
|
||||
static void mark_suspension_point(Scope *scope) {
|
||||
ScopeExpr *child_expr_scope = (scope->id == ScopeIdExpr) ? reinterpret_cast<ScopeExpr *>(scope) : nullptr;
|
||||
bool looking_for_exprs = true;
|
||||
for (;;) {
|
||||
scope = scope->parent;
|
||||
switch (scope->id) {
|
||||
case ScopeIdDefer:
|
||||
case ScopeIdDeferExpr:
|
||||
case ScopeIdDecls:
|
||||
case ScopeIdFnDef:
|
||||
case ScopeIdCompTime:
|
||||
case ScopeIdVarDecl:
|
||||
case ScopeIdCImport:
|
||||
case ScopeIdSuspend:
|
||||
case ScopeIdTypeOf:
|
||||
return;
|
||||
case ScopeIdVarDecl:
|
||||
case ScopeIdDefer:
|
||||
looking_for_exprs = false;
|
||||
continue;
|
||||
case ScopeIdLoop:
|
||||
case ScopeIdRuntime:
|
||||
continue;
|
||||
case ScopeIdExpr: {
|
||||
if (!looking_for_exprs) {
|
||||
// Now we're only looking for a block, to see if it's in a loop (see the case ScopeIdBlock)
|
||||
continue;
|
||||
}
|
||||
ScopeExpr *parent_expr_scope = reinterpret_cast<ScopeExpr *>(scope);
|
||||
if (child_expr_scope != nullptr) {
|
||||
for (size_t i = 0; parent_expr_scope->children_ptr[i] != child_expr_scope; i += 1) {
|
||||
|
||||
@ -1233,3 +1233,38 @@ test "spill target expr in a for loop" {
|
||||
resume S.global_frame;
|
||||
}
|
||||
|
||||
test "spill target expr in a for loop, with a var decl in the loop body" {
|
||||
const S = struct {
|
||||
var global_frame: anyframe = undefined;
|
||||
|
||||
fn doTheTest() void {
|
||||
var foo = Foo{
|
||||
.slice = [_]i32{1, 2},
|
||||
};
|
||||
expect(atest(&foo) == 3);
|
||||
}
|
||||
|
||||
const Foo = struct {
|
||||
slice: []i32,
|
||||
};
|
||||
|
||||
fn atest(foo: *Foo) i32 {
|
||||
var sum: i32 = 0;
|
||||
for (foo.slice) |x| {
|
||||
// Previously this var decl would prevent spills. This test makes sure
|
||||
// the for loop spills still happen even though there is a VarDecl in scope
|
||||
// before the suspend.
|
||||
var anything = true;
|
||||
_ = anything;
|
||||
suspend {
|
||||
global_frame = @frame();
|
||||
}
|
||||
sum += x;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
_ = async S.doTheTest();
|
||||
resume S.global_frame;
|
||||
resume S.global_frame;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user