mirror of
https://github.com/ziglang/zig.git
synced 2026-01-05 13:03:25 +00:00
Sema: fix reify Fn alignment and args
This commit is contained in:
parent
4831c1c65f
commit
292906fb23
18
src/Sema.zig
18
src/Sema.zig
@ -16429,10 +16429,24 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
|
||||
return sema.fail(block, src, "varargs functions must have C calling convention", .{});
|
||||
}
|
||||
|
||||
const alignment = @intCast(u29, alignment_val.toUnsignedInt(target)); // TODO: Validate this value.
|
||||
const alignment = alignment: {
|
||||
if (!try sema.intFitsInType(block, src, alignment_val, Type.u32, null)) {
|
||||
return sema.fail(block, src, "alignment must fit in 'u32'", .{});
|
||||
}
|
||||
const alignment = @intCast(u29, alignment_val.toUnsignedInt(target));
|
||||
if (alignment == target_util.defaultFunctionAlignment(target)) {
|
||||
break :alignment 0;
|
||||
} else {
|
||||
break :alignment alignment;
|
||||
}
|
||||
};
|
||||
var buf: Value.ToTypeBuffer = undefined;
|
||||
|
||||
const args: []Value = if (args_val.castTag(.aggregate)) |some| some.data else &.{};
|
||||
const args_slice_val = args_val.castTag(.slice).?.data;
|
||||
const args_decl_index = args_slice_val.ptr.pointerDecl().?;
|
||||
try sema.ensureDeclAnalyzed(args_decl_index);
|
||||
const args_decl = mod.declPtr(args_decl_index);
|
||||
const args: []Value = if (args_decl.val.castTag(.aggregate)) |some| some.data else &.{};
|
||||
var param_types = try sema.arena.alloc(Type, args.len);
|
||||
var comptime_params = try sema.arena.alloc(bool, args.len);
|
||||
var noalias_bits: u32 = 0;
|
||||
|
||||
@ -247,26 +247,17 @@ fn add(a: i32, b: i32) i32 {
|
||||
}
|
||||
|
||||
test "Type.ErrorSet" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
|
||||
try testing.expect(@Type(.{ .ErrorSet = null }) == anyerror);
|
||||
|
||||
// error sets don't compare equal so just check if they compile
|
||||
_ = @Type(@typeInfo(error{}));
|
||||
_ = @Type(@typeInfo(error{A}));
|
||||
_ = @Type(@typeInfo(error{ A, B, C }));
|
||||
_ = @Type(.{
|
||||
.ErrorSet = &[_]Type.Error{
|
||||
.{ .name = "A" },
|
||||
.{ .name = "B" },
|
||||
.{ .name = "C" },
|
||||
},
|
||||
});
|
||||
_ = @Type(.{
|
||||
.ErrorSet = &.{
|
||||
.{ .name = "C" },
|
||||
.{ .name = "B" },
|
||||
.{ .name = "A" },
|
||||
},
|
||||
});
|
||||
inline for (.{ error{}, error{A}, error{ A, B, C } }) |T| {
|
||||
const info = @typeInfo(T);
|
||||
const T2 = @Type(info);
|
||||
try testing.expect(T == T2);
|
||||
}
|
||||
}
|
||||
|
||||
test "Type.Struct" {
|
||||
@ -517,3 +508,35 @@ test "Type.Union from regular enum" {
|
||||
_ = T;
|
||||
_ = @typeInfo(T).Union;
|
||||
}
|
||||
|
||||
test "Type.Fn" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
|
||||
const some_opaque = opaque {};
|
||||
const some_ptr = *some_opaque;
|
||||
const T = fn (c_int, some_ptr) callconv(.C) void;
|
||||
|
||||
{
|
||||
const fn_info = std.builtin.Type{ .Fn = .{
|
||||
.calling_convention = .C,
|
||||
.alignment = 0,
|
||||
.is_generic = false,
|
||||
.is_var_args = false,
|
||||
.return_type = void,
|
||||
.args = &.{
|
||||
.{ .is_generic = false, .is_noalias = false, .arg_type = c_int },
|
||||
.{ .is_generic = false, .is_noalias = false, .arg_type = some_ptr },
|
||||
},
|
||||
} };
|
||||
|
||||
const fn_type = @Type(fn_info);
|
||||
try std.testing.expectEqual(T, fn_type);
|
||||
}
|
||||
|
||||
{
|
||||
const fn_info = @typeInfo(T);
|
||||
const fn_type = @Type(fn_info);
|
||||
try std.testing.expectEqual(T, fn_type);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user