mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
Merge pull request #11001 from Vexu/stage2
stage2: make formatted printing work
This commit is contained in:
commit
b5066fdae2
@ -865,10 +865,16 @@ pub fn flock(fd: fd_t, operation: i32) usize {
|
||||
return syscall2(.flock, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, operation)));
|
||||
}
|
||||
|
||||
var vdso_clock_gettime = @ptrCast(?*const anyopaque, init_vdso_clock_gettime);
|
||||
var vdso_clock_gettime = if (builtin.zig_backend == .stage1)
|
||||
@ptrCast(?*const anyopaque, init_vdso_clock_gettime)
|
||||
else
|
||||
@ptrCast(?*const anyopaque, &init_vdso_clock_gettime);
|
||||
|
||||
// We must follow the C calling convention when we call into the VDSO
|
||||
const vdso_clock_gettime_ty = fn (i32, *timespec) callconv(.C) usize;
|
||||
const vdso_clock_gettime_ty = if (builtin.zig_backend == .stage1)
|
||||
fn (i32, *timespec) callconv(.C) usize
|
||||
else
|
||||
*const fn (i32, *timespec) callconv(.C) usize;
|
||||
|
||||
pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
|
||||
if (@hasDecl(VDSO, "CGT_SYM")) {
|
||||
|
||||
@ -23,10 +23,12 @@ fn processArgs() void {
|
||||
}
|
||||
|
||||
pub fn main() void {
|
||||
if (builtin.zig_backend != .stage1) {
|
||||
if (builtin.zig_backend != .stage1 and
|
||||
builtin.zig_backend != .stage2_llvm)
|
||||
{
|
||||
return main2() catch @panic("test failure");
|
||||
}
|
||||
processArgs();
|
||||
if (builtin.zig_backend == .stage1) processArgs();
|
||||
const test_fn_list = builtin.test_functions;
|
||||
var ok_count: usize = 0;
|
||||
var skip_count: usize = 0;
|
||||
@ -44,9 +46,9 @@ pub fn main() void {
|
||||
|
||||
var leaks: usize = 0;
|
||||
for (test_fn_list) |test_fn, i| {
|
||||
std.testing.allocator_instance = .{};
|
||||
if (builtin.zig_backend != .stage2_llvm) std.testing.allocator_instance = .{};
|
||||
defer {
|
||||
if (std.testing.allocator_instance.deinit()) {
|
||||
if (builtin.zig_backend != .stage2_llvm and std.testing.allocator_instance.deinit()) {
|
||||
leaks += 1;
|
||||
}
|
||||
}
|
||||
@ -90,9 +92,9 @@ pub fn main() void {
|
||||
fail_count += 1;
|
||||
progress.log("FAIL ({s})\n", .{@errorName(err)});
|
||||
if (!have_tty) std.debug.print("FAIL ({s})\n", .{@errorName(err)});
|
||||
if (@errorReturnTrace()) |trace| {
|
||||
if (builtin.zig_backend != .stage2_llvm) if (@errorReturnTrace()) |trace| {
|
||||
std.debug.dumpStackTrace(trace.*);
|
||||
}
|
||||
};
|
||||
test_node.end();
|
||||
},
|
||||
}
|
||||
@ -141,8 +143,7 @@ pub fn main2() anyerror!void {
|
||||
}
|
||||
};
|
||||
}
|
||||
if (builtin.zig_backend == .stage2_llvm or
|
||||
builtin.zig_backend == .stage2_wasm or
|
||||
if (builtin.zig_backend == .stage2_wasm or
|
||||
builtin.zig_backend == .stage2_x86_64)
|
||||
{
|
||||
const passed = builtin.test_functions.len - skipped - failed;
|
||||
|
||||
@ -244,10 +244,14 @@ pub const ResultLoc = union(enum) {
|
||||
fn strategy(rl: ResultLoc, block_scope: *GenZir) Strategy {
|
||||
switch (rl) {
|
||||
// In this branch there will not be any store_to_block_ptr instructions.
|
||||
.discard, .none, .ty, .coerced_ty, .ref => return .{
|
||||
.none, .ty, .coerced_ty, .ref => return .{
|
||||
.tag = .break_operand,
|
||||
.elide_store_to_block_ptr_instructions = false,
|
||||
},
|
||||
.discard => return .{
|
||||
.tag = .break_void,
|
||||
.elide_store_to_block_ptr_instructions = false,
|
||||
},
|
||||
// The pointer got passed through to the sub-expressions, so we will use
|
||||
// break_void here.
|
||||
// In this branch there will not be any store_to_block_ptr instructions.
|
||||
@ -1766,6 +1770,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
|
||||
// we assume the result location is written, and we break with void.
|
||||
_ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
|
||||
},
|
||||
.discard => {
|
||||
_ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
|
||||
},
|
||||
else => {
|
||||
_ = try parent_gz.addBreak(break_tag, block_inst, operand);
|
||||
},
|
||||
|
||||
@ -3762,7 +3762,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
|
||||
// Note this resolves the type of the Decl, not the value; if this Decl
|
||||
// is a struct, for example, this resolves `type` (which needs no resolution),
|
||||
// not the struct itself.
|
||||
try sema.resolveTypeLayout(&block_scope, src, decl_tv.ty);
|
||||
try sema.resolveTypeFully(&block_scope, src, decl_tv.ty);
|
||||
|
||||
const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State);
|
||||
|
||||
|
||||
32
src/Sema.zig
32
src/Sema.zig
@ -4494,6 +4494,10 @@ fn analyzeCall(
|
||||
|
||||
try sema.emitBackwardBranch(&child_block, call_src);
|
||||
|
||||
// Whether this call should be memoized, set to false if the call can mutate
|
||||
// comptime state.
|
||||
var should_memoize = true;
|
||||
|
||||
// This will have return instructions analyzed as break instructions to
|
||||
// the block_inst above. Here we are performing "comptime/inline semantic analysis"
|
||||
// for a function body, which means we must map the parameter ZIR instructions to
|
||||
@ -4527,6 +4531,7 @@ fn analyzeCall(
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
should_memoize = should_memoize and !arg_val.isComptimeMutablePtr();
|
||||
memoized_call_key.args[arg_i] = .{
|
||||
.ty = param_ty,
|
||||
.val = arg_val,
|
||||
@ -4552,6 +4557,7 @@ fn analyzeCall(
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
should_memoize = should_memoize and !arg_val.isComptimeMutablePtr();
|
||||
memoized_call_key.args[arg_i] = .{
|
||||
.ty = sema.typeOf(uncasted_arg),
|
||||
.val = arg_val,
|
||||
@ -4597,7 +4603,7 @@ fn analyzeCall(
|
||||
// This `res2` is here instead of directly breaking from `res` due to a stage1
|
||||
// bug generating invalid LLVM IR.
|
||||
const res2: Air.Inst.Ref = res2: {
|
||||
if (is_comptime_call) {
|
||||
if (should_memoize and is_comptime_call) {
|
||||
if (mod.memoized_calls.get(memoized_call_key)) |result| {
|
||||
const ty_inst = try sema.addType(fn_ret_ty);
|
||||
try sema.air_values.append(gpa, result.val);
|
||||
@ -4621,7 +4627,7 @@ fn analyzeCall(
|
||||
break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);
|
||||
};
|
||||
|
||||
if (is_comptime_call) {
|
||||
if (should_memoize and is_comptime_call) {
|
||||
const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result);
|
||||
|
||||
// TODO: check whether any external comptime memory was mutated by the
|
||||
@ -10975,8 +10981,7 @@ fn zirCondbr(
|
||||
|
||||
if (try sema.resolveDefinedValue(parent_block, src, cond)) |cond_val| {
|
||||
const body = if (cond_val.toBool()) then_body else else_body;
|
||||
_ = try sema.analyzeBody(parent_block, body);
|
||||
return always_noreturn;
|
||||
return sema.analyzeBodyInner(parent_block, body);
|
||||
}
|
||||
|
||||
const gpa = sema.gpa;
|
||||
@ -11948,19 +11953,27 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
|
||||
var buffer: Value.ToTypeBuffer = undefined;
|
||||
const child_ty = child_val.toType(&buffer);
|
||||
|
||||
const ptr_size = size_val.toEnum(std.builtin.TypeInfo.Pointer.Size);
|
||||
|
||||
var actual_sentinel: ?Value = null;
|
||||
if (!sentinel_val.isNull()) {
|
||||
return sema.fail(block, src, "TODO: implement zirReify for pointer with non-null sentinel", .{});
|
||||
if (ptr_size == .One or ptr_size == .C) {
|
||||
return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
|
||||
}
|
||||
const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data;
|
||||
const ptr_ty = try Type.ptr(sema.arena, .{ .@"addrspace" = .generic, .pointee_type = child_ty });
|
||||
actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
|
||||
}
|
||||
|
||||
const ty = try Type.ptr(sema.arena, .{
|
||||
.size = size_val.toEnum(std.builtin.TypeInfo.Pointer.Size),
|
||||
.size = ptr_size,
|
||||
.mutable = !is_const_val.toBool(),
|
||||
.@"volatile" = is_volatile_val.toBool(),
|
||||
.@"align" = @intCast(u8, alignment_val.toUnsignedInt()), // TODO: Validate this value.
|
||||
.@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace),
|
||||
.pointee_type = try child_ty.copy(sema.arena),
|
||||
.@"allowzero" = is_allowzero_val.toBool(),
|
||||
.sentinel = null,
|
||||
.sentinel = actual_sentinel,
|
||||
});
|
||||
return sema.addType(ty);
|
||||
},
|
||||
@ -12070,6 +12083,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
|
||||
const type_res = try sema.resolveType(block, src, extra.lhs);
|
||||
try sema.checkPtrType(block, type_src, type_res);
|
||||
_ = try sema.resolveTypeLayout(block, src, type_res.childType());
|
||||
const ptr_align = type_res.ptrAlignment(sema.mod.getTarget());
|
||||
|
||||
if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {
|
||||
@ -17587,7 +17601,7 @@ fn resolvePeerTypes(
|
||||
return chosen_ty;
|
||||
}
|
||||
|
||||
pub fn resolveTypeLayout(
|
||||
fn resolveTypeLayout(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
src: LazySrcLoc,
|
||||
@ -17660,7 +17674,7 @@ fn resolveUnionLayout(
|
||||
union_obj.status = .have_layout;
|
||||
}
|
||||
|
||||
fn resolveTypeFully(
|
||||
pub fn resolveTypeFully(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
src: LazySrcLoc,
|
||||
|
||||
@ -3892,7 +3892,7 @@ pub const FuncGen = struct {
|
||||
return self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), "");
|
||||
}
|
||||
|
||||
if (operand_ty.zigTypeTag() == .Int and inst_ty.zigTypeTag() == .Pointer) {
|
||||
if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) {
|
||||
return self.builder.buildIntToPtr(operand, llvm_dest_ty, "");
|
||||
}
|
||||
|
||||
|
||||
@ -2602,7 +2602,7 @@ pub const Type = extern union {
|
||||
const payload = self.castTag(.pointer).?.data;
|
||||
return payload.@"allowzero";
|
||||
},
|
||||
else => false,
|
||||
else => return self.zigTypeTag() == .Optional,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -125,6 +125,7 @@ test {
|
||||
_ = @import("behavior/widening.zig");
|
||||
_ = @import("behavior/bugs/421.zig");
|
||||
_ = @import("behavior/bugs/726.zig");
|
||||
_ = @import("behavior/bugs/828.zig");
|
||||
_ = @import("behavior/bugs/1421.zig");
|
||||
_ = @import("behavior/bugs/1442.zig");
|
||||
_ = @import("behavior/bugs/1607.zig");
|
||||
@ -132,6 +133,7 @@ test {
|
||||
_ = @import("behavior/bugs/3384.zig");
|
||||
_ = @import("behavior/bugs/3742.zig");
|
||||
_ = @import("behavior/bugs/5398.zig");
|
||||
_ = @import("behavior/bugs/5413.zig");
|
||||
_ = @import("behavior/bugs/5487.zig");
|
||||
_ = @import("behavior/struct_contains_null_ptr_itself.zig");
|
||||
_ = @import("behavior/switch_prong_err_enum.zig");
|
||||
@ -148,12 +150,10 @@ test {
|
||||
_ = @import("behavior/await_struct.zig");
|
||||
_ = @import("behavior/bugs/529.zig");
|
||||
_ = @import("behavior/bugs/718.zig");
|
||||
_ = @import("behavior/bugs/828.zig");
|
||||
_ = @import("behavior/bugs/920.zig");
|
||||
_ = @import("behavior/bugs/1120.zig");
|
||||
_ = @import("behavior/bugs/1851.zig");
|
||||
_ = @import("behavior/bugs/3779.zig");
|
||||
_ = @import("behavior/bugs/5413.zig");
|
||||
_ = @import("behavior/bugs/6456.zig");
|
||||
_ = @import("behavior/bugs/6781.zig");
|
||||
_ = @import("behavior/bugs/7003.zig");
|
||||
|
||||
@ -819,3 +819,37 @@ test "if expression type coercion" {
|
||||
const x: u16 = if (cond) 1 else 0;
|
||||
try expect(@as(u16, x) == 1);
|
||||
}
|
||||
|
||||
test "discarding the result of various expressions" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn foo() !u32 {
|
||||
return 1;
|
||||
}
|
||||
fn bar() ?u32 {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
_ = S.bar() orelse {
|
||||
// do nothing
|
||||
};
|
||||
_ = S.foo() catch {
|
||||
// do nothing
|
||||
};
|
||||
_ = switch (1) {
|
||||
1 => 1,
|
||||
2 => {},
|
||||
else => return,
|
||||
};
|
||||
_ = try S.foo();
|
||||
_ = if (S.bar()) |some| some else {};
|
||||
_ = blk: {
|
||||
if (S.bar()) |some| break :blk some;
|
||||
break :blk;
|
||||
};
|
||||
_ = while (S.bar()) |some| break some else {};
|
||||
_ = for ("foo") |char| break char else {};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user