mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
AstGen: structInitExpr and arrayInitExpr avoid crash
when an inferred alloc is passed as the result pointer of a block.
This commit is contained in:
parent
a30d283981
commit
273da9efd9
@ -1360,6 +1360,12 @@ fn arrayInitExpr(
|
||||
}
|
||||
},
|
||||
.block_ptr => |block_gz| {
|
||||
// This condition is here for the same reason as the above condition in `inferred_ptr`.
|
||||
// See corresponding logic in structInitExpr.
|
||||
if (types.array == .none and astgen.isInferred(block_gz.rl_ptr)) {
|
||||
const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon);
|
||||
return rvalue(gz, rl, result, node);
|
||||
}
|
||||
return arrayInitExprRlPtr(gz, scope, rl, node, block_gz.rl_ptr, array_init.ast.elements, types.array);
|
||||
},
|
||||
}
|
||||
@ -1604,7 +1610,16 @@ fn structInitExpr(
|
||||
return structInitExprRlPtr(gz, scope, rl, node, struct_init, ptr_inst);
|
||||
}
|
||||
},
|
||||
.block_ptr => |block_gz| return structInitExprRlPtr(gz, scope, rl, node, struct_init, block_gz.rl_ptr),
|
||||
.block_ptr => |block_gz| {
|
||||
// This condition is here for the same reason as the above condition in `inferred_ptr`.
|
||||
// See corresponding logic in arrayInitExpr.
|
||||
if (struct_init.ast.type_expr == 0 and astgen.isInferred(block_gz.rl_ptr)) {
|
||||
const result = try structInitExprRlNone(gz, scope, node, struct_init, .struct_init_anon);
|
||||
return rvalue(gz, rl, result, node);
|
||||
}
|
||||
|
||||
return structInitExprRlPtr(gz, scope, rl, node, struct_init, block_gz.rl_ptr);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -10938,3 +10953,17 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.
|
||||
}
|
||||
return decl_count;
|
||||
}
|
||||
|
||||
fn isInferred(astgen: *AstGen, ref: Zir.Inst.Ref) bool {
|
||||
const inst = refToIndex(ref) orelse return false;
|
||||
const zir_tags = astgen.instructions.items(.tag);
|
||||
return switch (zir_tags[inst]) {
|
||||
.alloc_inferred,
|
||||
.alloc_inferred_mut,
|
||||
.alloc_inferred_comptime,
|
||||
.alloc_inferred_comptime_mut,
|
||||
=> true,
|
||||
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
@ -516,7 +516,7 @@ pub const Inst = struct {
|
||||
/// Same as `store` except provides a source location.
|
||||
/// Uses the `pl_node` union field. Payload is `Bin`.
|
||||
store_node,
|
||||
/// This instruction is not really supposed to be emitted from AstGen; nevetheless it
|
||||
/// This instruction is not really supposed to be emitted from AstGen; nevertheless it
|
||||
/// is sometimes emitted due to deficiencies in AstGen. When Sema sees this instruction,
|
||||
/// it must clean up after AstGen's mess by looking at various context clues and
|
||||
/// then treating it as one of the following:
|
||||
|
||||
@ -49,19 +49,17 @@ fn constant() !void {
|
||||
}
|
||||
|
||||
test "pointer-to-array constness for zero-size elements, var" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try mutable();
|
||||
comptime try mutable();
|
||||
}
|
||||
|
||||
test "pointer-to-array constness for zero-size elements, const" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try constant();
|
||||
comptime try constant();
|
||||
}
|
||||
|
||||
@ -165,3 +165,35 @@ test "array-like initializer for tuple types" {
|
||||
try S.doTheTest();
|
||||
comptime try S.doTheTest();
|
||||
}
|
||||
|
||||
test "anon struct as the result from a labeled block" {
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
const precomputed = comptime blk: {
|
||||
var x: i32 = 1234;
|
||||
break :blk .{
|
||||
.x = x,
|
||||
};
|
||||
};
|
||||
try expect(precomputed.x == 1234);
|
||||
}
|
||||
};
|
||||
|
||||
try S.doTheTest();
|
||||
comptime try S.doTheTest();
|
||||
}
|
||||
|
||||
test "tuple as the result from a labeled block" {
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
const precomputed = comptime blk: {
|
||||
var x: i32 = 1234;
|
||||
break :blk .{x};
|
||||
};
|
||||
try expect(precomputed[0] == 1234);
|
||||
}
|
||||
};
|
||||
|
||||
try S.doTheTest();
|
||||
comptime try S.doTheTest();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user